Remove hardcoded libpython binaries and add debug step
All checks were successful
build / build-linux (push) Successful in 16s
All checks were successful
build / build-linux (push) Successful in 16s
This commit is contained in:
188
venv/lib/python3.12/site-packages/setuptools/_static.py
Normal file
188
venv/lib/python3.12/site-packages/setuptools/_static.py
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user