about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/setuptools/_static.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/setuptools/_static.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-master.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/setuptools/_static.py')
-rw-r--r--.venv/lib/python3.12/site-packages/setuptools/_static.py188
1 files changed, 188 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/setuptools/_static.py b/.venv/lib/python3.12/site-packages/setuptools/_static.py
new file mode 100644
index 00000000..af35862c
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/setuptools/_static.py
@@ -0,0 +1,188 @@
+from functools import wraps
+from typing import TypeVar
+
+import packaging.specifiers
+
+from .warnings import SetuptoolsDeprecationWarning
+
+
+class Static:
+    """
+    Wrapper for built-in object types that are allow setuptools to identify
+    static core metadata (in opposition to ``Dynamic``, as defined :pep:`643`).
+
+    The trick is to mark values with :class:`Static` when they come from
+    ``pyproject.toml`` or ``setup.cfg``, so if any plugin overwrite the value
+    with a built-in, setuptools will be able to recognise the change.
+
+    We inherit from built-in classes, so that we don't need to change the existing
+    code base to deal with the new types.
+    We also should strive for immutability objects to avoid changes after the
+    initial parsing.
+    """
+
+    _mutated_: bool = False  # TODO: Remove after deprecation warning is solved
+
+
+def _prevent_modification(target: type, method: str, copying: str) -> None:
+    """
+    Because setuptools is very flexible we cannot fully prevent
+    plugins and user customizations from modifying static values that were
+    parsed from config files.
+    But we can attempt to block "in-place" mutations and identify when they
+    were done.
+    """
+    fn = getattr(target, method, None)
+    if fn is None:
+        return
+
+    @wraps(fn)
+    def _replacement(self: Static, *args, **kwargs):
+        # TODO: After deprecation period raise NotImplementedError instead of warning
+        #       which obviated the existence and checks of the `_mutated_` attribute.
+        self._mutated_ = True
+        SetuptoolsDeprecationWarning.emit(
+            "Direct modification of value will be disallowed",
+            f"""
+            In an effort to implement PEP 643, direct/in-place changes of static values
+            that come from configuration files are deprecated.
+            If you need to modify this value, please first create a copy with {copying}
+            and make sure conform to all relevant standards when overriding setuptools
+            functionality (https://packaging.python.org/en/latest/specifications/).
+            """,
+            due_date=(2025, 10, 10),  # Initially introduced in 2024-09-06
+        )
+        return fn(self, *args, **kwargs)
+
+    _replacement.__doc__ = ""  # otherwise doctest may fail.
+    setattr(target, method, _replacement)
+
+
+class Str(str, Static):
+    pass
+
+
+class Tuple(tuple, Static):
+    pass
+
+
+class List(list, Static):
+    """
+    :meta private:
+    >>> x = List([1, 2, 3])
+    >>> is_static(x)
+    True
+    >>> x += [0]  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+    SetuptoolsDeprecationWarning: Direct modification ...
+    >>> is_static(x)  # no longer static after modification
+    False
+    >>> y = list(x)
+    >>> y.clear()
+    >>> y
+    []
+    >>> y == x
+    False
+    >>> is_static(List(y))
+    True
+    """
+
+
+# Make `List` immutable-ish
+# (certain places of setuptools/distutils issue a warn if we use tuple instead of list)
+for _method in (
+    '__delitem__',
+    '__iadd__',
+    '__setitem__',
+    'append',
+    'clear',
+    'extend',
+    'insert',
+    'remove',
+    'reverse',
+    'pop',
+):
+    _prevent_modification(List, _method, "`list(value)`")
+
+
+class Dict(dict, Static):
+    """
+    :meta private:
+    >>> x = Dict({'a': 1, 'b': 2})
+    >>> is_static(x)
+    True
+    >>> x['c'] = 0  # doctest: +IGNORE_EXCEPTION_DETAIL
+    Traceback (most recent call last):
+    SetuptoolsDeprecationWarning: Direct modification ...
+    >>> x._mutated_
+    True
+    >>> is_static(x)  # no longer static after modification
+    False
+    >>> y = dict(x)
+    >>> y.popitem()
+    ('b', 2)
+    >>> y == x
+    False
+    >>> is_static(Dict(y))
+    True
+    """
+
+
+# Make `Dict` immutable-ish (we cannot inherit from types.MappingProxyType):
+for _method in (
+    '__delitem__',
+    '__ior__',
+    '__setitem__',
+    'clear',
+    'pop',
+    'popitem',
+    'setdefault',
+    'update',
+):
+    _prevent_modification(Dict, _method, "`dict(value)`")
+
+
+class SpecifierSet(packaging.specifiers.SpecifierSet, Static):
+    """Not exactly a built-in type but useful for ``requires-python``"""
+
+
+T = TypeVar("T")
+
+
+def noop(value: T) -> T:
+    """
+    >>> noop(42)
+    42
+    """
+    return value
+
+
+_CONVERSIONS = {str: Str, tuple: Tuple, list: List, dict: Dict}
+
+
+def attempt_conversion(value: T) -> T:
+    """
+    >>> is_static(attempt_conversion("hello"))
+    True
+    >>> is_static(object())
+    False
+    """
+    return _CONVERSIONS.get(type(value), noop)(value)  # type: ignore[call-overload]
+
+
+def is_static(value: object) -> bool:
+    """
+    >>> is_static(a := Dict({'a': 1}))
+    True
+    >>> is_static(dict(a))
+    False
+    >>> is_static(b := List([1, 2, 3]))
+    True
+    >>> is_static(list(b))
+    False
+    """
+    return isinstance(value, Static) and not value._mutated_
+
+
+EMPTY_LIST = List()
+EMPTY_DICT = Dict()