mirror of
https://github.com/alexandrebobkov/ESP-Nodes.git
synced 2025-08-08 03:42:24 +00:00
ESP-NOW RC Tutorial
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
# don't import any costly modules
|
||||
import os
|
||||
import sys
|
||||
|
||||
report_url = (
|
||||
"https://github.com/pypa/setuptools/issues/new?template=distutils-deprecation.yml"
|
||||
)
|
||||
|
||||
|
||||
def warn_distutils_present():
|
||||
if 'distutils' not in sys.modules:
|
||||
return
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"Distutils was imported before Setuptools, but importing Setuptools "
|
||||
"also replaces the `distutils` module in `sys.modules`. This may lead "
|
||||
"to undesirable behaviors or errors. To avoid these issues, avoid "
|
||||
"using distutils directly, ensure that setuptools is installed in the "
|
||||
"traditional way (e.g. not an editable install), and/or make sure "
|
||||
"that setuptools is always imported before distutils."
|
||||
)
|
||||
|
||||
|
||||
def clear_distutils():
|
||||
if 'distutils' not in sys.modules:
|
||||
return
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"Setuptools is replacing distutils. Support for replacing "
|
||||
"an already imported distutils is deprecated. In the future, "
|
||||
"this condition will fail. "
|
||||
f"Register concerns at {report_url}"
|
||||
)
|
||||
mods = [
|
||||
name
|
||||
for name in sys.modules
|
||||
if name == "distutils" or name.startswith("distutils.")
|
||||
]
|
||||
for name in mods:
|
||||
del sys.modules[name]
|
||||
|
||||
|
||||
def enabled():
|
||||
"""
|
||||
Allow selection of distutils by environment variable.
|
||||
"""
|
||||
which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local')
|
||||
if which == 'stdlib':
|
||||
import warnings
|
||||
|
||||
warnings.warn(
|
||||
"Reliance on distutils from stdlib is deprecated. Users "
|
||||
"must rely on setuptools to provide the distutils module. "
|
||||
"Avoid importing distutils or import setuptools first, "
|
||||
"and avoid setting SETUPTOOLS_USE_DISTUTILS=stdlib. "
|
||||
f"Register concerns at {report_url}"
|
||||
)
|
||||
return which == 'local'
|
||||
|
||||
|
||||
def ensure_local_distutils():
|
||||
import importlib
|
||||
|
||||
clear_distutils()
|
||||
|
||||
# With the DistutilsMetaFinder in place,
|
||||
# perform an import to cause distutils to be
|
||||
# loaded from setuptools._distutils. Ref #2906.
|
||||
with shim():
|
||||
importlib.import_module('distutils')
|
||||
|
||||
# check that submodules load as expected
|
||||
core = importlib.import_module('distutils.core')
|
||||
assert '_distutils' in core.__file__, core.__file__
|
||||
assert 'setuptools._distutils.log' not in sys.modules
|
||||
|
||||
|
||||
def do_override():
|
||||
"""
|
||||
Ensure that the local copy of distutils is preferred over stdlib.
|
||||
|
||||
See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
|
||||
for more motivation.
|
||||
"""
|
||||
if enabled():
|
||||
warn_distutils_present()
|
||||
ensure_local_distutils()
|
||||
|
||||
|
||||
class _TrivialRe:
|
||||
def __init__(self, *patterns) -> None:
|
||||
self._patterns = patterns
|
||||
|
||||
def match(self, string):
|
||||
return all(pat in string for pat in self._patterns)
|
||||
|
||||
|
||||
class DistutilsMetaFinder:
|
||||
def find_spec(self, fullname, path, target=None):
|
||||
# optimization: only consider top level modules and those
|
||||
# found in the CPython test suite.
|
||||
if path is not None and not fullname.startswith('test.'):
|
||||
return None
|
||||
|
||||
method_name = 'spec_for_{fullname}'.format(**locals())
|
||||
method = getattr(self, method_name, lambda: None)
|
||||
return method()
|
||||
|
||||
def spec_for_distutils(self):
|
||||
if self.is_cpython():
|
||||
return None
|
||||
|
||||
import importlib
|
||||
import importlib.abc
|
||||
import importlib.util
|
||||
|
||||
try:
|
||||
mod = importlib.import_module('setuptools._distutils')
|
||||
except Exception:
|
||||
# There are a couple of cases where setuptools._distutils
|
||||
# may not be present:
|
||||
# - An older Setuptools without a local distutils is
|
||||
# taking precedence. Ref #2957.
|
||||
# - Path manipulation during sitecustomize removes
|
||||
# setuptools from the path but only after the hook
|
||||
# has been loaded. Ref #2980.
|
||||
# In either case, fall back to stdlib behavior.
|
||||
return None
|
||||
|
||||
class DistutilsLoader(importlib.abc.Loader):
|
||||
def create_module(self, spec):
|
||||
mod.__name__ = 'distutils'
|
||||
return mod
|
||||
|
||||
def exec_module(self, module):
|
||||
pass
|
||||
|
||||
return importlib.util.spec_from_loader(
|
||||
'distutils', DistutilsLoader(), origin=mod.__file__
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def is_cpython():
|
||||
"""
|
||||
Suppress supplying distutils for CPython (build and tests).
|
||||
Ref #2965 and #3007.
|
||||
"""
|
||||
return os.path.isfile('pybuilddir.txt')
|
||||
|
||||
def spec_for_pip(self):
|
||||
"""
|
||||
Ensure stdlib distutils when running under pip.
|
||||
See pypa/pip#8761 for rationale.
|
||||
"""
|
||||
if sys.version_info >= (3, 12) or self.pip_imported_during_build():
|
||||
return
|
||||
clear_distutils()
|
||||
self.spec_for_distutils = lambda: None
|
||||
|
||||
@classmethod
|
||||
def pip_imported_during_build(cls):
|
||||
"""
|
||||
Detect if pip is being imported in a build script. Ref #2355.
|
||||
"""
|
||||
import traceback
|
||||
|
||||
return any(
|
||||
cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def frame_file_is_setup(frame):
|
||||
"""
|
||||
Return True if the indicated frame suggests a setup.py file.
|
||||
"""
|
||||
# some frames may not have __file__ (#2940)
|
||||
return frame.f_globals.get('__file__', '').endswith('setup.py')
|
||||
|
||||
def spec_for_sensitive_tests(self):
|
||||
"""
|
||||
Ensure stdlib distutils when running select tests under CPython.
|
||||
|
||||
python/cpython#91169
|
||||
"""
|
||||
clear_distutils()
|
||||
self.spec_for_distutils = lambda: None
|
||||
|
||||
sensitive_tests = (
|
||||
[
|
||||
'test.test_distutils',
|
||||
'test.test_peg_generator',
|
||||
'test.test_importlib',
|
||||
]
|
||||
if sys.version_info < (3, 10)
|
||||
else [
|
||||
'test.test_distutils',
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
for name in DistutilsMetaFinder.sensitive_tests:
|
||||
setattr(
|
||||
DistutilsMetaFinder,
|
||||
f'spec_for_{name}',
|
||||
DistutilsMetaFinder.spec_for_sensitive_tests,
|
||||
)
|
||||
|
||||
|
||||
DISTUTILS_FINDER = DistutilsMetaFinder()
|
||||
|
||||
|
||||
def add_shim():
|
||||
DISTUTILS_FINDER in sys.meta_path or insert_shim()
|
||||
|
||||
|
||||
class shim:
|
||||
def __enter__(self) -> None:
|
||||
insert_shim()
|
||||
|
||||
def __exit__(self, exc: object, value: object, tb: object) -> None:
|
||||
_remove_shim()
|
||||
|
||||
|
||||
def insert_shim():
|
||||
sys.meta_path.insert(0, DISTUTILS_FINDER)
|
||||
|
||||
|
||||
def _remove_shim():
|
||||
try:
|
||||
sys.meta_path.remove(DISTUTILS_FINDER)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
if sys.version_info < (3, 12):
|
||||
# DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632)
|
||||
remove_shim = _remove_shim
|
Binary file not shown.
Binary file not shown.
@@ -0,0 +1 @@
|
||||
__import__('_distutils_hack').do_override()
|
@@ -0,0 +1 @@
|
||||
import os; var = 'SETUPTOOLS_USE_DISTUTILS'; enabled = os.environ.get(var, 'local') == 'local'; enabled and __import__('_distutils_hack').add_shim();
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,424 @@
|
||||
Pluggable Distributions of Python Software
|
||||
==========================================
|
||||
|
||||
Distributions
|
||||
-------------
|
||||
|
||||
A "Distribution" is a collection of files that represent a "Release" of a
|
||||
"Project" as of a particular point in time, denoted by a
|
||||
"Version"::
|
||||
|
||||
>>> import sys, pkg_resources
|
||||
>>> from pkg_resources import Distribution
|
||||
>>> Distribution(project_name="Foo", version="1.2")
|
||||
Foo 1.2
|
||||
|
||||
Distributions have a location, which can be a filename, URL, or really anything
|
||||
else you care to use::
|
||||
|
||||
>>> dist = Distribution(
|
||||
... location="http://example.com/something",
|
||||
... project_name="Bar", version="0.9"
|
||||
... )
|
||||
|
||||
>>> dist
|
||||
Bar 0.9 (http://example.com/something)
|
||||
|
||||
|
||||
Distributions have various introspectable attributes::
|
||||
|
||||
>>> dist.location
|
||||
'http://example.com/something'
|
||||
|
||||
>>> dist.project_name
|
||||
'Bar'
|
||||
|
||||
>>> dist.version
|
||||
'0.9'
|
||||
|
||||
>>> dist.py_version == '{}.{}'.format(*sys.version_info)
|
||||
True
|
||||
|
||||
>>> print(dist.platform)
|
||||
None
|
||||
|
||||
Including various computed attributes::
|
||||
|
||||
>>> from pkg_resources import parse_version
|
||||
>>> dist.parsed_version == parse_version(dist.version)
|
||||
True
|
||||
|
||||
>>> dist.key # case-insensitive form of the project name
|
||||
'bar'
|
||||
|
||||
Distributions are compared (and hashed) by version first::
|
||||
|
||||
>>> Distribution(version='1.0') == Distribution(version='1.0')
|
||||
True
|
||||
>>> Distribution(version='1.0') == Distribution(version='1.1')
|
||||
False
|
||||
>>> Distribution(version='1.0') < Distribution(version='1.1')
|
||||
True
|
||||
|
||||
but also by project name (case-insensitive), platform, Python version,
|
||||
location, etc.::
|
||||
|
||||
>>> Distribution(project_name="Foo",version="1.0") == \
|
||||
... Distribution(project_name="Foo",version="1.0")
|
||||
True
|
||||
|
||||
>>> Distribution(project_name="Foo",version="1.0") == \
|
||||
... Distribution(project_name="foo",version="1.0")
|
||||
True
|
||||
|
||||
>>> Distribution(project_name="Foo",version="1.0") == \
|
||||
... Distribution(project_name="Foo",version="1.1")
|
||||
False
|
||||
|
||||
>>> Distribution(project_name="Foo",py_version="2.3",version="1.0") == \
|
||||
... Distribution(project_name="Foo",py_version="2.4",version="1.0")
|
||||
False
|
||||
|
||||
>>> Distribution(location="spam",version="1.0") == \
|
||||
... Distribution(location="spam",version="1.0")
|
||||
True
|
||||
|
||||
>>> Distribution(location="spam",version="1.0") == \
|
||||
... Distribution(location="baz",version="1.0")
|
||||
False
|
||||
|
||||
|
||||
|
||||
Hash and compare distribution by prio/plat
|
||||
|
||||
Get version from metadata
|
||||
provider capabilities
|
||||
egg_name()
|
||||
as_requirement()
|
||||
from_location, from_filename (w/path normalization)
|
||||
|
||||
Releases may have zero or more "Requirements", which indicate
|
||||
what releases of another project the release requires in order to
|
||||
function. A Requirement names the other project, expresses some criteria
|
||||
as to what releases of that project are acceptable, and lists any "Extras"
|
||||
that the requiring release may need from that project. (An Extra is an
|
||||
optional feature of a Release, that can only be used if its additional
|
||||
Requirements are satisfied.)
|
||||
|
||||
|
||||
|
||||
The Working Set
|
||||
---------------
|
||||
|
||||
A collection of active distributions is called a Working Set. Note that a
|
||||
Working Set can contain any importable distribution, not just pluggable ones.
|
||||
For example, the Python standard library is an importable distribution that
|
||||
will usually be part of the Working Set, even though it is not pluggable.
|
||||
Similarly, when you are doing development work on a project, the files you are
|
||||
editing are also a Distribution. (And, with a little attention to the
|
||||
directory names used, and including some additional metadata, such a
|
||||
"development distribution" can be made pluggable as well.)
|
||||
|
||||
>>> from pkg_resources import WorkingSet
|
||||
|
||||
A working set's entries are the sys.path entries that correspond to the active
|
||||
distributions. By default, the working set's entries are the items on
|
||||
``sys.path``::
|
||||
|
||||
>>> ws = WorkingSet()
|
||||
>>> ws.entries == sys.path
|
||||
True
|
||||
|
||||
But you can also create an empty working set explicitly, and add distributions
|
||||
to it::
|
||||
|
||||
>>> ws = WorkingSet([])
|
||||
>>> ws.add(dist)
|
||||
>>> ws.entries
|
||||
['http://example.com/something']
|
||||
>>> dist in ws
|
||||
True
|
||||
>>> Distribution('foo',version="") in ws
|
||||
False
|
||||
|
||||
And you can iterate over its distributions::
|
||||
|
||||
>>> list(ws)
|
||||
[Bar 0.9 (http://example.com/something)]
|
||||
|
||||
Adding the same distribution more than once is a no-op::
|
||||
|
||||
>>> ws.add(dist)
|
||||
>>> list(ws)
|
||||
[Bar 0.9 (http://example.com/something)]
|
||||
|
||||
For that matter, adding multiple distributions for the same project also does
|
||||
nothing, because a working set can only hold one active distribution per
|
||||
project -- the first one added to it::
|
||||
|
||||
>>> ws.add(
|
||||
... Distribution(
|
||||
... 'http://example.com/something', project_name="Bar",
|
||||
... version="7.2"
|
||||
... )
|
||||
... )
|
||||
>>> list(ws)
|
||||
[Bar 0.9 (http://example.com/something)]
|
||||
|
||||
You can append a path entry to a working set using ``add_entry()``::
|
||||
|
||||
>>> ws.entries
|
||||
['http://example.com/something']
|
||||
>>> ws.add_entry(pkg_resources.__file__)
|
||||
>>> ws.entries
|
||||
['http://example.com/something', '...pkg_resources...']
|
||||
|
||||
Multiple additions result in multiple entries, even if the entry is already in
|
||||
the working set (because ``sys.path`` can contain the same entry more than
|
||||
once)::
|
||||
|
||||
>>> ws.add_entry(pkg_resources.__file__)
|
||||
>>> ws.entries
|
||||
['...example.com...', '...pkg_resources...', '...pkg_resources...']
|
||||
|
||||
And you can specify the path entry a distribution was found under, using the
|
||||
optional second parameter to ``add()``::
|
||||
|
||||
>>> ws = WorkingSet([])
|
||||
>>> ws.add(dist,"foo")
|
||||
>>> ws.entries
|
||||
['foo']
|
||||
|
||||
But even if a distribution is found under multiple path entries, it still only
|
||||
shows up once when iterating the working set:
|
||||
|
||||
>>> ws.add_entry(ws.entries[0])
|
||||
>>> list(ws)
|
||||
[Bar 0.9 (http://example.com/something)]
|
||||
|
||||
You can ask a WorkingSet to ``find()`` a distribution matching a requirement::
|
||||
|
||||
>>> from pkg_resources import Requirement
|
||||
>>> print(ws.find(Requirement.parse("Foo==1.0"))) # no match, return None
|
||||
None
|
||||
|
||||
>>> ws.find(Requirement.parse("Bar==0.9")) # match, return distribution
|
||||
Bar 0.9 (http://example.com/something)
|
||||
|
||||
Note that asking for a conflicting version of a distribution already in a
|
||||
working set triggers a ``pkg_resources.VersionConflict`` error:
|
||||
|
||||
>>> try:
|
||||
... ws.find(Requirement.parse("Bar==1.0"))
|
||||
... except pkg_resources.VersionConflict as exc:
|
||||
... print(str(exc))
|
||||
... else:
|
||||
... raise AssertionError("VersionConflict was not raised")
|
||||
(Bar 0.9 (http://example.com/something), Requirement.parse('Bar==1.0'))
|
||||
|
||||
You can subscribe a callback function to receive notifications whenever a new
|
||||
distribution is added to a working set. The callback is immediately invoked
|
||||
once for each existing distribution in the working set, and then is called
|
||||
again for new distributions added thereafter::
|
||||
|
||||
>>> def added(dist): print("Added %s" % dist)
|
||||
>>> ws.subscribe(added)
|
||||
Added Bar 0.9
|
||||
>>> foo12 = Distribution(project_name="Foo", version="1.2", location="f12")
|
||||
>>> ws.add(foo12)
|
||||
Added Foo 1.2
|
||||
|
||||
Note, however, that only the first distribution added for a given project name
|
||||
will trigger a callback, even during the initial ``subscribe()`` callback::
|
||||
|
||||
>>> foo14 = Distribution(project_name="Foo", version="1.4", location="f14")
|
||||
>>> ws.add(foo14) # no callback, because Foo 1.2 is already active
|
||||
|
||||
>>> ws = WorkingSet([])
|
||||
>>> ws.add(foo12)
|
||||
>>> ws.add(foo14)
|
||||
>>> ws.subscribe(added)
|
||||
Added Foo 1.2
|
||||
|
||||
And adding a callback more than once has no effect, either::
|
||||
|
||||
>>> ws.subscribe(added) # no callbacks
|
||||
|
||||
# and no double-callbacks on subsequent additions, either
|
||||
>>> just_a_test = Distribution(project_name="JustATest", version="0.99")
|
||||
>>> ws.add(just_a_test)
|
||||
Added JustATest 0.99
|
||||
|
||||
|
||||
Finding Plugins
|
||||
---------------
|
||||
|
||||
``WorkingSet`` objects can be used to figure out what plugins in an
|
||||
``Environment`` can be loaded without any resolution errors::
|
||||
|
||||
>>> from pkg_resources import Environment
|
||||
|
||||
>>> plugins = Environment([]) # normally, a list of plugin directories
|
||||
>>> plugins.add(foo12)
|
||||
>>> plugins.add(foo14)
|
||||
>>> plugins.add(just_a_test)
|
||||
|
||||
In the simplest case, we just get the newest version of each distribution in
|
||||
the plugin environment::
|
||||
|
||||
>>> ws = WorkingSet([])
|
||||
>>> ws.find_plugins(plugins)
|
||||
([JustATest 0.99, Foo 1.4 (f14)], {})
|
||||
|
||||
But if there's a problem with a version conflict or missing requirements, the
|
||||
method falls back to older versions, and the error info dict will contain an
|
||||
exception instance for each unloadable plugin::
|
||||
|
||||
>>> ws.add(foo12) # this will conflict with Foo 1.4
|
||||
>>> ws.find_plugins(plugins)
|
||||
([JustATest 0.99, Foo 1.2 (f12)], {Foo 1.4 (f14): VersionConflict(...)})
|
||||
|
||||
But if you disallow fallbacks, the failed plugin will be skipped instead of
|
||||
trying older versions::
|
||||
|
||||
>>> ws.find_plugins(plugins, fallback=False)
|
||||
([JustATest 0.99], {Foo 1.4 (f14): VersionConflict(...)})
|
||||
|
||||
|
||||
|
||||
Platform Compatibility Rules
|
||||
----------------------------
|
||||
|
||||
On the Mac, there are potential compatibility issues for modules compiled
|
||||
on newer versions of macOS than what the user is running. Additionally,
|
||||
macOS will soon have two platforms to contend with: Intel and PowerPC.
|
||||
|
||||
Basic equality works as on other platforms::
|
||||
|
||||
>>> from pkg_resources import compatible_platforms as cp
|
||||
>>> reqd = 'macosx-10.4-ppc'
|
||||
>>> cp(reqd, reqd)
|
||||
True
|
||||
>>> cp("win32", reqd)
|
||||
False
|
||||
|
||||
Distributions made on other machine types are not compatible::
|
||||
|
||||
>>> cp("macosx-10.4-i386", reqd)
|
||||
False
|
||||
|
||||
Distributions made on earlier versions of the OS are compatible, as
|
||||
long as they are from the same top-level version. The patchlevel version
|
||||
number does not matter::
|
||||
|
||||
>>> cp("macosx-10.4-ppc", reqd)
|
||||
True
|
||||
>>> cp("macosx-10.3-ppc", reqd)
|
||||
True
|
||||
>>> cp("macosx-10.5-ppc", reqd)
|
||||
False
|
||||
>>> cp("macosx-9.5-ppc", reqd)
|
||||
False
|
||||
|
||||
Backwards compatibility for packages made via earlier versions of
|
||||
setuptools is provided as well::
|
||||
|
||||
>>> cp("darwin-8.2.0-Power_Macintosh", reqd)
|
||||
True
|
||||
>>> cp("darwin-7.2.0-Power_Macintosh", reqd)
|
||||
True
|
||||
>>> cp("darwin-8.2.0-Power_Macintosh", "macosx-10.3-ppc")
|
||||
False
|
||||
|
||||
|
||||
Environment Markers
|
||||
-------------------
|
||||
|
||||
>>> from pkg_resources import invalid_marker as im, evaluate_marker as em
|
||||
>>> import os
|
||||
|
||||
>>> print(im("sys_platform"))
|
||||
Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in
|
||||
sys_platform
|
||||
^
|
||||
|
||||
>>> print(im("sys_platform=="))
|
||||
Expected a marker variable or quoted string
|
||||
sys_platform==
|
||||
^
|
||||
|
||||
>>> print(im("sys_platform=='win32'"))
|
||||
False
|
||||
|
||||
>>> print(im("sys=='x'"))
|
||||
Expected a marker variable or quoted string
|
||||
sys=='x'
|
||||
^
|
||||
|
||||
>>> print(im("(extra)"))
|
||||
Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in
|
||||
(extra)
|
||||
^
|
||||
|
||||
>>> print(im("(extra"))
|
||||
Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in
|
||||
(extra
|
||||
^
|
||||
|
||||
>>> print(im("os.open('foo')=='y'"))
|
||||
Expected a marker variable or quoted string
|
||||
os.open('foo')=='y'
|
||||
^
|
||||
|
||||
>>> print(im("'x'=='y' and os.open('foo')=='y'")) # no short-circuit!
|
||||
Expected a marker variable or quoted string
|
||||
'x'=='y' and os.open('foo')=='y'
|
||||
^
|
||||
|
||||
>>> print(im("'x'=='x' or os.open('foo')=='y'")) # no short-circuit!
|
||||
Expected a marker variable or quoted string
|
||||
'x'=='x' or os.open('foo')=='y'
|
||||
^
|
||||
|
||||
>>> print(im("r'x'=='x'"))
|
||||
Expected a marker variable or quoted string
|
||||
r'x'=='x'
|
||||
^
|
||||
|
||||
>>> print(im("'''x'''=='x'"))
|
||||
Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in
|
||||
'''x'''=='x'
|
||||
^
|
||||
|
||||
>>> print(im('"""x"""=="x"'))
|
||||
Expected marker operator, one of <=, <, !=, ==, >=, >, ~=, ===, in, not in
|
||||
"""x"""=="x"
|
||||
^
|
||||
|
||||
>>> print(im(r"x\n=='x'"))
|
||||
Expected a marker variable or quoted string
|
||||
x\n=='x'
|
||||
^
|
||||
|
||||
>>> print(im("os.open=='y'"))
|
||||
Expected a marker variable or quoted string
|
||||
os.open=='y'
|
||||
^
|
||||
|
||||
>>> em("sys_platform=='win32'") == (sys.platform=='win32')
|
||||
True
|
||||
|
||||
>>> em("python_version >= '2.7'")
|
||||
True
|
||||
|
||||
>>> em("python_version > '2.6'")
|
||||
True
|
||||
|
||||
>>> im("implementation_name=='cpython'")
|
||||
False
|
||||
|
||||
>>> im("platform_python_implementation=='CPython'")
|
||||
False
|
||||
|
||||
>>> im("implementation_version=='3.5.1'")
|
||||
False
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
name="my-test-package",
|
||||
version="1.0",
|
||||
zip_safe=True,
|
||||
)
|
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
Metadata-Version: 1.0
|
||||
Name: my-test-package
|
||||
Version: 1.0
|
||||
Summary: UNKNOWN
|
||||
Home-page: UNKNOWN
|
||||
Author: UNKNOWN
|
||||
Author-email: UNKNOWN
|
||||
License: UNKNOWN
|
||||
Description: UNKNOWN
|
||||
Platform: UNKNOWN
|
@@ -0,0 +1,7 @@
|
||||
setup.cfg
|
||||
setup.py
|
||||
my_test_package.egg-info/PKG-INFO
|
||||
my_test_package.egg-info/SOURCES.txt
|
||||
my_test_package.egg-info/dependency_links.txt
|
||||
my_test_package.egg-info/top_level.txt
|
||||
my_test_package.egg-info/zip-safe
|
@@ -0,0 +1 @@
|
||||
|
@@ -0,0 +1 @@
|
||||
|
@@ -0,0 +1 @@
|
||||
|
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
import pkg_resources
|
||||
|
||||
TESTS_DATA_DIR = Path(__file__).parent / 'data'
|
||||
|
||||
|
||||
class TestFindDistributions:
|
||||
@pytest.fixture
|
||||
def target_dir(self, tmpdir):
|
||||
target_dir = tmpdir.mkdir('target')
|
||||
# place a .egg named directory in the target that is not an egg:
|
||||
target_dir.mkdir('not.an.egg')
|
||||
return target_dir
|
||||
|
||||
def test_non_egg_dir_named_egg(self, target_dir):
|
||||
dists = pkg_resources.find_distributions(str(target_dir))
|
||||
assert not list(dists)
|
||||
|
||||
def test_standalone_egg_directory(self, target_dir):
|
||||
shutil.copytree(
|
||||
TESTS_DATA_DIR / 'my-test-package_unpacked-egg',
|
||||
target_dir,
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
dists = pkg_resources.find_distributions(str(target_dir))
|
||||
assert [dist.project_name for dist in dists] == ['my-test-package']
|
||||
dists = pkg_resources.find_distributions(str(target_dir), only=True)
|
||||
assert not list(dists)
|
||||
|
||||
def test_zipped_egg(self, target_dir):
|
||||
shutil.copytree(
|
||||
TESTS_DATA_DIR / 'my-test-package_zipped-egg',
|
||||
target_dir,
|
||||
dirs_exist_ok=True,
|
||||
)
|
||||
dists = pkg_resources.find_distributions(str(target_dir))
|
||||
assert [dist.project_name for dist in dists] == ['my-test-package']
|
||||
dists = pkg_resources.find_distributions(str(target_dir), only=True)
|
||||
assert not list(dists)
|
||||
|
||||
def test_zipped_sdist_one_level_removed(self, target_dir):
|
||||
shutil.copytree(
|
||||
TESTS_DATA_DIR / 'my-test-package-zip', target_dir, dirs_exist_ok=True
|
||||
)
|
||||
dists = pkg_resources.find_distributions(
|
||||
str(target_dir / "my-test-package.zip")
|
||||
)
|
||||
assert [dist.project_name for dist in dists] == ['my-test-package']
|
||||
dists = pkg_resources.find_distributions(
|
||||
str(target_dir / "my-test-package.zip"), only=True
|
||||
)
|
||||
assert not list(dists)
|
@@ -0,0 +1,54 @@
|
||||
import platform
|
||||
from inspect import cleandoc
|
||||
|
||||
import jaraco.path
|
||||
import pytest
|
||||
|
||||
pytestmark = pytest.mark.integration
|
||||
|
||||
|
||||
# For the sake of simplicity this test uses fixtures defined in
|
||||
# `setuptools.test.fixtures`,
|
||||
# and it also exercise conditions considered deprecated...
|
||||
# So if needed this test can be deleted.
|
||||
@pytest.mark.skipif(
|
||||
platform.system() != "Linux",
|
||||
reason="only demonstrated to fail on Linux in #4399",
|
||||
)
|
||||
def test_interop_pkg_resources_iter_entry_points(tmp_path, venv):
|
||||
"""
|
||||
Importing pkg_resources.iter_entry_points on console_scripts
|
||||
seems to cause trouble with zope-interface, when deprecates installation method
|
||||
is used. See #4399.
|
||||
"""
|
||||
project = {
|
||||
"pkg": {
|
||||
"foo.py": cleandoc(
|
||||
"""
|
||||
from pkg_resources import iter_entry_points
|
||||
|
||||
def bar():
|
||||
print("Print me if you can")
|
||||
"""
|
||||
),
|
||||
"setup.py": cleandoc(
|
||||
"""
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
install_requires=["zope-interface==6.4.post2"],
|
||||
entry_points={
|
||||
"console_scripts": [
|
||||
"foo=foo:bar",
|
||||
],
|
||||
},
|
||||
)
|
||||
"""
|
||||
),
|
||||
}
|
||||
}
|
||||
jaraco.path.build(project, prefix=tmp_path)
|
||||
cmd = ["pip", "install", "-e", ".", "--no-use-pep517"]
|
||||
venv.run(cmd, cwd=tmp_path / "pkg") # Needs this version of pkg_resources installed
|
||||
out = venv.run(["foo"])
|
||||
assert "Print me if you can" in out
|
@@ -0,0 +1,8 @@
|
||||
from unittest import mock
|
||||
|
||||
from pkg_resources import evaluate_marker
|
||||
|
||||
|
||||
@mock.patch('platform.python_version', return_value='2.7.10')
|
||||
def test_ordering(python_version_mock):
|
||||
assert evaluate_marker("python_full_version > '2.7.3'") is True
|
@@ -0,0 +1,485 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import builtins
|
||||
import datetime
|
||||
import inspect
|
||||
import os
|
||||
import plistlib
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import zipfile
|
||||
from unittest import mock
|
||||
|
||||
import pytest
|
||||
|
||||
import pkg_resources
|
||||
from pkg_resources import DistInfoDistribution, Distribution, EggInfoDistribution
|
||||
|
||||
import distutils.command.install_egg_info
|
||||
import distutils.dist
|
||||
|
||||
|
||||
class EggRemover(str):
|
||||
def __call__(self):
|
||||
if self in sys.path:
|
||||
sys.path.remove(self)
|
||||
if os.path.exists(self):
|
||||
os.remove(self)
|
||||
|
||||
|
||||
class TestZipProvider:
|
||||
finalizers: list[EggRemover] = []
|
||||
|
||||
ref_time = datetime.datetime(2013, 5, 12, 13, 25, 0)
|
||||
"A reference time for a file modification"
|
||||
|
||||
@classmethod
|
||||
def setup_class(cls):
|
||||
"create a zip egg and add it to sys.path"
|
||||
egg = tempfile.NamedTemporaryFile(suffix='.egg', delete=False)
|
||||
zip_egg = zipfile.ZipFile(egg, 'w')
|
||||
zip_info = zipfile.ZipInfo()
|
||||
zip_info.filename = 'mod.py'
|
||||
zip_info.date_time = cls.ref_time.timetuple()
|
||||
zip_egg.writestr(zip_info, 'x = 3\n')
|
||||
zip_info = zipfile.ZipInfo()
|
||||
zip_info.filename = 'data.dat'
|
||||
zip_info.date_time = cls.ref_time.timetuple()
|
||||
zip_egg.writestr(zip_info, 'hello, world!')
|
||||
zip_info = zipfile.ZipInfo()
|
||||
zip_info.filename = 'subdir/mod2.py'
|
||||
zip_info.date_time = cls.ref_time.timetuple()
|
||||
zip_egg.writestr(zip_info, 'x = 6\n')
|
||||
zip_info = zipfile.ZipInfo()
|
||||
zip_info.filename = 'subdir/data2.dat'
|
||||
zip_info.date_time = cls.ref_time.timetuple()
|
||||
zip_egg.writestr(zip_info, 'goodbye, world!')
|
||||
zip_egg.close()
|
||||
egg.close()
|
||||
|
||||
sys.path.append(egg.name)
|
||||
subdir = os.path.join(egg.name, 'subdir')
|
||||
sys.path.append(subdir)
|
||||
cls.finalizers.append(EggRemover(subdir))
|
||||
cls.finalizers.append(EggRemover(egg.name))
|
||||
|
||||
@classmethod
|
||||
def teardown_class(cls):
|
||||
for finalizer in cls.finalizers:
|
||||
finalizer()
|
||||
|
||||
def test_resource_listdir(self):
|
||||
import mod # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
|
||||
zp = pkg_resources.ZipProvider(mod)
|
||||
|
||||
expected_root = ['data.dat', 'mod.py', 'subdir']
|
||||
assert sorted(zp.resource_listdir('')) == expected_root
|
||||
|
||||
expected_subdir = ['data2.dat', 'mod2.py']
|
||||
assert sorted(zp.resource_listdir('subdir')) == expected_subdir
|
||||
assert sorted(zp.resource_listdir('subdir/')) == expected_subdir
|
||||
|
||||
assert zp.resource_listdir('nonexistent') == []
|
||||
assert zp.resource_listdir('nonexistent/') == []
|
||||
|
||||
import mod2 # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
|
||||
zp2 = pkg_resources.ZipProvider(mod2)
|
||||
|
||||
assert sorted(zp2.resource_listdir('')) == expected_subdir
|
||||
|
||||
assert zp2.resource_listdir('subdir') == []
|
||||
assert zp2.resource_listdir('subdir/') == []
|
||||
|
||||
def test_resource_filename_rewrites_on_change(self):
|
||||
"""
|
||||
If a previous call to get_resource_filename has saved the file, but
|
||||
the file has been subsequently mutated with different file of the
|
||||
same size and modification time, it should not be overwritten on a
|
||||
subsequent call to get_resource_filename.
|
||||
"""
|
||||
import mod # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
|
||||
manager = pkg_resources.ResourceManager()
|
||||
zp = pkg_resources.ZipProvider(mod)
|
||||
filename = zp.get_resource_filename(manager, 'data.dat')
|
||||
actual = datetime.datetime.fromtimestamp(os.stat(filename).st_mtime)
|
||||
assert actual == self.ref_time
|
||||
f = open(filename, 'w', encoding="utf-8")
|
||||
f.write('hello, world?')
|
||||
f.close()
|
||||
ts = self.ref_time.timestamp()
|
||||
os.utime(filename, (ts, ts))
|
||||
filename = zp.get_resource_filename(manager, 'data.dat')
|
||||
with open(filename, encoding="utf-8") as f:
|
||||
assert f.read() == 'hello, world!'
|
||||
manager.cleanup_resources()
|
||||
|
||||
|
||||
class TestResourceManager:
|
||||
def test_get_cache_path(self):
|
||||
mgr = pkg_resources.ResourceManager()
|
||||
path = mgr.get_cache_path('foo')
|
||||
type_ = str(type(path))
|
||||
message = "Unexpected type from get_cache_path: " + type_
|
||||
assert isinstance(path, str), message
|
||||
|
||||
def test_get_cache_path_race(self, tmpdir):
|
||||
# Patch to os.path.isdir to create a race condition
|
||||
def patched_isdir(dirname, unpatched_isdir=pkg_resources.isdir):
|
||||
patched_isdir.dirnames.append(dirname)
|
||||
|
||||
was_dir = unpatched_isdir(dirname)
|
||||
if not was_dir:
|
||||
os.makedirs(dirname)
|
||||
return was_dir
|
||||
|
||||
patched_isdir.dirnames = []
|
||||
|
||||
# Get a cache path with a "race condition"
|
||||
mgr = pkg_resources.ResourceManager()
|
||||
mgr.set_extraction_path(str(tmpdir))
|
||||
|
||||
archive_name = os.sep.join(('foo', 'bar', 'baz'))
|
||||
with mock.patch.object(pkg_resources, 'isdir', new=patched_isdir):
|
||||
mgr.get_cache_path(archive_name)
|
||||
|
||||
# Because this test relies on the implementation details of this
|
||||
# function, these assertions are a sentinel to ensure that the
|
||||
# test suite will not fail silently if the implementation changes.
|
||||
called_dirnames = patched_isdir.dirnames
|
||||
assert len(called_dirnames) == 2
|
||||
assert called_dirnames[0].split(os.sep)[-2:] == ['foo', 'bar']
|
||||
assert called_dirnames[1].split(os.sep)[-1:] == ['foo']
|
||||
|
||||
"""
|
||||
Tests to ensure that pkg_resources runs independently from setuptools.
|
||||
"""
|
||||
|
||||
def test_setuptools_not_imported(self):
|
||||
"""
|
||||
In a separate Python environment, import pkg_resources and assert
|
||||
that action doesn't cause setuptools to be imported.
|
||||
"""
|
||||
lines = (
|
||||
'import pkg_resources',
|
||||
'import sys',
|
||||
('assert "setuptools" not in sys.modules, "setuptools was imported"'),
|
||||
)
|
||||
cmd = [sys.executable, '-c', '; '.join(lines)]
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def make_test_distribution(metadata_path, metadata):
|
||||
"""
|
||||
Make a test Distribution object, and return it.
|
||||
|
||||
:param metadata_path: the path to the metadata file that should be
|
||||
created. This should be inside a distribution directory that should
|
||||
also be created. For example, an argument value might end with
|
||||
"<project>.dist-info/METADATA".
|
||||
:param metadata: the desired contents of the metadata file, as bytes.
|
||||
"""
|
||||
dist_dir = os.path.dirname(metadata_path)
|
||||
os.mkdir(dist_dir)
|
||||
with open(metadata_path, 'wb') as f:
|
||||
f.write(metadata)
|
||||
dists = list(pkg_resources.distributions_from_metadata(dist_dir))
|
||||
(dist,) = dists
|
||||
|
||||
return dist
|
||||
|
||||
|
||||
def test_get_metadata__bad_utf8(tmpdir):
|
||||
"""
|
||||
Test a metadata file with bytes that can't be decoded as utf-8.
|
||||
"""
|
||||
filename = 'METADATA'
|
||||
# Convert the tmpdir LocalPath object to a string before joining.
|
||||
metadata_path = os.path.join(str(tmpdir), 'foo.dist-info', filename)
|
||||
# Encode a non-ascii string with the wrong encoding (not utf-8).
|
||||
metadata = 'née'.encode('iso-8859-1')
|
||||
dist = make_test_distribution(metadata_path, metadata=metadata)
|
||||
|
||||
with pytest.raises(UnicodeDecodeError) as excinfo:
|
||||
dist.get_metadata(filename)
|
||||
|
||||
exc = excinfo.value
|
||||
actual = str(exc)
|
||||
expected = (
|
||||
# The error message starts with "'utf-8' codec ..." However, the
|
||||
# spelling of "utf-8" can vary (e.g. "utf8") so we don't include it
|
||||
"codec can't decode byte 0xe9 in position 1: "
|
||||
'invalid continuation byte in METADATA file at path: '
|
||||
)
|
||||
assert expected in actual, f'actual: {actual}'
|
||||
assert actual.endswith(metadata_path), f'actual: {actual}'
|
||||
|
||||
|
||||
def make_distribution_no_version(tmpdir, basename):
|
||||
"""
|
||||
Create a distribution directory with no file containing the version.
|
||||
"""
|
||||
dist_dir = tmpdir / basename
|
||||
dist_dir.ensure_dir()
|
||||
# Make the directory non-empty so distributions_from_metadata()
|
||||
# will detect it and yield it.
|
||||
dist_dir.join('temp.txt').ensure()
|
||||
|
||||
dists = list(pkg_resources.distributions_from_metadata(dist_dir))
|
||||
assert len(dists) == 1
|
||||
(dist,) = dists
|
||||
|
||||
return dist, dist_dir
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("suffix", "expected_filename", "expected_dist_type"),
|
||||
[
|
||||
('egg-info', 'PKG-INFO', EggInfoDistribution),
|
||||
('dist-info', 'METADATA', DistInfoDistribution),
|
||||
],
|
||||
)
|
||||
@pytest.mark.xfail(
|
||||
sys.version_info[:2] == (3, 12) and sys.version_info.releaselevel != 'final',
|
||||
reason="https://github.com/python/cpython/issues/103632",
|
||||
)
|
||||
def test_distribution_version_missing(
|
||||
tmpdir, suffix, expected_filename, expected_dist_type
|
||||
):
|
||||
"""
|
||||
Test Distribution.version when the "Version" header is missing.
|
||||
"""
|
||||
basename = f'foo.{suffix}'
|
||||
dist, dist_dir = make_distribution_no_version(tmpdir, basename)
|
||||
|
||||
expected_text = (
|
||||
f"Missing 'Version:' header and/or {expected_filename} file at path: "
|
||||
)
|
||||
metadata_path = os.path.join(dist_dir, expected_filename)
|
||||
|
||||
# Now check the exception raised when the "version" attribute is accessed.
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
dist.version
|
||||
|
||||
err = str(excinfo.value)
|
||||
# Include a string expression after the assert so the full strings
|
||||
# will be visible for inspection on failure.
|
||||
assert expected_text in err, str((expected_text, err))
|
||||
|
||||
# Also check the args passed to the ValueError.
|
||||
msg, dist = excinfo.value.args
|
||||
assert expected_text in msg
|
||||
# Check that the message portion contains the path.
|
||||
assert metadata_path in msg, str((metadata_path, msg))
|
||||
assert type(dist) is expected_dist_type
|
||||
|
||||
|
||||
@pytest.mark.xfail(
|
||||
sys.version_info[:2] == (3, 12) and sys.version_info.releaselevel != 'final',
|
||||
reason="https://github.com/python/cpython/issues/103632",
|
||||
)
|
||||
def test_distribution_version_missing_undetected_path():
|
||||
"""
|
||||
Test Distribution.version when the "Version" header is missing and
|
||||
the path can't be detected.
|
||||
"""
|
||||
# Create a Distribution object with no metadata argument, which results
|
||||
# in an empty metadata provider.
|
||||
dist = Distribution('/foo')
|
||||
with pytest.raises(ValueError) as excinfo:
|
||||
dist.version
|
||||
|
||||
msg, dist = excinfo.value.args
|
||||
expected = (
|
||||
"Missing 'Version:' header and/or PKG-INFO file at path: [could not detect]"
|
||||
)
|
||||
assert msg == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('only', [False, True])
|
||||
def test_dist_info_is_not_dir(tmp_path, only):
|
||||
"""Test path containing a file with dist-info extension."""
|
||||
dist_info = tmp_path / 'foobar.dist-info'
|
||||
dist_info.touch()
|
||||
assert not pkg_resources.dist_factory(str(tmp_path), str(dist_info), only)
|
||||
|
||||
|
||||
def test_macos_vers_fallback(monkeypatch, tmp_path):
|
||||
"""Regression test for pkg_resources._macos_vers"""
|
||||
orig_open = builtins.open
|
||||
|
||||
# Pretend we need to use the plist file
|
||||
monkeypatch.setattr('platform.mac_ver', mock.Mock(return_value=('', (), '')))
|
||||
|
||||
# Create fake content for the fake plist file
|
||||
with open(tmp_path / 'fake.plist', 'wb') as fake_file:
|
||||
plistlib.dump({"ProductVersion": "11.4"}, fake_file)
|
||||
|
||||
# Pretend the fake file exists
|
||||
monkeypatch.setattr('os.path.exists', mock.Mock(return_value=True))
|
||||
|
||||
def fake_open(file, *args, **kwargs):
|
||||
return orig_open(tmp_path / 'fake.plist', *args, **kwargs)
|
||||
|
||||
# Ensure that the _macos_vers works correctly
|
||||
with mock.patch('builtins.open', mock.Mock(side_effect=fake_open)) as m:
|
||||
pkg_resources._macos_vers.cache_clear()
|
||||
assert pkg_resources._macos_vers() == ["11", "4"]
|
||||
pkg_resources._macos_vers.cache_clear()
|
||||
|
||||
m.assert_called()
|
||||
|
||||
|
||||
class TestDeepVersionLookupDistutils:
|
||||
@pytest.fixture
|
||||
def env(self, tmpdir):
|
||||
"""
|
||||
Create a package environment, similar to a virtualenv,
|
||||
in which packages are installed.
|
||||
"""
|
||||
|
||||
class Environment(str):
|
||||
pass
|
||||
|
||||
env = Environment(tmpdir)
|
||||
tmpdir.chmod(stat.S_IRWXU)
|
||||
subs = 'home', 'lib', 'scripts', 'data', 'egg-base'
|
||||
env.paths = dict((dirname, str(tmpdir / dirname)) for dirname in subs)
|
||||
list(map(os.mkdir, env.paths.values()))
|
||||
return env
|
||||
|
||||
def create_foo_pkg(self, env, version):
|
||||
"""
|
||||
Create a foo package installed (distutils-style) to env.paths['lib']
|
||||
as version.
|
||||
"""
|
||||
ld = "This package has unicode metadata! ❄"
|
||||
attrs = dict(name='foo', version=version, long_description=ld)
|
||||
dist = distutils.dist.Distribution(attrs)
|
||||
iei_cmd = distutils.command.install_egg_info.install_egg_info(dist)
|
||||
iei_cmd.initialize_options()
|
||||
iei_cmd.install_dir = env.paths['lib']
|
||||
iei_cmd.finalize_options()
|
||||
iei_cmd.run()
|
||||
|
||||
def test_version_resolved_from_egg_info(self, env):
|
||||
version = '1.11.0.dev0+2329eae'
|
||||
self.create_foo_pkg(env, version)
|
||||
|
||||
# this requirement parsing will raise a VersionConflict unless the
|
||||
# .egg-info file is parsed (see #419 on BitBucket)
|
||||
req = pkg_resources.Requirement.parse('foo>=1.9')
|
||||
dist = pkg_resources.WorkingSet([env.paths['lib']]).find(req)
|
||||
assert dist.version == version
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("unnormalized", "normalized"),
|
||||
[
|
||||
('foo', 'foo'),
|
||||
('foo/', 'foo'),
|
||||
('foo/bar', 'foo/bar'),
|
||||
('foo/bar/', 'foo/bar'),
|
||||
],
|
||||
)
|
||||
def test_normalize_path_trailing_sep(self, unnormalized, normalized):
|
||||
"""Ensure the trailing slash is cleaned for path comparison.
|
||||
|
||||
See pypa/setuptools#1519.
|
||||
"""
|
||||
result_from_unnormalized = pkg_resources.normalize_path(unnormalized)
|
||||
result_from_normalized = pkg_resources.normalize_path(normalized)
|
||||
assert result_from_unnormalized == result_from_normalized
|
||||
|
||||
@pytest.mark.skipif(
|
||||
os.path.normcase('A') != os.path.normcase('a'),
|
||||
reason='Testing case-insensitive filesystems.',
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("unnormalized", "normalized"),
|
||||
[
|
||||
('MiXeD/CasE', 'mixed/case'),
|
||||
],
|
||||
)
|
||||
def test_normalize_path_normcase(self, unnormalized, normalized):
|
||||
"""Ensure mixed case is normalized on case-insensitive filesystems."""
|
||||
result_from_unnormalized = pkg_resources.normalize_path(unnormalized)
|
||||
result_from_normalized = pkg_resources.normalize_path(normalized)
|
||||
assert result_from_unnormalized == result_from_normalized
|
||||
|
||||
@pytest.mark.skipif(
|
||||
os.path.sep != '\\',
|
||||
reason='Testing systems using backslashes as path separators.',
|
||||
)
|
||||
@pytest.mark.parametrize(
|
||||
("unnormalized", "expected"),
|
||||
[
|
||||
('forward/slash', 'forward\\slash'),
|
||||
('forward/slash/', 'forward\\slash'),
|
||||
('backward\\slash\\', 'backward\\slash'),
|
||||
],
|
||||
)
|
||||
def test_normalize_path_backslash_sep(self, unnormalized, expected):
|
||||
"""Ensure path seps are cleaned on backslash path sep systems."""
|
||||
result = pkg_resources.normalize_path(unnormalized)
|
||||
assert result.endswith(expected)
|
||||
|
||||
|
||||
class TestWorkdirRequire:
|
||||
def fake_site_packages(self, tmp_path, monkeypatch, dist_files):
|
||||
site_packages = tmp_path / "site-packages"
|
||||
site_packages.mkdir()
|
||||
for file, content in self.FILES.items():
|
||||
path = site_packages / file
|
||||
path.parent.mkdir(exist_ok=True, parents=True)
|
||||
path.write_text(inspect.cleandoc(content), encoding="utf-8")
|
||||
|
||||
monkeypatch.setattr(sys, "path", [site_packages])
|
||||
return os.fspath(site_packages)
|
||||
|
||||
FILES = {
|
||||
"pkg1_mod-1.2.3.dist-info/METADATA": """
|
||||
Metadata-Version: 2.4
|
||||
Name: pkg1.mod
|
||||
Version: 1.2.3
|
||||
""",
|
||||
"pkg2.mod-0.42.dist-info/METADATA": """
|
||||
Metadata-Version: 2.1
|
||||
Name: pkg2.mod
|
||||
Version: 0.42
|
||||
""",
|
||||
"pkg3_mod.egg-info/PKG-INFO": """
|
||||
Name: pkg3.mod
|
||||
Version: 1.2.3.4
|
||||
""",
|
||||
"pkg4.mod.egg-info/PKG-INFO": """
|
||||
Name: pkg4.mod
|
||||
Version: 0.42.1
|
||||
""",
|
||||
}
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("version", "requirement"),
|
||||
[
|
||||
("1.2.3", "pkg1.mod>=1"),
|
||||
("0.42", "pkg2.mod>=0.4"),
|
||||
("1.2.3.4", "pkg3.mod<=2"),
|
||||
("0.42.1", "pkg4.mod>0.2,<1"),
|
||||
],
|
||||
)
|
||||
def test_require_non_normalised_name(
|
||||
self, tmp_path, monkeypatch, version, requirement
|
||||
):
|
||||
# https://github.com/pypa/setuptools/issues/4853
|
||||
site_packages = self.fake_site_packages(tmp_path, monkeypatch, self.FILES)
|
||||
ws = pkg_resources.WorkingSet([site_packages])
|
||||
|
||||
for req in [requirement, requirement.replace(".", "-")]:
|
||||
[dist] = ws.require(req)
|
||||
assert dist.version == version
|
||||
assert os.path.samefile(
|
||||
os.path.commonpath([dist.location, site_packages]), site_packages
|
||||
)
|
@@ -0,0 +1,869 @@
|
||||
import itertools
|
||||
import os
|
||||
import platform
|
||||
import string
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
from packaging.specifiers import SpecifierSet
|
||||
|
||||
import pkg_resources
|
||||
from pkg_resources import (
|
||||
Distribution,
|
||||
EntryPoint,
|
||||
Requirement,
|
||||
VersionConflict,
|
||||
WorkingSet,
|
||||
parse_requirements,
|
||||
parse_version,
|
||||
safe_name,
|
||||
safe_version,
|
||||
)
|
||||
|
||||
|
||||
# from Python 3.6 docs. Available from itertools on Python 3.10
|
||||
def pairwise(iterable):
|
||||
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
|
||||
a, b = itertools.tee(iterable)
|
||||
next(b, None)
|
||||
return zip(a, b)
|
||||
|
||||
|
||||
class Metadata(pkg_resources.EmptyProvider):
|
||||
"""Mock object to return metadata as if from an on-disk distribution"""
|
||||
|
||||
def __init__(self, *pairs) -> None:
|
||||
self.metadata = dict(pairs)
|
||||
|
||||
def has_metadata(self, name) -> bool:
|
||||
return name in self.metadata
|
||||
|
||||
def get_metadata(self, name):
|
||||
return self.metadata[name]
|
||||
|
||||
def get_metadata_lines(self, name):
|
||||
return pkg_resources.yield_lines(self.get_metadata(name))
|
||||
|
||||
|
||||
dist_from_fn = pkg_resources.Distribution.from_filename
|
||||
|
||||
|
||||
class TestDistro:
|
||||
def testCollection(self):
|
||||
# empty path should produce no distributions
|
||||
ad = pkg_resources.Environment([], platform=None, python=None)
|
||||
assert list(ad) == []
|
||||
assert ad['FooPkg'] == []
|
||||
ad.add(dist_from_fn("FooPkg-1.3_1.egg"))
|
||||
ad.add(dist_from_fn("FooPkg-1.4-py2.4-win32.egg"))
|
||||
ad.add(dist_from_fn("FooPkg-1.2-py2.4.egg"))
|
||||
|
||||
# Name is in there now
|
||||
assert ad['FooPkg']
|
||||
# But only 1 package
|
||||
assert list(ad) == ['foopkg']
|
||||
|
||||
# Distributions sort by version
|
||||
expected = ['1.4', '1.3-1', '1.2']
|
||||
assert [dist.version for dist in ad['FooPkg']] == expected
|
||||
|
||||
# Removing a distribution leaves sequence alone
|
||||
ad.remove(ad['FooPkg'][1])
|
||||
assert [dist.version for dist in ad['FooPkg']] == ['1.4', '1.2']
|
||||
|
||||
# And inserting adds them in order
|
||||
ad.add(dist_from_fn("FooPkg-1.9.egg"))
|
||||
assert [dist.version for dist in ad['FooPkg']] == ['1.9', '1.4', '1.2']
|
||||
|
||||
ws = WorkingSet([])
|
||||
foo12 = dist_from_fn("FooPkg-1.2-py2.4.egg")
|
||||
foo14 = dist_from_fn("FooPkg-1.4-py2.4-win32.egg")
|
||||
(req,) = parse_requirements("FooPkg>=1.3")
|
||||
|
||||
# Nominal case: no distros on path, should yield all applicable
|
||||
assert ad.best_match(req, ws).version == '1.9'
|
||||
# If a matching distro is already installed, should return only that
|
||||
ws.add(foo14)
|
||||
assert ad.best_match(req, ws).version == '1.4'
|
||||
|
||||
# If the first matching distro is unsuitable, it's a version conflict
|
||||
ws = WorkingSet([])
|
||||
ws.add(foo12)
|
||||
ws.add(foo14)
|
||||
with pytest.raises(VersionConflict):
|
||||
ad.best_match(req, ws)
|
||||
|
||||
# If more than one match on the path, the first one takes precedence
|
||||
ws = WorkingSet([])
|
||||
ws.add(foo14)
|
||||
ws.add(foo12)
|
||||
ws.add(foo14)
|
||||
assert ad.best_match(req, ws).version == '1.4'
|
||||
|
||||
def checkFooPkg(self, d):
|
||||
assert d.project_name == "FooPkg"
|
||||
assert d.key == "foopkg"
|
||||
assert d.version == "1.3.post1"
|
||||
assert d.py_version == "2.4"
|
||||
assert d.platform == "win32"
|
||||
assert d.parsed_version == parse_version("1.3-1")
|
||||
|
||||
def testDistroBasics(self):
|
||||
d = Distribution(
|
||||
"/some/path",
|
||||
project_name="FooPkg",
|
||||
version="1.3-1",
|
||||
py_version="2.4",
|
||||
platform="win32",
|
||||
)
|
||||
self.checkFooPkg(d)
|
||||
|
||||
d = Distribution("/some/path")
|
||||
assert d.py_version == f'{sys.version_info.major}.{sys.version_info.minor}'
|
||||
assert d.platform is None
|
||||
|
||||
def testDistroParse(self):
|
||||
d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg")
|
||||
self.checkFooPkg(d)
|
||||
d = dist_from_fn("FooPkg-1.3.post1-py2.4-win32.egg-info")
|
||||
self.checkFooPkg(d)
|
||||
|
||||
def testDistroMetadata(self):
|
||||
d = Distribution(
|
||||
"/some/path",
|
||||
project_name="FooPkg",
|
||||
py_version="2.4",
|
||||
platform="win32",
|
||||
metadata=Metadata(('PKG-INFO', "Metadata-Version: 1.0\nVersion: 1.3-1\n")),
|
||||
)
|
||||
self.checkFooPkg(d)
|
||||
|
||||
def distRequires(self, txt):
|
||||
return Distribution("/foo", metadata=Metadata(('depends.txt', txt)))
|
||||
|
||||
def checkRequires(self, dist, txt, extras=()):
|
||||
assert list(dist.requires(extras)) == list(parse_requirements(txt))
|
||||
|
||||
def testDistroDependsSimple(self):
|
||||
for v in "Twisted>=1.5", "Twisted>=1.5\nZConfig>=2.0":
|
||||
self.checkRequires(self.distRequires(v), v)
|
||||
|
||||
needs_object_dir = pytest.mark.skipif(
|
||||
not hasattr(object, '__dir__'),
|
||||
reason='object.__dir__ necessary for self.__dir__ implementation',
|
||||
)
|
||||
|
||||
def test_distribution_dir(self):
|
||||
d = pkg_resources.Distribution()
|
||||
dir(d)
|
||||
|
||||
@needs_object_dir
|
||||
def test_distribution_dir_includes_provider_dir(self):
|
||||
d = pkg_resources.Distribution()
|
||||
before = d.__dir__()
|
||||
assert 'test_attr' not in before
|
||||
d._provider.test_attr = None
|
||||
after = d.__dir__()
|
||||
assert len(after) == len(before) + 1
|
||||
assert 'test_attr' in after
|
||||
|
||||
@needs_object_dir
|
||||
def test_distribution_dir_ignores_provider_dir_leading_underscore(self):
|
||||
d = pkg_resources.Distribution()
|
||||
before = d.__dir__()
|
||||
assert '_test_attr' not in before
|
||||
d._provider._test_attr = None
|
||||
after = d.__dir__()
|
||||
assert len(after) == len(before)
|
||||
assert '_test_attr' not in after
|
||||
|
||||
def testResolve(self):
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
# Resolving no requirements -> nothing to install
|
||||
assert list(ws.resolve([], ad)) == []
|
||||
# Request something not in the collection -> DistributionNotFound
|
||||
with pytest.raises(pkg_resources.DistributionNotFound):
|
||||
ws.resolve(parse_requirements("Foo"), ad)
|
||||
|
||||
Foo = Distribution.from_filename(
|
||||
"/foo_dir/Foo-1.2.egg",
|
||||
metadata=Metadata(('depends.txt', "[bar]\nBaz>=2.0")),
|
||||
)
|
||||
ad.add(Foo)
|
||||
ad.add(Distribution.from_filename("Foo-0.9.egg"))
|
||||
|
||||
# Request thing(s) that are available -> list to activate
|
||||
for i in range(3):
|
||||
targets = list(ws.resolve(parse_requirements("Foo"), ad))
|
||||
assert targets == [Foo]
|
||||
list(map(ws.add, targets))
|
||||
with pytest.raises(VersionConflict):
|
||||
ws.resolve(parse_requirements("Foo==0.9"), ad)
|
||||
ws = WorkingSet([]) # reset
|
||||
|
||||
# Request an extra that causes an unresolved dependency for "Baz"
|
||||
with pytest.raises(pkg_resources.DistributionNotFound):
|
||||
ws.resolve(parse_requirements("Foo[bar]"), ad)
|
||||
Baz = Distribution.from_filename(
|
||||
"/foo_dir/Baz-2.1.egg", metadata=Metadata(('depends.txt', "Foo"))
|
||||
)
|
||||
ad.add(Baz)
|
||||
|
||||
# Activation list now includes resolved dependency
|
||||
assert list(ws.resolve(parse_requirements("Foo[bar]"), ad)) == [Foo, Baz]
|
||||
# Requests for conflicting versions produce VersionConflict
|
||||
with pytest.raises(VersionConflict) as vc:
|
||||
ws.resolve(parse_requirements("Foo==1.2\nFoo!=1.2"), ad)
|
||||
|
||||
msg = 'Foo 0.9 is installed but Foo==1.2 is required'
|
||||
assert vc.value.report() == msg
|
||||
|
||||
def test_environment_marker_evaluation_negative(self):
|
||||
"""Environment markers are evaluated at resolution time."""
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
res = ws.resolve(parse_requirements("Foo;python_version<'2'"), ad)
|
||||
assert list(res) == []
|
||||
|
||||
def test_environment_marker_evaluation_positive(self):
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
Foo = Distribution.from_filename("/foo_dir/Foo-1.2.dist-info")
|
||||
ad.add(Foo)
|
||||
res = ws.resolve(parse_requirements("Foo;python_version>='2'"), ad)
|
||||
assert list(res) == [Foo]
|
||||
|
||||
def test_environment_marker_evaluation_called(self):
|
||||
"""
|
||||
If one package foo requires bar without any extras,
|
||||
markers should pass for bar without extras.
|
||||
"""
|
||||
(parent_req,) = parse_requirements("foo")
|
||||
(req,) = parse_requirements("bar;python_version>='2'")
|
||||
req_extras = pkg_resources._ReqExtras({req: parent_req.extras})
|
||||
assert req_extras.markers_pass(req)
|
||||
|
||||
(parent_req,) = parse_requirements("foo[]")
|
||||
(req,) = parse_requirements("bar;python_version>='2'")
|
||||
req_extras = pkg_resources._ReqExtras({req: parent_req.extras})
|
||||
assert req_extras.markers_pass(req)
|
||||
|
||||
def test_marker_evaluation_with_extras(self):
|
||||
"""Extras are also evaluated as markers at resolution time."""
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
Foo = Distribution.from_filename(
|
||||
"/foo_dir/Foo-1.2.dist-info",
|
||||
metadata=Metadata((
|
||||
"METADATA",
|
||||
"Provides-Extra: baz\nRequires-Dist: quux; extra=='baz'",
|
||||
)),
|
||||
)
|
||||
ad.add(Foo)
|
||||
assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
|
||||
quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
|
||||
ad.add(quux)
|
||||
res = list(ws.resolve(parse_requirements("Foo[baz]"), ad))
|
||||
assert res == [Foo, quux]
|
||||
|
||||
def test_marker_evaluation_with_extras_normlized(self):
|
||||
"""Extras are also evaluated as markers at resolution time."""
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
Foo = Distribution.from_filename(
|
||||
"/foo_dir/Foo-1.2.dist-info",
|
||||
metadata=Metadata((
|
||||
"METADATA",
|
||||
"Provides-Extra: baz-lightyear\n"
|
||||
"Requires-Dist: quux; extra=='baz-lightyear'",
|
||||
)),
|
||||
)
|
||||
ad.add(Foo)
|
||||
assert list(ws.resolve(parse_requirements("Foo"), ad)) == [Foo]
|
||||
quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
|
||||
ad.add(quux)
|
||||
res = list(ws.resolve(parse_requirements("Foo[baz-lightyear]"), ad))
|
||||
assert res == [Foo, quux]
|
||||
|
||||
def test_marker_evaluation_with_multiple_extras(self):
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
Foo = Distribution.from_filename(
|
||||
"/foo_dir/Foo-1.2.dist-info",
|
||||
metadata=Metadata((
|
||||
"METADATA",
|
||||
"Provides-Extra: baz\n"
|
||||
"Requires-Dist: quux; extra=='baz'\n"
|
||||
"Provides-Extra: bar\n"
|
||||
"Requires-Dist: fred; extra=='bar'\n",
|
||||
)),
|
||||
)
|
||||
ad.add(Foo)
|
||||
quux = Distribution.from_filename("/foo_dir/quux-1.0.dist-info")
|
||||
ad.add(quux)
|
||||
fred = Distribution.from_filename("/foo_dir/fred-0.1.dist-info")
|
||||
ad.add(fred)
|
||||
res = list(ws.resolve(parse_requirements("Foo[baz,bar]"), ad))
|
||||
assert sorted(res) == [fred, quux, Foo]
|
||||
|
||||
def test_marker_evaluation_with_extras_loop(self):
|
||||
ad = pkg_resources.Environment([])
|
||||
ws = WorkingSet([])
|
||||
a = Distribution.from_filename(
|
||||
"/foo_dir/a-0.2.dist-info",
|
||||
metadata=Metadata(("METADATA", "Requires-Dist: c[a]")),
|
||||
)
|
||||
b = Distribution.from_filename(
|
||||
"/foo_dir/b-0.3.dist-info",
|
||||
metadata=Metadata(("METADATA", "Requires-Dist: c[b]")),
|
||||
)
|
||||
c = Distribution.from_filename(
|
||||
"/foo_dir/c-1.0.dist-info",
|
||||
metadata=Metadata((
|
||||
"METADATA",
|
||||
"Provides-Extra: a\n"
|
||||
"Requires-Dist: b;extra=='a'\n"
|
||||
"Provides-Extra: b\n"
|
||||
"Requires-Dist: foo;extra=='b'",
|
||||
)),
|
||||
)
|
||||
foo = Distribution.from_filename("/foo_dir/foo-0.1.dist-info")
|
||||
for dist in (a, b, c, foo):
|
||||
ad.add(dist)
|
||||
res = list(ws.resolve(parse_requirements("a"), ad))
|
||||
assert res == [a, c, b, foo]
|
||||
|
||||
@pytest.mark.xfail(
|
||||
sys.version_info[:2] == (3, 12) and sys.version_info.releaselevel != 'final',
|
||||
reason="https://github.com/python/cpython/issues/103632",
|
||||
)
|
||||
def testDistroDependsOptions(self):
|
||||
d = self.distRequires(
|
||||
"""
|
||||
Twisted>=1.5
|
||||
[docgen]
|
||||
ZConfig>=2.0
|
||||
docutils>=0.3
|
||||
[fastcgi]
|
||||
fcgiapp>=0.1"""
|
||||
)
|
||||
self.checkRequires(d, "Twisted>=1.5")
|
||||
self.checkRequires(
|
||||
d, "Twisted>=1.5 ZConfig>=2.0 docutils>=0.3".split(), ["docgen"]
|
||||
)
|
||||
self.checkRequires(d, "Twisted>=1.5 fcgiapp>=0.1".split(), ["fastcgi"])
|
||||
self.checkRequires(
|
||||
d,
|
||||
"Twisted>=1.5 ZConfig>=2.0 docutils>=0.3 fcgiapp>=0.1".split(),
|
||||
["docgen", "fastcgi"],
|
||||
)
|
||||
self.checkRequires(
|
||||
d,
|
||||
"Twisted>=1.5 fcgiapp>=0.1 ZConfig>=2.0 docutils>=0.3".split(),
|
||||
["fastcgi", "docgen"],
|
||||
)
|
||||
with pytest.raises(pkg_resources.UnknownExtra):
|
||||
d.requires(["foo"])
|
||||
|
||||
|
||||
class TestWorkingSet:
|
||||
def test_find_conflicting(self):
|
||||
ws = WorkingSet([])
|
||||
Foo = Distribution.from_filename("/foo_dir/Foo-1.2.egg")
|
||||
ws.add(Foo)
|
||||
|
||||
# create a requirement that conflicts with Foo 1.2
|
||||
req = next(parse_requirements("Foo<1.2"))
|
||||
|
||||
with pytest.raises(VersionConflict) as vc:
|
||||
ws.find(req)
|
||||
|
||||
msg = 'Foo 1.2 is installed but Foo<1.2 is required'
|
||||
assert vc.value.report() == msg
|
||||
|
||||
def test_resolve_conflicts_with_prior(self):
|
||||
"""
|
||||
A ContextualVersionConflict should be raised when a requirement
|
||||
conflicts with a prior requirement for a different package.
|
||||
"""
|
||||
# Create installation where Foo depends on Baz 1.0 and Bar depends on
|
||||
# Baz 2.0.
|
||||
ws = WorkingSet([])
|
||||
md = Metadata(('depends.txt', "Baz==1.0"))
|
||||
Foo = Distribution.from_filename("/foo_dir/Foo-1.0.egg", metadata=md)
|
||||
ws.add(Foo)
|
||||
md = Metadata(('depends.txt', "Baz==2.0"))
|
||||
Bar = Distribution.from_filename("/foo_dir/Bar-1.0.egg", metadata=md)
|
||||
ws.add(Bar)
|
||||
Baz = Distribution.from_filename("/foo_dir/Baz-1.0.egg")
|
||||
ws.add(Baz)
|
||||
Baz = Distribution.from_filename("/foo_dir/Baz-2.0.egg")
|
||||
ws.add(Baz)
|
||||
|
||||
with pytest.raises(VersionConflict) as vc:
|
||||
ws.resolve(parse_requirements("Foo\nBar\n"))
|
||||
|
||||
msg = "Baz 1.0 is installed but Baz==2.0 is required by "
|
||||
msg += repr(set(['Bar']))
|
||||
assert vc.value.report() == msg
|
||||
|
||||
|
||||
class TestEntryPoints:
|
||||
def assertfields(self, ep):
|
||||
assert ep.name == "foo"
|
||||
assert ep.module_name == "pkg_resources.tests.test_resources"
|
||||
assert ep.attrs == ("TestEntryPoints",)
|
||||
assert ep.extras == ("x",)
|
||||
assert ep.load() is TestEntryPoints
|
||||
expect = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]"
|
||||
assert str(ep) == expect
|
||||
|
||||
def setup_method(self, method):
|
||||
self.dist = Distribution.from_filename(
|
||||
"FooPkg-1.2-py2.4.egg", metadata=Metadata(('requires.txt', '[x]'))
|
||||
)
|
||||
|
||||
def testBasics(self):
|
||||
ep = EntryPoint(
|
||||
"foo",
|
||||
"pkg_resources.tests.test_resources",
|
||||
["TestEntryPoints"],
|
||||
["x"],
|
||||
self.dist,
|
||||
)
|
||||
self.assertfields(ep)
|
||||
|
||||
def testParse(self):
|
||||
s = "foo = pkg_resources.tests.test_resources:TestEntryPoints [x]"
|
||||
ep = EntryPoint.parse(s, self.dist)
|
||||
self.assertfields(ep)
|
||||
|
||||
ep = EntryPoint.parse("bar baz= spammity[PING]")
|
||||
assert ep.name == "bar baz"
|
||||
assert ep.module_name == "spammity"
|
||||
assert ep.attrs == ()
|
||||
assert ep.extras == ("ping",)
|
||||
|
||||
ep = EntryPoint.parse(" fizzly = wocka:foo")
|
||||
assert ep.name == "fizzly"
|
||||
assert ep.module_name == "wocka"
|
||||
assert ep.attrs == ("foo",)
|
||||
assert ep.extras == ()
|
||||
|
||||
# plus in the name
|
||||
spec = "html+mako = mako.ext.pygmentplugin:MakoHtmlLexer"
|
||||
ep = EntryPoint.parse(spec)
|
||||
assert ep.name == 'html+mako'
|
||||
|
||||
reject_specs = "foo", "x=a:b:c", "q=x/na", "fez=pish:tush-z", "x=f[a]>2"
|
||||
|
||||
@pytest.mark.parametrize("reject_spec", reject_specs)
|
||||
def test_reject_spec(self, reject_spec):
|
||||
with pytest.raises(ValueError):
|
||||
EntryPoint.parse(reject_spec)
|
||||
|
||||
def test_printable_name(self):
|
||||
"""
|
||||
Allow any printable character in the name.
|
||||
"""
|
||||
# Create a name with all printable characters; strip the whitespace.
|
||||
name = string.printable.strip()
|
||||
spec = "{name} = module:attr".format(**locals())
|
||||
ep = EntryPoint.parse(spec)
|
||||
assert ep.name == name
|
||||
|
||||
def checkSubMap(self, m):
|
||||
assert len(m) == len(self.submap_expect)
|
||||
for key, ep in self.submap_expect.items():
|
||||
assert m.get(key).name == ep.name
|
||||
assert m.get(key).module_name == ep.module_name
|
||||
assert sorted(m.get(key).attrs) == sorted(ep.attrs)
|
||||
assert sorted(m.get(key).extras) == sorted(ep.extras)
|
||||
|
||||
submap_expect = dict(
|
||||
feature1=EntryPoint('feature1', 'somemodule', ['somefunction']),
|
||||
feature2=EntryPoint(
|
||||
'feature2', 'another.module', ['SomeClass'], ['extra1', 'extra2']
|
||||
),
|
||||
feature3=EntryPoint('feature3', 'this.module', extras=['something']),
|
||||
)
|
||||
submap_str = """
|
||||
# define features for blah blah
|
||||
feature1 = somemodule:somefunction
|
||||
feature2 = another.module:SomeClass [extra1,extra2]
|
||||
feature3 = this.module [something]
|
||||
"""
|
||||
|
||||
def testParseList(self):
|
||||
self.checkSubMap(EntryPoint.parse_group("xyz", self.submap_str))
|
||||
with pytest.raises(ValueError):
|
||||
EntryPoint.parse_group("x a", "foo=bar")
|
||||
with pytest.raises(ValueError):
|
||||
EntryPoint.parse_group("x", ["foo=baz", "foo=bar"])
|
||||
|
||||
def testParseMap(self):
|
||||
m = EntryPoint.parse_map({'xyz': self.submap_str})
|
||||
self.checkSubMap(m['xyz'])
|
||||
assert list(m.keys()) == ['xyz']
|
||||
m = EntryPoint.parse_map("[xyz]\n" + self.submap_str)
|
||||
self.checkSubMap(m['xyz'])
|
||||
assert list(m.keys()) == ['xyz']
|
||||
with pytest.raises(ValueError):
|
||||
EntryPoint.parse_map(["[xyz]", "[xyz]"])
|
||||
with pytest.raises(ValueError):
|
||||
EntryPoint.parse_map(self.submap_str)
|
||||
|
||||
def testDeprecationWarnings(self):
|
||||
ep = EntryPoint(
|
||||
"foo", "pkg_resources.tests.test_resources", ["TestEntryPoints"], ["x"]
|
||||
)
|
||||
with pytest.warns(pkg_resources.PkgResourcesDeprecationWarning):
|
||||
ep.load(require=False)
|
||||
|
||||
|
||||
class TestRequirements:
|
||||
def testBasics(self):
|
||||
r = Requirement.parse("Twisted>=1.2")
|
||||
assert str(r) == "Twisted>=1.2"
|
||||
assert repr(r) == "Requirement.parse('Twisted>=1.2')"
|
||||
assert r == Requirement("Twisted>=1.2")
|
||||
assert r == Requirement("twisTed>=1.2")
|
||||
assert r != Requirement("Twisted>=2.0")
|
||||
assert r != Requirement("Zope>=1.2")
|
||||
assert r != Requirement("Zope>=3.0")
|
||||
assert r != Requirement("Twisted[extras]>=1.2")
|
||||
|
||||
def testOrdering(self):
|
||||
r1 = Requirement("Twisted==1.2c1,>=1.2")
|
||||
r2 = Requirement("Twisted>=1.2,==1.2c1")
|
||||
assert r1 == r2
|
||||
assert str(r1) == str(r2)
|
||||
assert str(r2) == "Twisted==1.2c1,>=1.2"
|
||||
assert Requirement("Twisted") != Requirement(
|
||||
"Twisted @ https://localhost/twisted.zip"
|
||||
)
|
||||
|
||||
def testBasicContains(self):
|
||||
r = Requirement("Twisted>=1.2")
|
||||
foo_dist = Distribution.from_filename("FooPkg-1.3_1.egg")
|
||||
twist11 = Distribution.from_filename("Twisted-1.1.egg")
|
||||
twist12 = Distribution.from_filename("Twisted-1.2.egg")
|
||||
assert parse_version('1.2') in r
|
||||
assert parse_version('1.1') not in r
|
||||
assert '1.2' in r
|
||||
assert '1.1' not in r
|
||||
assert foo_dist not in r
|
||||
assert twist11 not in r
|
||||
assert twist12 in r
|
||||
|
||||
def testOptionsAndHashing(self):
|
||||
r1 = Requirement.parse("Twisted[foo,bar]>=1.2")
|
||||
r2 = Requirement.parse("Twisted[bar,FOO]>=1.2")
|
||||
assert r1 == r2
|
||||
assert set(r1.extras) == set(("foo", "bar"))
|
||||
assert set(r2.extras) == set(("foo", "bar"))
|
||||
assert hash(r1) == hash(r2)
|
||||
assert hash(r1) == hash((
|
||||
"twisted",
|
||||
None,
|
||||
SpecifierSet(">=1.2"),
|
||||
frozenset(["foo", "bar"]),
|
||||
None,
|
||||
))
|
||||
assert hash(
|
||||
Requirement.parse("Twisted @ https://localhost/twisted.zip")
|
||||
) == hash((
|
||||
"twisted",
|
||||
"https://localhost/twisted.zip",
|
||||
SpecifierSet(),
|
||||
frozenset(),
|
||||
None,
|
||||
))
|
||||
|
||||
def testVersionEquality(self):
|
||||
r1 = Requirement.parse("foo==0.3a2")
|
||||
r2 = Requirement.parse("foo!=0.3a4")
|
||||
d = Distribution.from_filename
|
||||
|
||||
assert d("foo-0.3a4.egg") not in r1
|
||||
assert d("foo-0.3a1.egg") not in r1
|
||||
assert d("foo-0.3a4.egg") not in r2
|
||||
|
||||
assert d("foo-0.3a2.egg") in r1
|
||||
assert d("foo-0.3a2.egg") in r2
|
||||
assert d("foo-0.3a3.egg") in r2
|
||||
assert d("foo-0.3a5.egg") in r2
|
||||
|
||||
def testSetuptoolsProjectName(self):
|
||||
"""
|
||||
The setuptools project should implement the setuptools package.
|
||||
"""
|
||||
|
||||
assert Requirement.parse('setuptools').project_name == 'setuptools'
|
||||
# setuptools 0.7 and higher means setuptools.
|
||||
assert Requirement.parse('setuptools == 0.7').project_name == 'setuptools'
|
||||
assert Requirement.parse('setuptools == 0.7a1').project_name == 'setuptools'
|
||||
assert Requirement.parse('setuptools >= 0.7').project_name == 'setuptools'
|
||||
|
||||
|
||||
class TestParsing:
|
||||
def testEmptyParse(self):
|
||||
assert list(parse_requirements('')) == []
|
||||
|
||||
def testYielding(self):
|
||||
for inp, out in [
|
||||
([], []),
|
||||
('x', ['x']),
|
||||
([[]], []),
|
||||
(' x\n y', ['x', 'y']),
|
||||
(['x\n\n', 'y'], ['x', 'y']),
|
||||
]:
|
||||
assert list(pkg_resources.yield_lines(inp)) == out
|
||||
|
||||
def testSplitting(self):
|
||||
sample = """
|
||||
x
|
||||
[Y]
|
||||
z
|
||||
|
||||
a
|
||||
[b ]
|
||||
# foo
|
||||
c
|
||||
[ d]
|
||||
[q]
|
||||
v
|
||||
"""
|
||||
assert list(pkg_resources.split_sections(sample)) == [
|
||||
(None, ["x"]),
|
||||
("Y", ["z", "a"]),
|
||||
("b", ["c"]),
|
||||
("d", []),
|
||||
("q", ["v"]),
|
||||
]
|
||||
with pytest.raises(ValueError):
|
||||
list(pkg_resources.split_sections("[foo"))
|
||||
|
||||
def testSafeName(self):
|
||||
assert safe_name("adns-python") == "adns-python"
|
||||
assert safe_name("WSGI Utils") == "WSGI-Utils"
|
||||
assert safe_name("WSGI Utils") == "WSGI-Utils"
|
||||
assert safe_name("Money$$$Maker") == "Money-Maker"
|
||||
assert safe_name("peak.web") != "peak-web"
|
||||
|
||||
def testSafeVersion(self):
|
||||
assert safe_version("1.2-1") == "1.2.post1"
|
||||
assert safe_version("1.2 alpha") == "1.2.alpha"
|
||||
assert safe_version("2.3.4 20050521") == "2.3.4.20050521"
|
||||
assert safe_version("Money$$$Maker") == "Money-Maker"
|
||||
assert safe_version("peak.web") == "peak.web"
|
||||
|
||||
def testSimpleRequirements(self):
|
||||
assert list(parse_requirements('Twis-Ted>=1.2-1')) == [
|
||||
Requirement('Twis-Ted>=1.2-1')
|
||||
]
|
||||
assert list(parse_requirements('Twisted >=1.2, \\ # more\n<2.0')) == [
|
||||
Requirement('Twisted>=1.2,<2.0')
|
||||
]
|
||||
assert Requirement.parse("FooBar==1.99a3") == Requirement("FooBar==1.99a3")
|
||||
with pytest.raises(ValueError):
|
||||
Requirement.parse(">=2.3")
|
||||
with pytest.raises(ValueError):
|
||||
Requirement.parse("x\\")
|
||||
with pytest.raises(ValueError):
|
||||
Requirement.parse("x==2 q")
|
||||
with pytest.raises(ValueError):
|
||||
Requirement.parse("X==1\nY==2")
|
||||
with pytest.raises(ValueError):
|
||||
Requirement.parse("#")
|
||||
|
||||
def test_requirements_with_markers(self):
|
||||
assert Requirement.parse("foobar;os_name=='a'") == Requirement.parse(
|
||||
"foobar;os_name=='a'"
|
||||
)
|
||||
assert Requirement.parse(
|
||||
"name==1.1;python_version=='2.7'"
|
||||
) != Requirement.parse("name==1.1;python_version=='3.6'")
|
||||
assert Requirement.parse(
|
||||
"name==1.0;python_version=='2.7'"
|
||||
) != Requirement.parse("name==1.2;python_version=='2.7'")
|
||||
assert Requirement.parse(
|
||||
"name[foo]==1.0;python_version=='3.6'"
|
||||
) != Requirement.parse("name[foo,bar]==1.0;python_version=='3.6'")
|
||||
|
||||
def test_local_version(self):
|
||||
parse_requirements('foo==1.0+org1')
|
||||
|
||||
def test_spaces_between_multiple_versions(self):
|
||||
parse_requirements('foo>=1.0, <3')
|
||||
parse_requirements('foo >= 1.0, < 3')
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("lower", "upper"),
|
||||
[
|
||||
('1.2-rc1', '1.2rc1'),
|
||||
('0.4', '0.4.0'),
|
||||
('0.4.0.0', '0.4.0'),
|
||||
('0.4.0-0', '0.4-0'),
|
||||
('0post1', '0.0post1'),
|
||||
('0pre1', '0.0c1'),
|
||||
('0.0.0preview1', '0c1'),
|
||||
('0.0c1', '0-rc1'),
|
||||
('1.2a1', '1.2.a.1'),
|
||||
('1.2.a', '1.2a'),
|
||||
],
|
||||
)
|
||||
def testVersionEquality(self, lower, upper):
|
||||
assert parse_version(lower) == parse_version(upper)
|
||||
|
||||
torture = """
|
||||
0.80.1-3 0.80.1-2 0.80.1-1 0.79.9999+0.80.0pre4-1
|
||||
0.79.9999+0.80.0pre2-3 0.79.9999+0.80.0pre2-2
|
||||
0.77.2-1 0.77.1-1 0.77.0-1
|
||||
"""
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("lower", "upper"),
|
||||
[
|
||||
('2.1', '2.1.1'),
|
||||
('2a1', '2b0'),
|
||||
('2a1', '2.1'),
|
||||
('2.3a1', '2.3'),
|
||||
('2.1-1', '2.1-2'),
|
||||
('2.1-1', '2.1.1'),
|
||||
('2.1', '2.1post4'),
|
||||
('2.1a0-20040501', '2.1'),
|
||||
('1.1', '02.1'),
|
||||
('3.2', '3.2.post0'),
|
||||
('3.2post1', '3.2post2'),
|
||||
('0.4', '4.0'),
|
||||
('0.0.4', '0.4.0'),
|
||||
('0post1', '0.4post1'),
|
||||
('2.1.0-rc1', '2.1.0'),
|
||||
('2.1dev', '2.1a0'),
|
||||
]
|
||||
+ list(pairwise(reversed(torture.split()))),
|
||||
)
|
||||
def testVersionOrdering(self, lower, upper):
|
||||
assert parse_version(lower) < parse_version(upper)
|
||||
|
||||
def testVersionHashable(self):
|
||||
"""
|
||||
Ensure that our versions stay hashable even though we've subclassed
|
||||
them and added some shim code to them.
|
||||
"""
|
||||
assert hash(parse_version("1.0")) == hash(parse_version("1.0"))
|
||||
|
||||
|
||||
class TestNamespaces:
|
||||
ns_str = "__import__('pkg_resources').declare_namespace(__name__)\n"
|
||||
|
||||
@pytest.fixture
|
||||
def symlinked_tmpdir(self, tmpdir):
|
||||
"""
|
||||
Where available, return the tempdir as a symlink,
|
||||
which as revealed in #231 is more fragile than
|
||||
a natural tempdir.
|
||||
"""
|
||||
if not hasattr(os, 'symlink'):
|
||||
yield str(tmpdir)
|
||||
return
|
||||
|
||||
link_name = str(tmpdir) + '-linked'
|
||||
os.symlink(str(tmpdir), link_name)
|
||||
try:
|
||||
yield type(tmpdir)(link_name)
|
||||
finally:
|
||||
os.unlink(link_name)
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def patched_path(self, tmpdir):
|
||||
"""
|
||||
Patch sys.path to include the 'site-pkgs' dir. Also
|
||||
restore pkg_resources._namespace_packages to its
|
||||
former state.
|
||||
"""
|
||||
saved_ns_pkgs = pkg_resources._namespace_packages.copy()
|
||||
saved_sys_path = sys.path[:]
|
||||
site_pkgs = tmpdir.mkdir('site-pkgs')
|
||||
sys.path.append(str(site_pkgs))
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
pkg_resources._namespace_packages = saved_ns_pkgs
|
||||
sys.path = saved_sys_path
|
||||
|
||||
issue591 = pytest.mark.xfail(platform.system() == 'Windows', reason="#591")
|
||||
|
||||
@issue591
|
||||
def test_two_levels_deep(self, symlinked_tmpdir):
|
||||
"""
|
||||
Test nested namespace packages
|
||||
Create namespace packages in the following tree :
|
||||
site-packages-1/pkg1/pkg2
|
||||
site-packages-2/pkg1/pkg2
|
||||
Check both are in the _namespace_packages dict and that their __path__
|
||||
is correct
|
||||
"""
|
||||
real_tmpdir = symlinked_tmpdir.realpath()
|
||||
tmpdir = symlinked_tmpdir
|
||||
sys.path.append(str(tmpdir / 'site-pkgs2'))
|
||||
site_dirs = tmpdir / 'site-pkgs', tmpdir / 'site-pkgs2'
|
||||
for site in site_dirs:
|
||||
pkg1 = site / 'pkg1'
|
||||
pkg2 = pkg1 / 'pkg2'
|
||||
pkg2.ensure_dir()
|
||||
(pkg1 / '__init__.py').write_text(self.ns_str, encoding='utf-8')
|
||||
(pkg2 / '__init__.py').write_text(self.ns_str, encoding='utf-8')
|
||||
with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"):
|
||||
import pkg1 # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
assert "pkg1" in pkg_resources._namespace_packages
|
||||
# attempt to import pkg2 from site-pkgs2
|
||||
with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"):
|
||||
import pkg1.pkg2 # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
# check the _namespace_packages dict
|
||||
assert "pkg1.pkg2" in pkg_resources._namespace_packages
|
||||
assert pkg_resources._namespace_packages["pkg1"] == ["pkg1.pkg2"]
|
||||
# check the __path__ attribute contains both paths
|
||||
expected = [
|
||||
str(real_tmpdir / "site-pkgs" / "pkg1" / "pkg2"),
|
||||
str(real_tmpdir / "site-pkgs2" / "pkg1" / "pkg2"),
|
||||
]
|
||||
assert pkg1.pkg2.__path__ == expected
|
||||
|
||||
@issue591
|
||||
def test_path_order(self, symlinked_tmpdir):
|
||||
"""
|
||||
Test that if multiple versions of the same namespace package subpackage
|
||||
are on different sys.path entries, that only the one earliest on
|
||||
sys.path is imported, and that the namespace package's __path__ is in
|
||||
the correct order.
|
||||
|
||||
Regression test for https://github.com/pypa/setuptools/issues/207
|
||||
"""
|
||||
|
||||
tmpdir = symlinked_tmpdir
|
||||
site_dirs = (
|
||||
tmpdir / "site-pkgs",
|
||||
tmpdir / "site-pkgs2",
|
||||
tmpdir / "site-pkgs3",
|
||||
)
|
||||
|
||||
vers_str = "__version__ = %r"
|
||||
|
||||
for number, site in enumerate(site_dirs, 1):
|
||||
if number > 1:
|
||||
sys.path.append(str(site))
|
||||
nspkg = site / 'nspkg'
|
||||
subpkg = nspkg / 'subpkg'
|
||||
subpkg.ensure_dir()
|
||||
(nspkg / '__init__.py').write_text(self.ns_str, encoding='utf-8')
|
||||
(subpkg / '__init__.py').write_text(vers_str % number, encoding='utf-8')
|
||||
|
||||
with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"):
|
||||
import nspkg # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
import nspkg.subpkg # pyright: ignore[reportMissingImports] # Temporary package for test
|
||||
expected = [str(site.realpath() / 'nspkg') for site in site_dirs]
|
||||
assert nspkg.__path__ == expected
|
||||
assert nspkg.subpkg.__version__ == 1
|
@@ -0,0 +1,505 @@
|
||||
import functools
|
||||
import inspect
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
import pytest
|
||||
|
||||
import pkg_resources
|
||||
|
||||
from .test_resources import Metadata
|
||||
|
||||
|
||||
def strip_comments(s):
|
||||
return '\n'.join(
|
||||
line
|
||||
for line in s.split('\n')
|
||||
if line.strip() and not line.strip().startswith('#')
|
||||
)
|
||||
|
||||
|
||||
def parse_distributions(s):
|
||||
"""
|
||||
Parse a series of distribution specs of the form:
|
||||
{project_name}-{version}
|
||||
[optional, indented requirements specification]
|
||||
|
||||
Example:
|
||||
|
||||
foo-0.2
|
||||
bar-1.0
|
||||
foo>=3.0
|
||||
[feature]
|
||||
baz
|
||||
|
||||
yield 2 distributions:
|
||||
- project_name=foo, version=0.2
|
||||
- project_name=bar, version=1.0,
|
||||
requires=['foo>=3.0', 'baz; extra=="feature"']
|
||||
"""
|
||||
s = s.strip()
|
||||
for spec in re.split(r'\n(?=[^\s])', s):
|
||||
if not spec:
|
||||
continue
|
||||
fields = spec.split('\n', 1)
|
||||
assert 1 <= len(fields) <= 2
|
||||
name, version = fields.pop(0).rsplit('-', 1)
|
||||
if fields:
|
||||
requires = textwrap.dedent(fields.pop(0))
|
||||
metadata = Metadata(('requires.txt', requires))
|
||||
else:
|
||||
metadata = None
|
||||
dist = pkg_resources.Distribution(
|
||||
project_name=name, version=version, metadata=metadata
|
||||
)
|
||||
yield dist
|
||||
|
||||
|
||||
class FakeInstaller:
|
||||
def __init__(self, installable_dists) -> None:
|
||||
self._installable_dists = installable_dists
|
||||
|
||||
def __call__(self, req):
|
||||
return next(
|
||||
iter(filter(lambda dist: dist in req, self._installable_dists)), None
|
||||
)
|
||||
|
||||
|
||||
def parametrize_test_working_set_resolve(*test_list):
|
||||
idlist = []
|
||||
argvalues = []
|
||||
for test in test_list:
|
||||
(
|
||||
name,
|
||||
installed_dists,
|
||||
installable_dists,
|
||||
requirements,
|
||||
expected1,
|
||||
expected2,
|
||||
) = (
|
||||
strip_comments(s.lstrip())
|
||||
for s in textwrap.dedent(test).lstrip().split('\n\n', 5)
|
||||
)
|
||||
installed_dists = list(parse_distributions(installed_dists))
|
||||
installable_dists = list(parse_distributions(installable_dists))
|
||||
requirements = list(pkg_resources.parse_requirements(requirements))
|
||||
for id_, replace_conflicting, expected in (
|
||||
(name, False, expected1),
|
||||
(name + '_replace_conflicting', True, expected2),
|
||||
):
|
||||
idlist.append(id_)
|
||||
expected = strip_comments(expected.strip())
|
||||
if re.match(r'\w+$', expected):
|
||||
expected = getattr(pkg_resources, expected)
|
||||
assert issubclass(expected, Exception)
|
||||
else:
|
||||
expected = list(parse_distributions(expected))
|
||||
argvalues.append(
|
||||
pytest.param(
|
||||
installed_dists,
|
||||
installable_dists,
|
||||
requirements,
|
||||
replace_conflicting,
|
||||
expected,
|
||||
)
|
||||
)
|
||||
return pytest.mark.parametrize(
|
||||
(
|
||||
"installed_dists",
|
||||
"installable_dists",
|
||||
"requirements",
|
||||
"replace_conflicting",
|
||||
"resolved_dists_or_exception",
|
||||
),
|
||||
argvalues,
|
||||
ids=idlist,
|
||||
)
|
||||
|
||||
|
||||
@parametrize_test_working_set_resolve(
|
||||
"""
|
||||
# id
|
||||
noop
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
|
||||
# resolved
|
||||
|
||||
# resolved [replace conflicting]
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
already_installed
|
||||
|
||||
# installed
|
||||
foo-3.0
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# resolved
|
||||
foo-3.0
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.0
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installable_not_installed
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
foo-3.0
|
||||
foo-4.0
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# resolved
|
||||
foo-3.0
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.0
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
not_installable
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# resolved
|
||||
DistributionNotFound
|
||||
|
||||
# resolved [replace conflicting]
|
||||
DistributionNotFound
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
no_matching_version
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
foo-3.1
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# resolved
|
||||
DistributionNotFound
|
||||
|
||||
# resolved [replace conflicting]
|
||||
DistributionNotFound
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installable_with_installed_conflict
|
||||
|
||||
# installed
|
||||
foo-3.1
|
||||
|
||||
# installable
|
||||
foo-3.5
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.5
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
not_installable_with_installed_conflict
|
||||
|
||||
# installed
|
||||
foo-3.1
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
DistributionNotFound
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installed_with_installed_require
|
||||
|
||||
# installed
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installed_with_conflicting_installed_require
|
||||
|
||||
# installed
|
||||
foo-5
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
DistributionNotFound
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installed_with_installable_conflicting_require
|
||||
|
||||
# installed
|
||||
foo-5
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# installable
|
||||
foo-2.9
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
baz-0.1
|
||||
foo-2.9
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installed_with_installable_require
|
||||
|
||||
# installed
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# installable
|
||||
foo-3.9
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installable_with_installed_require
|
||||
|
||||
# installed
|
||||
foo-3.9
|
||||
|
||||
# installable
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installable_with_installable_require
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo-3.9
|
||||
baz-0.1
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installable_with_conflicting_installable_require
|
||||
|
||||
# installed
|
||||
foo-5
|
||||
|
||||
# installable
|
||||
foo-2.9
|
||||
baz-0.1
|
||||
foo>=2.1,!=3.1,<4
|
||||
|
||||
# wanted
|
||||
baz
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
baz-0.1
|
||||
foo-2.9
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
conflicting_installables
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
foo-2.9
|
||||
foo-5.0
|
||||
|
||||
# wanted
|
||||
foo>=2.1,!=3.1,<4
|
||||
foo>=4
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
VersionConflict
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installables_with_conflicting_requires
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
foo-2.9
|
||||
dep==1.0
|
||||
baz-5.0
|
||||
dep==2.0
|
||||
dep-1.0
|
||||
dep-2.0
|
||||
|
||||
# wanted
|
||||
foo
|
||||
baz
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
VersionConflict
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
installables_with_conflicting_nested_requires
|
||||
|
||||
# installed
|
||||
|
||||
# installable
|
||||
foo-2.9
|
||||
dep1
|
||||
dep1-1.0
|
||||
subdep<1.0
|
||||
baz-5.0
|
||||
dep2
|
||||
dep2-1.0
|
||||
subdep>1.0
|
||||
subdep-0.9
|
||||
subdep-1.1
|
||||
|
||||
# wanted
|
||||
foo
|
||||
baz
|
||||
|
||||
# resolved
|
||||
VersionConflict
|
||||
|
||||
# resolved [replace conflicting]
|
||||
VersionConflict
|
||||
""",
|
||||
"""
|
||||
# id
|
||||
wanted_normalized_name_installed_canonical
|
||||
|
||||
# installed
|
||||
foo.bar-3.6
|
||||
|
||||
# installable
|
||||
|
||||
# wanted
|
||||
foo-bar==3.6
|
||||
|
||||
# resolved
|
||||
foo.bar-3.6
|
||||
|
||||
# resolved [replace conflicting]
|
||||
foo.bar-3.6
|
||||
""",
|
||||
)
|
||||
def test_working_set_resolve(
|
||||
installed_dists,
|
||||
installable_dists,
|
||||
requirements,
|
||||
replace_conflicting,
|
||||
resolved_dists_or_exception,
|
||||
):
|
||||
ws = pkg_resources.WorkingSet([])
|
||||
list(map(ws.add, installed_dists))
|
||||
resolve_call = functools.partial(
|
||||
ws.resolve,
|
||||
requirements,
|
||||
installer=FakeInstaller(installable_dists),
|
||||
replace_conflicting=replace_conflicting,
|
||||
)
|
||||
if inspect.isclass(resolved_dists_or_exception):
|
||||
with pytest.raises(resolved_dists_or_exception):
|
||||
resolve_call()
|
||||
else:
|
||||
assert sorted(resolve_call()) == sorted(resolved_dists_or_exception)
|
@@ -0,0 +1 @@
|
||||
pip
|
@@ -0,0 +1,141 @@
|
||||
Metadata-Version: 2.4
|
||||
Name: setuptools
|
||||
Version: 80.9.0
|
||||
Summary: Easily download, build, install, upgrade, and uninstall Python packages
|
||||
Author-email: Python Packaging Authority <distutils-sig@python.org>
|
||||
License-Expression: MIT
|
||||
Project-URL: Source, https://github.com/pypa/setuptools
|
||||
Project-URL: Documentation, https://setuptools.pypa.io/
|
||||
Project-URL: Changelog, https://setuptools.pypa.io/en/stable/history.html
|
||||
Keywords: CPAN PyPI distutils eggs package management
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3 :: Only
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
Classifier: Topic :: System :: Archiving :: Packaging
|
||||
Classifier: Topic :: System :: Systems Administration
|
||||
Classifier: Topic :: Utilities
|
||||
Requires-Python: >=3.9
|
||||
Description-Content-Type: text/x-rst
|
||||
License-File: LICENSE
|
||||
Provides-Extra: test
|
||||
Requires-Dist: pytest!=8.1.*,>=6; extra == "test"
|
||||
Requires-Dist: virtualenv>=13.0.0; extra == "test"
|
||||
Requires-Dist: wheel>=0.44.0; extra == "test"
|
||||
Requires-Dist: pip>=19.1; extra == "test"
|
||||
Requires-Dist: packaging>=24.2; extra == "test"
|
||||
Requires-Dist: jaraco.envs>=2.2; extra == "test"
|
||||
Requires-Dist: pytest-xdist>=3; extra == "test"
|
||||
Requires-Dist: jaraco.path>=3.7.2; extra == "test"
|
||||
Requires-Dist: build[virtualenv]>=1.0.3; extra == "test"
|
||||
Requires-Dist: filelock>=3.4.0; extra == "test"
|
||||
Requires-Dist: ini2toml[lite]>=0.14; extra == "test"
|
||||
Requires-Dist: tomli-w>=1.0.0; extra == "test"
|
||||
Requires-Dist: pytest-timeout; extra == "test"
|
||||
Requires-Dist: pytest-perf; sys_platform != "cygwin" and extra == "test"
|
||||
Requires-Dist: jaraco.develop>=7.21; (python_version >= "3.9" and sys_platform != "cygwin") and extra == "test"
|
||||
Requires-Dist: pytest-home>=0.5; extra == "test"
|
||||
Requires-Dist: pytest-subprocess; extra == "test"
|
||||
Requires-Dist: pyproject-hooks!=1.1; extra == "test"
|
||||
Requires-Dist: jaraco.test>=5.5; extra == "test"
|
||||
Provides-Extra: doc
|
||||
Requires-Dist: sphinx>=3.5; extra == "doc"
|
||||
Requires-Dist: jaraco.packaging>=9.3; extra == "doc"
|
||||
Requires-Dist: rst.linker>=1.9; extra == "doc"
|
||||
Requires-Dist: furo; extra == "doc"
|
||||
Requires-Dist: sphinx-lint; extra == "doc"
|
||||
Requires-Dist: jaraco.tidelift>=1.4; extra == "doc"
|
||||
Requires-Dist: pygments-github-lexers==0.0.5; extra == "doc"
|
||||
Requires-Dist: sphinx-favicon; extra == "doc"
|
||||
Requires-Dist: sphinx-inline-tabs; extra == "doc"
|
||||
Requires-Dist: sphinx-reredirects; extra == "doc"
|
||||
Requires-Dist: sphinxcontrib-towncrier; extra == "doc"
|
||||
Requires-Dist: sphinx-notfound-page<2,>=1; extra == "doc"
|
||||
Requires-Dist: pyproject-hooks!=1.1; extra == "doc"
|
||||
Requires-Dist: towncrier<24.7; extra == "doc"
|
||||
Provides-Extra: ssl
|
||||
Provides-Extra: certs
|
||||
Provides-Extra: core
|
||||
Requires-Dist: packaging>=24.2; extra == "core"
|
||||
Requires-Dist: more_itertools>=8.8; extra == "core"
|
||||
Requires-Dist: jaraco.text>=3.7; extra == "core"
|
||||
Requires-Dist: importlib_metadata>=6; python_version < "3.10" and extra == "core"
|
||||
Requires-Dist: tomli>=2.0.1; python_version < "3.11" and extra == "core"
|
||||
Requires-Dist: wheel>=0.43.0; extra == "core"
|
||||
Requires-Dist: platformdirs>=4.2.2; extra == "core"
|
||||
Requires-Dist: jaraco.functools>=4; extra == "core"
|
||||
Requires-Dist: more_itertools; extra == "core"
|
||||
Provides-Extra: check
|
||||
Requires-Dist: pytest-checkdocs>=2.4; extra == "check"
|
||||
Requires-Dist: pytest-ruff>=0.2.1; sys_platform != "cygwin" and extra == "check"
|
||||
Requires-Dist: ruff>=0.8.0; sys_platform != "cygwin" and extra == "check"
|
||||
Provides-Extra: cover
|
||||
Requires-Dist: pytest-cov; extra == "cover"
|
||||
Provides-Extra: enabler
|
||||
Requires-Dist: pytest-enabler>=2.2; extra == "enabler"
|
||||
Provides-Extra: type
|
||||
Requires-Dist: pytest-mypy; extra == "type"
|
||||
Requires-Dist: mypy==1.14.*; extra == "type"
|
||||
Requires-Dist: importlib_metadata>=7.0.2; python_version < "3.10" and extra == "type"
|
||||
Requires-Dist: jaraco.develop>=7.21; sys_platform != "cygwin" and extra == "type"
|
||||
Dynamic: license-file
|
||||
|
||||
.. |pypi-version| image:: https://img.shields.io/pypi/v/setuptools.svg
|
||||
:target: https://pypi.org/project/setuptools
|
||||
|
||||
.. |py-version| image:: https://img.shields.io/pypi/pyversions/setuptools.svg
|
||||
|
||||
.. |test-badge| image:: https://github.com/pypa/setuptools/actions/workflows/main.yml/badge.svg
|
||||
:target: https://github.com/pypa/setuptools/actions?query=workflow%3A%22tests%22
|
||||
:alt: tests
|
||||
|
||||
.. |ruff-badge| image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json
|
||||
:target: https://github.com/astral-sh/ruff
|
||||
:alt: Ruff
|
||||
|
||||
.. |docs-badge| image:: https://img.shields.io/readthedocs/setuptools/latest.svg
|
||||
:target: https://setuptools.pypa.io
|
||||
|
||||
.. |skeleton-badge| image:: https://img.shields.io/badge/skeleton-2025-informational
|
||||
:target: https://blog.jaraco.com/skeleton
|
||||
|
||||
.. |codecov-badge| image:: https://img.shields.io/codecov/c/github/pypa/setuptools/master.svg?logo=codecov&logoColor=white
|
||||
:target: https://codecov.io/gh/pypa/setuptools
|
||||
|
||||
.. |tidelift-badge| image:: https://tidelift.com/badges/github/pypa/setuptools?style=flat
|
||||
:target: https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=readme
|
||||
|
||||
.. |discord-badge| image:: https://img.shields.io/discord/803025117553754132
|
||||
:target: https://discord.com/channels/803025117553754132/815945031150993468
|
||||
:alt: Discord
|
||||
|
||||
|pypi-version| |py-version| |test-badge| |ruff-badge| |docs-badge| |skeleton-badge| |codecov-badge| |discord-badge|
|
||||
|
||||
See the `Quickstart <https://setuptools.pypa.io/en/latest/userguide/quickstart.html>`_
|
||||
and the `User's Guide <https://setuptools.pypa.io/en/latest/userguide/>`_ for
|
||||
instructions on how to use Setuptools.
|
||||
|
||||
Questions and comments should be directed to `GitHub Discussions
|
||||
<https://github.com/pypa/setuptools/discussions>`_.
|
||||
Bug reports and especially tested patches may be
|
||||
submitted directly to the `bug tracker
|
||||
<https://github.com/pypa/setuptools/issues>`_.
|
||||
|
||||
|
||||
Code of Conduct
|
||||
===============
|
||||
|
||||
Everyone interacting in the setuptools project's codebases, issue trackers,
|
||||
chat rooms, and fora is expected to follow the
|
||||
`PSF Code of Conduct <https://github.com/pypa/.github/blob/main/CODE_OF_CONDUCT.md>`_.
|
||||
|
||||
|
||||
For Enterprise
|
||||
==============
|
||||
|
||||
Available as part of the Tidelift Subscription.
|
||||
|
||||
Setuptools and the maintainers of thousands of other packages are working with Tidelift to deliver one enterprise subscription that covers all of the open source you use.
|
||||
|
||||
`Learn more <https://tidelift.com/subscription/pkg/pypi-setuptools?utm_source=pypi-setuptools&utm_medium=referral&utm_campaign=github>`_.
|
@@ -0,0 +1,869 @@
|
||||
_distutils_hack/__init__.py,sha256=34HmvLo07j45Uvd2VR-2aRQ7lJD91sTK6zJgn5fphbQ,6755
|
||||
_distutils_hack/__pycache__/__init__.cpython-312.pyc,,
|
||||
_distutils_hack/__pycache__/override.cpython-312.pyc,,
|
||||
_distutils_hack/override.py,sha256=Eu_s-NF6VIZ4Cqd0tbbA5wtWky2IZPNd8et6GLt1mzo,44
|
||||
distutils-precedence.pth,sha256=JjjOniUA5XKl4N5_rtZmHrVp0baW_LoHsN0iPaX10iQ,151
|
||||
pkg_resources/__init__.py,sha256=uxrWmKF3lxsG4q6ojHlu4tB8j8Kw9jqx_SNMyDKP5q4,126219
|
||||
pkg_resources/__pycache__/__init__.cpython-312.pyc,,
|
||||
pkg_resources/api_tests.txt,sha256=XEdvy4igHHrq2qNHNMHnlfO6XSQKNqOyLHbl6QcpfAI,12595
|
||||
pkg_resources/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pkg_resources/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pkg_resources/tests/__pycache__/__init__.cpython-312.pyc,,
|
||||
pkg_resources/tests/__pycache__/test_find_distributions.cpython-312.pyc,,
|
||||
pkg_resources/tests/__pycache__/test_integration_zope_interface.cpython-312.pyc,,
|
||||
pkg_resources/tests/__pycache__/test_markers.cpython-312.pyc,,
|
||||
pkg_resources/tests/__pycache__/test_pkg_resources.cpython-312.pyc,,
|
||||
pkg_resources/tests/__pycache__/test_resources.cpython-312.pyc,,
|
||||
pkg_resources/tests/__pycache__/test_working_set.cpython-312.pyc,,
|
||||
pkg_resources/tests/data/my-test-package-source/__pycache__/setup.cpython-312.pyc,,
|
||||
pkg_resources/tests/data/my-test-package-source/setup.cfg,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
pkg_resources/tests/data/my-test-package-source/setup.py,sha256=1VobhAZbMb7M9mfhb_NE8PwDsvukoWLs9aUAS0pYhe8,105
|
||||
pkg_resources/tests/data/my-test-package-zip/my-test-package.zip,sha256=AYRcQ39GVePPnMT8TknP1gdDHyJnXhthESmpAjnzSCI,1809
|
||||
pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/PKG-INFO,sha256=JvWv9Io2PAuYwEEw2fBW4Qc5YvdbkscpKX1kmLzsoHk,187
|
||||
pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/SOURCES.txt,sha256=4ClkH8eTovZrdVrJFsVuxdbMEF--lBVSuKonDAPE5Jc,208
|
||||
pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/dependency_links.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
||||
pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
||||
pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7.egg/EGG-INFO/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
||||
pkg_resources/tests/data/my-test-package_zipped-egg/my_test_package-1.0-py3.7.egg,sha256=ZTlMGxjRGiKDNkiA2c75jbQH2TWIteP00irF9gvczbo,843
|
||||
pkg_resources/tests/test_find_distributions.py,sha256=U91cov5L1COAIWLNq3Xy4plU7_MnOE1WtXMu6iV2waM,1972
|
||||
pkg_resources/tests/test_integration_zope_interface.py,sha256=nzVoK557KZQN0V3DIQ1sVeaCOgt4Kpl-CODAWsO7pmc,1652
|
||||
pkg_resources/tests/test_markers.py,sha256=0orKg7UMDf7fnuNQvRMOc-EF9EAP_JTQnk4mtGgbW50,241
|
||||
pkg_resources/tests/test_pkg_resources.py,sha256=5Mt4bJQhLCL8j8cC46Uv32Np2Xc1TTxLGawIfET55Fk,17111
|
||||
pkg_resources/tests/test_resources.py,sha256=K0LqMAUGpRQ9pUb9K0vyI7GesvtlQvTH074m-E2VQlo,31252
|
||||
pkg_resources/tests/test_working_set.py,sha256=lRtGJWIixSwSMSbjHgRxeJEQiLMRXcz3xzJL2qL7eXY,8602
|
||||
setuptools-80.9.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools-80.9.0.dist-info/METADATA,sha256=f4kMqNvBa2O1aMiTEu1qf58KedCyt_PIO_eWrD2TBhU,6572
|
||||
setuptools-80.9.0.dist-info/RECORD,,
|
||||
setuptools-80.9.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools-80.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
||||
setuptools-80.9.0.dist-info/entry_points.txt,sha256=zkgthpf_Fa9NVE9p6FKT3Xk9DR1faAcRU4coggsV7jA,2449
|
||||
setuptools-80.9.0.dist-info/licenses/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools-80.9.0.dist-info/top_level.txt,sha256=d9yL39v_W7qmKDDSH6sT4bE0j_Ls1M3P161OGgdsm4g,41
|
||||
setuptools/__init__.py,sha256=7duacBaImxzrUa0OghIz8lVgaJ1fIw7-uL2v16vY_SE,9004
|
||||
setuptools/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_core_metadata.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_discovery.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_entry_points.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_imp.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_importlib.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_itertools.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_normalization.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_path.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_reqs.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_scripts.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_shutil.cpython-312.pyc,,
|
||||
setuptools/__pycache__/_static.cpython-312.pyc,,
|
||||
setuptools/__pycache__/archive_util.cpython-312.pyc,,
|
||||
setuptools/__pycache__/build_meta.cpython-312.pyc,,
|
||||
setuptools/__pycache__/depends.cpython-312.pyc,,
|
||||
setuptools/__pycache__/discovery.cpython-312.pyc,,
|
||||
setuptools/__pycache__/dist.cpython-312.pyc,,
|
||||
setuptools/__pycache__/errors.cpython-312.pyc,,
|
||||
setuptools/__pycache__/extension.cpython-312.pyc,,
|
||||
setuptools/__pycache__/glob.cpython-312.pyc,,
|
||||
setuptools/__pycache__/installer.cpython-312.pyc,,
|
||||
setuptools/__pycache__/launch.cpython-312.pyc,,
|
||||
setuptools/__pycache__/logging.cpython-312.pyc,,
|
||||
setuptools/__pycache__/modified.cpython-312.pyc,,
|
||||
setuptools/__pycache__/monkey.cpython-312.pyc,,
|
||||
setuptools/__pycache__/msvc.cpython-312.pyc,,
|
||||
setuptools/__pycache__/namespaces.cpython-312.pyc,,
|
||||
setuptools/__pycache__/unicode_utils.cpython-312.pyc,,
|
||||
setuptools/__pycache__/version.cpython-312.pyc,,
|
||||
setuptools/__pycache__/warnings.cpython-312.pyc,,
|
||||
setuptools/__pycache__/wheel.cpython-312.pyc,,
|
||||
setuptools/__pycache__/windows_support.cpython-312.pyc,,
|
||||
setuptools/_core_metadata.py,sha256=T7Tjp-WSoN881adev3R1wzXCPnkDHqbC2MgylN1yjS8,11978
|
||||
setuptools/_discovery.py,sha256=HxEpgYQ8zUaLOOSp8JIA4y2Mdvn9ysVxspPT-ppfzM4,836
|
||||
setuptools/_distutils/__init__.py,sha256=xGYuhWwLG07J0Q49BVnEjPy6wyDcd6veJMDJX7ljlyM,359
|
||||
setuptools/_distutils/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/_log.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/_macos_compat.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/_modified.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/_msvccompiler.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/archive_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/ccompiler.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/cmd.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/core.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/cygwinccompiler.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/debug.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/dep_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/dir_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/dist.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/errors.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/extension.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/fancy_getopt.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/file_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/filelist.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/log.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/spawn.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/sysconfig.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/text_file.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/unixccompiler.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/util.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/version.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/versionpredicate.cpython-312.pyc,,
|
||||
setuptools/_distutils/__pycache__/zosccompiler.cpython-312.pyc,,
|
||||
setuptools/_distutils/_log.py,sha256=i-lNTTcXS8TmWITJ6DODGvtW5z5tMattJQ76h8rZxQU,42
|
||||
setuptools/_distutils/_macos_compat.py,sha256=JzUGhF4E5yIITHbUaPobZEWjGHdrrcNV63z86S4RjBc,239
|
||||
setuptools/_distutils/_modified.py,sha256=RF1n1CexyDYV3lvGbeXS0s-XCJVboDOIUbA8wEQqYTY,3211
|
||||
setuptools/_distutils/_msvccompiler.py,sha256=9PSfSHxvJnHnQL6Sqz4Xcz7iaBIT62p6BheQzGsSlwo,335
|
||||
setuptools/_distutils/archive_util.py,sha256=Qw2z-Pt-NV8lNUQrzjs3XDGWCWHMPnqHLyt8TiD2XEA,8884
|
||||
setuptools/_distutils/ccompiler.py,sha256=FKVjqzGJ7c-FtouNjhLiaMPm5LKMZHHAruXf8LU216c,524
|
||||
setuptools/_distutils/cmd.py,sha256=hXtaRaH7QBnfNOIqEvCt47iwZzD9MVvBdhhdQctHsxM,22186
|
||||
setuptools/_distutils/command/__init__.py,sha256=GfFAzbBqk1qxSH4BdaKioKS4hRRnD44BAmwEN85C4u8,386
|
||||
setuptools/_distutils/command/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/_framework_compat.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/bdist.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/bdist_dumb.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/bdist_rpm.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/build.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/build_clib.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/build_ext.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/build_py.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/build_scripts.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/check.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/clean.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/config.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/install.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/install_data.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/install_egg_info.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/install_headers.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/install_lib.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/install_scripts.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/__pycache__/sdist.cpython-312.pyc,,
|
||||
setuptools/_distutils/command/_framework_compat.py,sha256=0iZdSJYzGRWCCvzRDKE-R0-_yaAYvFMd1ylXb2eYXug,1609
|
||||
setuptools/_distutils/command/bdist.py,sha256=jWtk61R7fWNUUNxJV0thTZzU5n80L3Ay1waSiP9kiLA,5854
|
||||
setuptools/_distutils/command/bdist_dumb.py,sha256=Hx1jAqoZNxYIy4N5TLzUp6J5fi8Ls18py7UlLNFhO2E,4631
|
||||
setuptools/_distutils/command/bdist_rpm.py,sha256=nxcXXv5a7B-1ntWu4DbGmCtES4EBINrJaBQcRNAYCJI,21785
|
||||
setuptools/_distutils/command/build.py,sha256=SpHlagf0iNaKVyIhxDfhPFZ8X1-LAWOCQACy-yt2K0w,5923
|
||||
setuptools/_distutils/command/build_clib.py,sha256=aMqZcUfCbOAu_xr-A9iW-Q9YZHzpDGLRTezOgMQJmSQ,7777
|
||||
setuptools/_distutils/command/build_ext.py,sha256=zrrsu9HXnzV6bXYbJuZCK4SwVZMjKnl4pG1o3bNcxtc,32710
|
||||
setuptools/_distutils/command/build_py.py,sha256=Vfq-INemoMbg6f003BTy_Ufp8bjOZhmFIhpKMcfXLgs,16696
|
||||
setuptools/_distutils/command/build_scripts.py,sha256=emMEOONkNLPC-AMjKy45UksUlY1wk06esOGThpwidIM,5135
|
||||
setuptools/_distutils/command/check.py,sha256=yoNe2MPY4JcTM7rwoIQdfZ75q5Ri058I2coi-Gq9CjM,4946
|
||||
setuptools/_distutils/command/clean.py,sha256=dQAacOabwBXU9JoZ-1GFusq3eFltDaeXJFSYncqGbvE,2644
|
||||
setuptools/_distutils/command/config.py,sha256=qrrfz6NEQORmbqiY2XlvCDWYhsbLyxZXJsURKfYN_kw,12724
|
||||
setuptools/_distutils/command/install.py,sha256=-JenB-mua4hc2RI_-W8F9PnP_J-OaFO7E0PJGKxLo1o,30072
|
||||
setuptools/_distutils/command/install_data.py,sha256=GzBlUWWKubTYJlP-L0auUriq9cL-5RKOcoyHTttKj0Q,2875
|
||||
setuptools/_distutils/command/install_egg_info.py,sha256=ffiLoU1ivQJ8q2_WL7ZygZbUcOsgdFLKL7otEIJWWkI,2868
|
||||
setuptools/_distutils/command/install_headers.py,sha256=5ciKCj8c3XKsYNKdkdMvnypaUCKcoWCDeeZij3fD-Z4,1272
|
||||
setuptools/_distutils/command/install_lib.py,sha256=2s9-m5-b1qKm51F28lB5L39Z6vv_GHMlv9dNBSupok0,8588
|
||||
setuptools/_distutils/command/install_scripts.py,sha256=M0pPdiaqB7TGmqTMujpGGeiL0Iq_CTeGjMFtrmDmwzM,2002
|
||||
setuptools/_distutils/command/sdist.py,sha256=cRIF6Ht1hJ6ayOOFVycMFBUNxjo94e_rFYPx4Hi8Ahc,19151
|
||||
setuptools/_distutils/compat/__init__.py,sha256=J20aXGjJ86Rg41xFLIWlcWCgZ9edMdJ9vvdNEQ87vPQ,522
|
||||
setuptools/_distutils/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_distutils/compat/__pycache__/numpy.cpython-312.pyc,,
|
||||
setuptools/_distutils/compat/__pycache__/py39.cpython-312.pyc,,
|
||||
setuptools/_distutils/compat/numpy.py,sha256=UFgneZw9w97g4c-yGoAIOyLxUOWQ-fPRIhhfMs7_Ouc,167
|
||||
setuptools/_distutils/compat/py39.py,sha256=hOsD6lwZLqZoMnacNJ3P6nUA-LJQhEpVtYTzVH0o96M,1964
|
||||
setuptools/_distutils/compilers/C/__pycache__/base.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/__pycache__/cygwin.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/__pycache__/errors.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/__pycache__/msvc.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/__pycache__/unix.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/__pycache__/zos.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/base.py,sha256=XR1rBCStCquqm7QOYXD41-LfvsFcPpGxrwxeXzJyn_w,54876
|
||||
setuptools/_distutils/compilers/C/cygwin.py,sha256=DUlwQSb55aj7OdcmcddrmCmVEjEaxIiJ5hHUO3GBPNs,11844
|
||||
setuptools/_distutils/compilers/C/errors.py,sha256=sKOVzJajMUmNdfywo9UM_QQGsKFcclDhtI5TlCiXMLc,573
|
||||
setuptools/_distutils/compilers/C/msvc.py,sha256=elzG8v9jN5QytLMwLCdUdSuZ3eZ3R98VUvnm9Y2PBCA,21404
|
||||
setuptools/_distutils/compilers/C/tests/__pycache__/test_base.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/tests/__pycache__/test_cygwin.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/tests/__pycache__/test_mingw.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/tests/__pycache__/test_msvc.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/tests/__pycache__/test_unix.cpython-312.pyc,,
|
||||
setuptools/_distutils/compilers/C/tests/test_base.py,sha256=rdhHc56bhXtm5NnN9BSHwr6c69UqzMItZQzlw2AsdMc,2706
|
||||
setuptools/_distutils/compilers/C/tests/test_cygwin.py,sha256=UgV2VgUXj3VulcbDc0UBWfEyJDx42tgSwS4LzHix3mY,2701
|
||||
setuptools/_distutils/compilers/C/tests/test_mingw.py,sha256=hCmwyywISpRoyOySbFHBL4TprWRV0mUWDKmOLO8XBXE,1900
|
||||
setuptools/_distutils/compilers/C/tests/test_msvc.py,sha256=DlGjmZ1mBSMXIgmlu80BKc7V-EJOZuYucwJwFh5dn28,4151
|
||||
setuptools/_distutils/compilers/C/tests/test_unix.py,sha256=AyadWw1fR-UeDl2TvIbYBzOJVHkpE_oRRQ3JTJWqaEA,14642
|
||||
setuptools/_distutils/compilers/C/unix.py,sha256=YH-y9g_pjBFjaJyHJQkDEBQ7q4D20I2-cWJNdgw-Yho,16531
|
||||
setuptools/_distutils/compilers/C/zos.py,sha256=vnNeWLRZkdIkdZ-YyBnL8idTUfcCOn0tLMW5OBJ0ScU,6586
|
||||
setuptools/_distutils/core.py,sha256=GEHKaFC48T3o-_SmH4864GvKyx1IgbVC6ISIPVlx7a4,9364
|
||||
setuptools/_distutils/cygwinccompiler.py,sha256=mG_cU8SVZ4amD_VtF5vH6BXP0-kghGsDPbDSXrQ963c,594
|
||||
setuptools/_distutils/debug.py,sha256=N6MrTAqK6l9SVk6tWweR108PM8Ol7qNlfyV-nHcLhsY,139
|
||||
setuptools/_distutils/dep_util.py,sha256=xN75p6ZpHhMiHEc-rpL2XilJQynHnDNiafHteaZ4tjU,349
|
||||
setuptools/_distutils/dir_util.py,sha256=DXPUlfVVGsg9B-Jgg4At_j9T7vM60OgwNXkQHqTo7-I,7236
|
||||
setuptools/_distutils/dist.py,sha256=gW598UE0WMkzXQQ31Nr-8L7MPw0oIOz5OSSRzYZlwrM,55794
|
||||
setuptools/_distutils/errors.py,sha256=PPE2oDRh5y9Q1beKK9rhdvDaCzQhi4HCXs4KcqfqgZY,3092
|
||||
setuptools/_distutils/extension.py,sha256=Foyu4gULcPqm1_U9zrYYHxNk4NqglXv1rbsOk_QrSds,11155
|
||||
setuptools/_distutils/fancy_getopt.py,sha256=PjdO-bWCW0imV_UN-MGEw9R2GP2OiE8pHjITgmTAY3Q,17895
|
||||
setuptools/_distutils/file_util.py,sha256=YFQL_pD3hLuER9II_H6-hDC_YIGEookdd4wedLuiTW0,7978
|
||||
setuptools/_distutils/filelist.py,sha256=MBeSRJmPcKmDv8ooZgSU4BiQPZ0Khwv8l_jhD50XycI,15337
|
||||
setuptools/_distutils/log.py,sha256=VyBs5j7z4-K6XTEEBThUc9HyMpoPLGtQpERqbz5ylww,1200
|
||||
setuptools/_distutils/spawn.py,sha256=zseCh9sEifyp0I5Vg719JNIASlROJ2ehXqQnHlpt89Q,4086
|
||||
setuptools/_distutils/sysconfig.py,sha256=KeI8OHbMuEzHJ8Q0cBez9KZny8iRy6Z6Y0AkMz1jlsU,19728
|
||||
setuptools/_distutils/tests/__init__.py,sha256=j-IoPZEtQv3EOPuqNTwalr6GLyRjzCC-OOaNvZzmHsI,1485
|
||||
setuptools/_distutils/tests/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/support.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_archive_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_bdist.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_bdist_dumb.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_bdist_rpm.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_build.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_build_clib.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_build_ext.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_build_py.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_build_scripts.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_check.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_clean.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_cmd.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_config_cmd.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_core.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_dir_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_dist.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_extension.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_file_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_filelist.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_install.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_install_data.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_install_headers.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_install_lib.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_install_scripts.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_log.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_modified.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_sdist.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_spawn.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_sysconfig.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_text_file.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_util.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_version.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/test_versionpredicate.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/__pycache__/unix_compat.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_distutils/tests/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/compat/__pycache__/py39.cpython-312.pyc,,
|
||||
setuptools/_distutils/tests/compat/py39.py,sha256=t0GBTM-30jX-9zCfkwlNBFtzzabemx6065mJ0d9_VRw,1026
|
||||
setuptools/_distutils/tests/support.py,sha256=tjsYsyxvpTK4NrkCseh2ujvDIGV0Mf_b5SI5fP2T0yM,4099
|
||||
setuptools/_distutils/tests/test_archive_util.py,sha256=jozimSwPBF-JoJfN_vDaiVGZp66BNcWZGh34FlW57DQ,11787
|
||||
setuptools/_distutils/tests/test_bdist.py,sha256=xNHxUsLlHsZQRwkzLb_iSD24s-9Mk-NX2ffBWwOyPyc,1396
|
||||
setuptools/_distutils/tests/test_bdist_dumb.py,sha256=QF05MHNhPOdZyh88Xpw8KsO64s7pRFkl8KL-RoV4XK0,2247
|
||||
setuptools/_distutils/tests/test_bdist_rpm.py,sha256=Hdm-pwWgyaoGdGbEcGZa8cRhGU45y8gHK8umOanTjik,3932
|
||||
setuptools/_distutils/tests/test_build.py,sha256=JJY5XpOZco25ZY0pstxl-iI8mHsWP0ujf5o8aOtuZYY,1742
|
||||
setuptools/_distutils/tests/test_build_clib.py,sha256=Mo1ZFb4C1VXBYOGvnallwN7YCnTtr24akLDO8Zi4CsY,4331
|
||||
setuptools/_distutils/tests/test_build_ext.py,sha256=QFO9qYVhWWdJu17HXc4x9RMnLZlhk0lAHi9HVppbuX4,22545
|
||||
setuptools/_distutils/tests/test_build_py.py,sha256=NsfmRrojOHBXNMqWR_mp5g4PLTgjhD7iZFUffGZFIdw,6882
|
||||
setuptools/_distutils/tests/test_build_scripts.py,sha256=cD-FRy-oX55sXRX5Ez5xQCaeHrWajyKc4Xuwv2fe48w,2880
|
||||
setuptools/_distutils/tests/test_check.py,sha256=hHSV07qf7YoSxGsTbbsUQ9tssZz5RRNdbrY1s2SwaFI,6226
|
||||
setuptools/_distutils/tests/test_clean.py,sha256=hPH6jfIpGFUrvWbF1txkiNVSNaAxt2wq5XjV499zO4E,1240
|
||||
setuptools/_distutils/tests/test_cmd.py,sha256=bgRB79mitoOKR1OiyZHnCogvGxt3pWkxeTqIC04lQWQ,3254
|
||||
setuptools/_distutils/tests/test_config_cmd.py,sha256=Zs6WX0IfxDvmuC19XzuVNnYCnTr9Y-hl73TAmDSBN4Y,2664
|
||||
setuptools/_distutils/tests/test_core.py,sha256=L7XKVAxa-MGoAZeANopnuK9fRKneYhkSQpgw8XQvcF8,3829
|
||||
setuptools/_distutils/tests/test_dir_util.py,sha256=E84lC-k4riVUwURyWaQ0Jqx2ui2-io-0RuJa3M7qkJs,4500
|
||||
setuptools/_distutils/tests/test_dist.py,sha256=a6wlc5fQJd5qQ6HOndzcupNhjTxvj6-_JLtpuYvaP1M,18793
|
||||
setuptools/_distutils/tests/test_extension.py,sha256=-YejLgZCuycFrOBd64pVH0JvwMc9NwhzHvQxvvjXHqk,3670
|
||||
setuptools/_distutils/tests/test_file_util.py,sha256=livjnl3FkilQlrB2rFdFQq9nvjEVZHynNya0bfzv_b4,3522
|
||||
setuptools/_distutils/tests/test_filelist.py,sha256=rJwkqCUfkGDgWlD22TozsT8ycbupMHB8DXqThzwT1T4,10766
|
||||
setuptools/_distutils/tests/test_install.py,sha256=TfCB0ykhIxydIC2Q4SuTAZzSHvteMHgrBL9whoSgK9Q,8618
|
||||
setuptools/_distutils/tests/test_install_data.py,sha256=vKq3K97k0hBAnOg38nmwEdf7cEDVr9rTVyCeJolgb4A,2464
|
||||
setuptools/_distutils/tests/test_install_headers.py,sha256=PVAYpo_tYl980Qf64DPOmmSvyefIHdU06f7VsJeZykE,936
|
||||
setuptools/_distutils/tests/test_install_lib.py,sha256=qri6Rl-maNTQrNDV8DbeXNl0hjsfRIKiI4rfZLrmWBI,3612
|
||||
setuptools/_distutils/tests/test_install_scripts.py,sha256=KE3v0cDkFW-90IOID-OmZZGM2mhy-ZkEuuW7UXS2SHw,1600
|
||||
setuptools/_distutils/tests/test_log.py,sha256=isFtOufloCyEdZaQOV7cVUr46GwtdVMj43mGBB5XH7k,323
|
||||
setuptools/_distutils/tests/test_modified.py,sha256=h1--bOWmtJo1bpVV6uRhdnS9br71CBiNDM1MDwSGpug,4221
|
||||
setuptools/_distutils/tests/test_sdist.py,sha256=cfzUhlCA418-1vH9ta3IBs26c_jUBbkJoFOK5GnAyNk,15062
|
||||
setuptools/_distutils/tests/test_spawn.py,sha256=eS8w9D7bTxyFLSyRahJWeuh8Kc1F8RWWiY_dSG5B5Bc,4803
|
||||
setuptools/_distutils/tests/test_sysconfig.py,sha256=lxM8LsUi1TomjDV4HoYK8u5nUoBkeNL60Uq8PY1DcwU,11986
|
||||
setuptools/_distutils/tests/test_text_file.py,sha256=WQWSB5AfdBDZaMA8BFgipJPnsJb_2SKMfL90fSkRVtw,3460
|
||||
setuptools/_distutils/tests/test_util.py,sha256=H9zlZ4z4Vh4TfjNYDBsxP7wguQLpxCfJYyOcm1yZU3c,7988
|
||||
setuptools/_distutils/tests/test_version.py,sha256=ahfg_mP8wRy1sgwY-_Px5hrjgf6_upTIpnCgpR4yWRk,2750
|
||||
setuptools/_distutils/tests/test_versionpredicate.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_distutils/tests/unix_compat.py,sha256=z-op6C2iVdX1aq5BIBR7cqOxijKE97alNwJqHNdLpoI,386
|
||||
setuptools/_distutils/text_file.py,sha256=z4dkOJBr9Bo2LG0TNqm8sD63LEEaKSSP0J0bWBrFG3c,12101
|
||||
setuptools/_distutils/unixccompiler.py,sha256=1bXJWH4fiu_A2WfriHzf88xjllQTXnnjUkZdRKs9cWU,212
|
||||
setuptools/_distutils/util.py,sha256=Njfnqk60zMdkiAjRnGcTWX3t49-obHapOlbNvyIl02I,18094
|
||||
setuptools/_distutils/version.py,sha256=vImT5-ECXkQ21oKL0XYFiTqK6NyM09cpzBNoA_34CQU,12619
|
||||
setuptools/_distutils/versionpredicate.py,sha256=qBWQ6wTj12ODytoTmIydefIY2jb4uY1sdbgbuLn-IJM,5205
|
||||
setuptools/_distutils/zosccompiler.py,sha256=svdiXZ2kdcwKrJKfhUhib03y8gz7aGZKukXH3I7YkBc,58
|
||||
setuptools/_entry_points.py,sha256=10TjbzfGdqWGH06lQuPPGDDci-OnXoIzrfpIWba5AZw,2468
|
||||
setuptools/_imp.py,sha256=YY1EjZEN-0zYci1cxO10B_adAEOr7i8eK8JoCc9Ierc,2435
|
||||
setuptools/_importlib.py,sha256=aKIjcK0HKXNz2D-XTrxaixGn_juTkONwmu3dcheMOF0,223
|
||||
setuptools/_itertools.py,sha256=jWRfsIrpC7myooz3hDURj9GtvpswZeKXg2HakmEhNjo,657
|
||||
setuptools/_normalization.py,sha256=-SxdhisW3W1JKzqKYxd3XeHyRjIj3J9EVRkt3aL8nKY,5747
|
||||
setuptools/_path.py,sha256=2Bv1q9_Hrd4oizKwcH3pv_05YVR6meovQE6ZtyD45yI,2976
|
||||
setuptools/_reqs.py,sha256=RRX-qYsz_fy6K66XchCHcIszK3bSAtU6aO1s3ZaLV14,1380
|
||||
setuptools/_scripts.py,sha256=5TrIWDVOuO3cRcfzcZAUBKPRH7K4svQRdQLZKKiD1bQ,11247
|
||||
setuptools/_shutil.py,sha256=IQQ1gcPX4X_wPilYGJGxChyMCqG43VOejoQZTIrCTY8,1578
|
||||
setuptools/_static.py,sha256=GTR79gESF1_JaK4trLkpDrEuCeEtPlwQW0MRv7VNQX4,4855
|
||||
setuptools/_vendor/__pycache__/typing_extensions.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand-2.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/autocommand-2.2.2.dist-info/LICENSE,sha256=reeNBJgtaZctREqOFKlPh6IzTdOFXMgDSOqOJAqg3y0,7634
|
||||
setuptools/_vendor/autocommand-2.2.2.dist-info/METADATA,sha256=OADZuR3O6iBlpu1ieTgzYul6w4uOVrk0P0BO5TGGAJk,15006
|
||||
setuptools/_vendor/autocommand-2.2.2.dist-info/RECORD,sha256=giu6ZrQVJvpUcYa4AiH4XaUNZSvuVJPb_l0UCFES8MM,1308
|
||||
setuptools/_vendor/autocommand-2.2.2.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
||||
setuptools/_vendor/autocommand-2.2.2.dist-info/top_level.txt,sha256=AzfhgKKS8EdAwWUTSF8mgeVQbXOY9kokHB6kSqwwqu0,12
|
||||
setuptools/_vendor/autocommand/__init__.py,sha256=zko5Rnvolvb-UXjCx_2ArPTGBWwUK5QY4LIQIKYR7As,1037
|
||||
setuptools/_vendor/autocommand/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand/__pycache__/autoasync.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand/__pycache__/autocommand.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand/__pycache__/automain.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand/__pycache__/autoparse.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand/__pycache__/errors.cpython-312.pyc,,
|
||||
setuptools/_vendor/autocommand/autoasync.py,sha256=AMdyrxNS4pqWJfP_xuoOcImOHWD-qT7x06wmKN1Vp-U,5680
|
||||
setuptools/_vendor/autocommand/autocommand.py,sha256=hmkEmQ72HtL55gnURVjDOnsfYlGd5lLXbvT4KG496Qw,2505
|
||||
setuptools/_vendor/autocommand/automain.py,sha256=A2b8i754Mxc_DjU9WFr6vqYDWlhz0cn8miu8d8EsxV8,2076
|
||||
setuptools/_vendor/autocommand/autoparse.py,sha256=WVWmZJPcbzUKXP40raQw_0HD8qPJ2V9VG1eFFmmnFxw,11642
|
||||
setuptools/_vendor/autocommand/errors.py,sha256=7aa3roh9Herd6nIKpQHNWEslWE8oq7GiHYVUuRqORnA,886
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/METADATA,sha256=ghXFTq132dxaEIolxr3HK1mZqm9iyUmaRANZQSr6WlE,2020
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/RECORD,sha256=JYofHISeEXUGmlWl1s41ev3QTjTNXeJwk-Ss7HqdLOE,1360
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
setuptools/_vendor/backports.tarfile-1.2.0.dist-info/top_level.txt,sha256=cGjaLMOoBR1FK0ApojtzWVmViTtJ7JGIK_HwXiEsvtU,10
|
||||
setuptools/_vendor/backports/__init__.py,sha256=iOEMwnlORWezdO8-2vxBIPSR37D7JGjluZ8f55vzxls,81
|
||||
setuptools/_vendor/backports/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/backports/tarfile/__init__.py,sha256=Pwf2qUIfB0SolJPCKcx3vz3UEu_aids4g4sAfxy94qg,108491
|
||||
setuptools/_vendor/backports/tarfile/__main__.py,sha256=Yw2oGT1afrz2eBskzdPYL8ReB_3liApmhFkN2EbDmc4,59
|
||||
setuptools/_vendor/backports/tarfile/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/backports/tarfile/__pycache__/__main__.cpython-312.pyc,,
|
||||
setuptools/_vendor/backports/tarfile/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/backports/tarfile/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/backports/tarfile/compat/__pycache__/py38.cpython-312.pyc,,
|
||||
setuptools/_vendor/backports/tarfile/compat/py38.py,sha256=iYkyt_gvWjLzGUTJD9TuTfMMjOk-ersXZmRlvQYN2qE,568
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/METADATA,sha256=anuQ7_7h4J1bSEzfcjIBakPi2cyVQ7y7jklLHsBeH1k,4648
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/RECORD,sha256=DY08buueu-hsrH1ghhVSQzwynanqUSSLYdAr4uXmQDA,2518
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/WHEEL,sha256=mguMlWGMX-VHnMpKOjjQidIo1ssRlCFu4a4mBpz1s2M,91
|
||||
setuptools/_vendor/importlib_metadata-8.0.0.dist-info/top_level.txt,sha256=CO3fD9yylANiXkrMo4qHLV_mqXL2sC5JFKgt1yWAT-A,19
|
||||
setuptools/_vendor/importlib_metadata/__init__.py,sha256=tZNB-23h8Bixi9uCrQqj9Yf0aeC--Josdy3IZRIQeB0,33798
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_adapters.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_collections.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_compat.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_functools.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_itertools.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_meta.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/_text.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/__pycache__/diagnose.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/_adapters.py,sha256=rIhWTwBvYA1bV7i-5FfVX38qEXDTXFeS5cb5xJtP3ks,2317
|
||||
setuptools/_vendor/importlib_metadata/_collections.py,sha256=CJ0OTCHIjWA0ZIVS4voORAsn2R4R2cQBEtPsZEJpASY,743
|
||||
setuptools/_vendor/importlib_metadata/_compat.py,sha256=73QKrN9KNoaZzhbX5yPCCZa-FaALwXe8TPlDR72JgBU,1314
|
||||
setuptools/_vendor/importlib_metadata/_functools.py,sha256=PsY2-4rrKX4RVeRC1oGp1lB1pmC9eKN88_f-bD9uOoA,2895
|
||||
setuptools/_vendor/importlib_metadata/_itertools.py,sha256=cvr_2v8BRbxcIl5x5ldfqdHjhI8Yi8s8yk50G_nm6jQ,2068
|
||||
setuptools/_vendor/importlib_metadata/_meta.py,sha256=nxZ7C8GVlcBFAKWyVOn_dn7ot_twBcbm1NmvjIetBHI,1801
|
||||
setuptools/_vendor/importlib_metadata/_text.py,sha256=HCsFksZpJLeTP3NEk_ngrAeXVRRtTrtyh9eOABoRP4A,2166
|
||||
setuptools/_vendor/importlib_metadata/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/importlib_metadata/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/compat/__pycache__/py311.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/compat/__pycache__/py39.cpython-312.pyc,,
|
||||
setuptools/_vendor/importlib_metadata/compat/py311.py,sha256=uqm-K-uohyj1042TH4a9Er_I5o7667DvulcD-gC_fSA,608
|
||||
setuptools/_vendor/importlib_metadata/compat/py39.py,sha256=cPkMv6-0ilK-0Jw_Tkn0xYbOKJZc4WJKQHow0c2T44w,1102
|
||||
setuptools/_vendor/importlib_metadata/diagnose.py,sha256=nkSRMiowlmkhLYhKhvCg9glmt_11Cox-EmLzEbqYTa8,379
|
||||
setuptools/_vendor/importlib_metadata/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/inflect-7.3.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/inflect-7.3.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/inflect-7.3.1.dist-info/METADATA,sha256=ZgMNY0WAZRs-U8wZiV2SMfjSKqBrMngXyDMs_CAwMwg,21079
|
||||
setuptools/_vendor/inflect-7.3.1.dist-info/RECORD,sha256=XXg0rBuiYSxoAQUP3lenuYsPNqz4jDwtTzdv2JEbMJE,943
|
||||
setuptools/_vendor/inflect-7.3.1.dist-info/WHEEL,sha256=y4mX-SOX4fYIkonsAGA5N0Oy-8_gI4FXw5HNI1xqvWg,91
|
||||
setuptools/_vendor/inflect-7.3.1.dist-info/top_level.txt,sha256=m52ujdp10CqT6jh1XQxZT6kEntcnv-7Tl7UiGNTzWZA,8
|
||||
setuptools/_vendor/inflect/__init__.py,sha256=Jxy1HJXZiZ85kHeLAhkmvz6EMTdFqBe-duvt34R6IOc,103796
|
||||
setuptools/_vendor/inflect/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/inflect/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/inflect/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/inflect/compat/__pycache__/py38.cpython-312.pyc,,
|
||||
setuptools/_vendor/inflect/compat/py38.py,sha256=oObVfVnWX9_OpnOuEJn1mFbJxVhwyR5epbiTNXDDaso,160
|
||||
setuptools/_vendor/inflect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/METADATA,sha256=IMUaliNsA5X1Ox9MXUWOagch5R4Wwb_3M7erp29dBtg,3933
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/RECORD,sha256=HptivXDkpfom6VlMu4CGD_7KPev-6Hc9rvp3TNJZygY,873
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91
|
||||
setuptools/_vendor/jaraco.collections-5.1.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7
|
||||
setuptools/_vendor/jaraco.context-5.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/jaraco.context-5.3.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/jaraco.context-5.3.0.dist-info/METADATA,sha256=xDtguJej0tN9iEXCUvxEJh2a7xceIRVBEakBLSr__tY,4020
|
||||
setuptools/_vendor/jaraco.context-5.3.0.dist-info/RECORD,sha256=VRl7iKeEQyl7stgnp1uq50CzOJYlHYcoNdS0x17C9X4,641
|
||||
setuptools/_vendor/jaraco.context-5.3.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
setuptools/_vendor/jaraco.context-5.3.0.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7
|
||||
setuptools/_vendor/jaraco.functools-4.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/jaraco.functools-4.0.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/jaraco.functools-4.0.1.dist-info/METADATA,sha256=i4aUaQDX-jjdEQK5wevhegyx8JyLfin2HyvaSk3FHso,2891
|
||||
setuptools/_vendor/jaraco.functools-4.0.1.dist-info/RECORD,sha256=YyqnwE98S8wBwCevW5vHb-iVj0oYEDW5V6O9MBS6JIs,843
|
||||
setuptools/_vendor/jaraco.functools-4.0.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
setuptools/_vendor/jaraco.functools-4.0.1.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/METADATA,sha256=AzWdm6ViMfDOPoQMfLWn2zgBQSGJScyqeN29TcuWXVI,3658
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/RECORD,sha256=gW2UV0HcokYJk4jKPu10_AZnrLqjb3C1WbJJTDl5sfY,1500
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
setuptools/_vendor/jaraco.text-3.12.1.dist-info/top_level.txt,sha256=0JnN3LfXH4LIRfXL-QFOGCJzQWZO3ELx4R1d_louoQM,7
|
||||
setuptools/_vendor/jaraco/__pycache__/context.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/collections/__init__.py,sha256=Pc1-SqjWm81ad1P0-GttpkwO_LWlnaY6gUq8gcKh2v0,26640
|
||||
setuptools/_vendor/jaraco/collections/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/collections/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/jaraco/context.py,sha256=REoLIxDkO5MfEYowt_WoupNCRoxBS5v7YX2PbW8lIcs,9552
|
||||
setuptools/_vendor/jaraco/functools/__init__.py,sha256=hEAJaS2uSZRuF_JY4CxCHIYh79ZpxaPp9OiHyr9EJ1w,16642
|
||||
setuptools/_vendor/jaraco/functools/__init__.pyi,sha256=gk3dsgHzo5F_U74HzAvpNivFAPCkPJ1b2-yCd62dfnw,3878
|
||||
setuptools/_vendor/jaraco/functools/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/functools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/jaraco/text/Lorem ipsum.txt,sha256=N_7c_79zxOufBY9HZ3yzMgOkNv-TkOTTio4BydrSjgs,1335
|
||||
setuptools/_vendor/jaraco/text/__init__.py,sha256=Y2YUqXR_orUoDaY4SkPRe6ZZhb5HUHB_Ah9RCNsVyho,16250
|
||||
setuptools/_vendor/jaraco/text/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/text/__pycache__/layouts.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/text/__pycache__/show-newlines.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/text/__pycache__/strip-prefix.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/text/__pycache__/to-dvorak.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/text/__pycache__/to-qwerty.cpython-312.pyc,,
|
||||
setuptools/_vendor/jaraco/text/layouts.py,sha256=HTC8aSTLZ7uXipyOXapRMC158juecjK6RVwitfmZ9_w,643
|
||||
setuptools/_vendor/jaraco/text/show-newlines.py,sha256=WGQa65e8lyhb92LUOLqVn6KaCtoeVgVws6WtSRmLk6w,904
|
||||
setuptools/_vendor/jaraco/text/strip-prefix.py,sha256=NfVXV8JVNo6nqcuYASfMV7_y4Eo8zMQqlCOGvAnRIVw,412
|
||||
setuptools/_vendor/jaraco/text/to-dvorak.py,sha256=1SNcbSsvISpXXg-LnybIHHY-RUFOQr36zcHkY1pWFqw,119
|
||||
setuptools/_vendor/jaraco/text/to-qwerty.py,sha256=s4UMQUnPwFn_dB5uZC27BurHOQcYondBfzIpVL5pEzw,119
|
||||
setuptools/_vendor/more_itertools-10.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/more_itertools-10.3.0.dist-info/LICENSE,sha256=CfHIyelBrz5YTVlkHqm4fYPAyw_QB-te85Gn4mQ8GkY,1053
|
||||
setuptools/_vendor/more_itertools-10.3.0.dist-info/METADATA,sha256=BFO90O-fLNiVQMpj7oIS5ztzgJUUQZ3TA32P5HH3N-A,36293
|
||||
setuptools/_vendor/more_itertools-10.3.0.dist-info/RECORD,sha256=d8jnPgGNwP1-ntbICwWkQEVF9kH7CFIgzkKzaLWao9M,1259
|
||||
setuptools/_vendor/more_itertools-10.3.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/more_itertools-10.3.0.dist-info/WHEEL,sha256=rSgq_JpHF9fHR1lx53qwg_1-2LypZE_qmcuXbVUq948,81
|
||||
setuptools/_vendor/more_itertools/__init__.py,sha256=dtAbGjTDmn_ghiU5YXfhyDy0phAlXVdt5klZA5fUa-Q,149
|
||||
setuptools/_vendor/more_itertools/__init__.pyi,sha256=5B3eTzON1BBuOLob1vCflyEb2lSd6usXQQ-Cv-hXkeA,43
|
||||
setuptools/_vendor/more_itertools/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/more_itertools/__pycache__/more.cpython-312.pyc,,
|
||||
setuptools/_vendor/more_itertools/__pycache__/recipes.cpython-312.pyc,,
|
||||
setuptools/_vendor/more_itertools/more.py,sha256=1E5kzFncRKTDw0cYv1yRXMgDdunstLQd1QStcnL6U90,148370
|
||||
setuptools/_vendor/more_itertools/more.pyi,sha256=iXXeqt48Nxe8VGmIWpkVXuKpR2FYNuu2DU8nQLWCCu0,21484
|
||||
setuptools/_vendor/more_itertools/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/more_itertools/recipes.py,sha256=WedhhfhGVgr6zii8fIbGJVmRTw0ZKRiLKnYBDGJv4nY,28591
|
||||
setuptools/_vendor/more_itertools/recipes.pyi,sha256=T_mdGpcFdfrP3JSWbwzYP9JyNV-Go-7RPfpxfftAWlA,4617
|
||||
setuptools/_vendor/packaging-24.2.dist-info/INSTALLER,sha256=5hhM4Q4mYTT9z6QB6PGpUAW81PGNFrYrdXMj4oM_6ak,2
|
||||
setuptools/_vendor/packaging-24.2.dist-info/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197
|
||||
setuptools/_vendor/packaging-24.2.dist-info/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
|
||||
setuptools/_vendor/packaging-24.2.dist-info/LICENSE.BSD,sha256=tw5-m3QvHMb5SLNMFqo5_-zpQZY2S8iP8NIYDwAo-sU,1344
|
||||
setuptools/_vendor/packaging-24.2.dist-info/METADATA,sha256=ohH86s6k5mIfQxY2TS0LcSfADeOFa4BiCC-bxZV-pNs,3204
|
||||
setuptools/_vendor/packaging-24.2.dist-info/RECORD,sha256=Y4DrXM0KY0ArfzhbAEa1LYFPwW3WEgEeL4iCqXe-A-M,2009
|
||||
setuptools/_vendor/packaging-24.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/packaging-24.2.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
||||
setuptools/_vendor/packaging/__init__.py,sha256=dk4Ta_vmdVJxYHDcfyhvQNw8V3PgSBomKNXqg-D2JDY,494
|
||||
setuptools/_vendor/packaging/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/_elffile.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/_manylinux.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/_musllinux.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/_parser.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/_structures.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/_tokenizer.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/markers.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/metadata.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/requirements.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/specifiers.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/tags.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/utils.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/__pycache__/version.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/_elffile.py,sha256=cflAQAkE25tzhYmq_aCi72QfbT_tn891tPzfpbeHOwE,3306
|
||||
setuptools/_vendor/packaging/_manylinux.py,sha256=vl5OCoz4kx80H5rwXKeXWjl9WNISGmr4ZgTpTP9lU9c,9612
|
||||
setuptools/_vendor/packaging/_musllinux.py,sha256=p9ZqNYiOItGee8KcZFeHF_YcdhVwGHdK6r-8lgixvGQ,2694
|
||||
setuptools/_vendor/packaging/_parser.py,sha256=s_TvTvDNK0NrM2QB3VKThdWFM4Nc0P6JnkObkl3MjpM,10236
|
||||
setuptools/_vendor/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
|
||||
setuptools/_vendor/packaging/_tokenizer.py,sha256=J6v5H7Jzvb-g81xp_2QACKwO7LxHQA6ikryMU7zXwN8,5273
|
||||
setuptools/_vendor/packaging/licenses/__init__.py,sha256=1x5M1nEYjcgwEbLt0dXwz2ukjr18DiCzC0sraQqJ-Ww,5715
|
||||
setuptools/_vendor/packaging/licenses/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/licenses/__pycache__/_spdx.cpython-312.pyc,,
|
||||
setuptools/_vendor/packaging/licenses/_spdx.py,sha256=oAm1ztPFwlsmCKe7lAAsv_OIOfS1cWDu9bNBkeu-2ns,48398
|
||||
setuptools/_vendor/packaging/markers.py,sha256=c89TNzB7ZdGYhkovm6PYmqGyHxXlYVaLW591PHUNKD8,10561
|
||||
setuptools/_vendor/packaging/metadata.py,sha256=YJibM7GYe4re8-0a3OlXmGS-XDgTEoO4tlBt2q25Bng,34762
|
||||
setuptools/_vendor/packaging/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/packaging/requirements.py,sha256=gYyRSAdbrIyKDY66ugIDUQjRMvxkH2ALioTmX3tnL6o,2947
|
||||
setuptools/_vendor/packaging/specifiers.py,sha256=GG1wPNMcL0fMJO68vF53wKMdwnfehDcaI-r9NpTfilA,40074
|
||||
setuptools/_vendor/packaging/tags.py,sha256=CFqrJzAzc2XNGexerH__T-Y5Iwq7WbsYXsiLERLWxY0,21014
|
||||
setuptools/_vendor/packaging/utils.py,sha256=0F3Hh9OFuRgrhTgGZUl5K22Fv1YP2tZl1z_2gO6kJiA,5050
|
||||
setuptools/_vendor/packaging/version.py,sha256=olfyuk_DPbflNkJ4wBWetXQ17c74x3DB501degUv7DY,16676
|
||||
setuptools/_vendor/platformdirs-4.2.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/platformdirs-4.2.2.dist-info/METADATA,sha256=zmsie01G1MtXR0wgIv5XpVeTO7idr0WWvfmxKsKWuGk,11429
|
||||
setuptools/_vendor/platformdirs-4.2.2.dist-info/RECORD,sha256=TCEddtQu1A78Os_Mhm2JEqcYr7yit-UYSUQjZtbpn-g,1642
|
||||
setuptools/_vendor/platformdirs-4.2.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/platformdirs-4.2.2.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
|
||||
setuptools/_vendor/platformdirs-4.2.2.dist-info/licenses/LICENSE,sha256=KeD9YukphQ6G6yjD_czwzv30-pSHkBHP-z0NS-1tTbY,1089
|
||||
setuptools/_vendor/platformdirs/__init__.py,sha256=EMGE8qeHRR9CzDFr8kL3tA8hdZZniYjXBVZd0UGTWK0,22225
|
||||
setuptools/_vendor/platformdirs/__main__.py,sha256=HnsUQHpiBaiTxwcmwVw-nFaPdVNZtQIdi1eWDtI-MzI,1493
|
||||
setuptools/_vendor/platformdirs/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/__main__.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/android.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/api.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/macos.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/unix.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/version.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/__pycache__/windows.cpython-312.pyc,,
|
||||
setuptools/_vendor/platformdirs/android.py,sha256=xZXY9Jd46WOsxT2U6-5HsNtDZ-IQqxcEUrBLl3hYk4o,9016
|
||||
setuptools/_vendor/platformdirs/api.py,sha256=QBYdUac2eC521ek_y53uD1Dcq-lJX8IgSRVd4InC6uc,8996
|
||||
setuptools/_vendor/platformdirs/macos.py,sha256=wftsbsvq6nZ0WORXSiCrZNkRHz_WKuktl0a6mC7MFkI,5580
|
||||
setuptools/_vendor/platformdirs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/platformdirs/unix.py,sha256=Cci9Wqt35dAMsg6HT9nRGHSBW5obb0pR3AE1JJnsCXg,10643
|
||||
setuptools/_vendor/platformdirs/version.py,sha256=r7F76tZRjgQKzrpx_I0_ZMQOMU-PS7eGnHD7zEK3KB0,411
|
||||
setuptools/_vendor/platformdirs/windows.py,sha256=IFpiohUBwxPtCzlyKwNtxyW4Jk8haa6W8o59mfrDXVo,10125
|
||||
setuptools/_vendor/tomli-2.0.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/tomli-2.0.1.dist-info/LICENSE,sha256=uAgWsNUwuKzLTCIReDeQmEpuO2GSLCte6S8zcqsnQv4,1072
|
||||
setuptools/_vendor/tomli-2.0.1.dist-info/METADATA,sha256=zPDceKmPwJGLWtZykrHixL7WVXWmJGzZ1jyRT5lCoPI,8875
|
||||
setuptools/_vendor/tomli-2.0.1.dist-info/RECORD,sha256=DLn5pFGh42WsVLTIhmLh2gy1SnLRalJY-wq_-dPhwCI,999
|
||||
setuptools/_vendor/tomli-2.0.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/tomli-2.0.1.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81
|
||||
setuptools/_vendor/tomli/__init__.py,sha256=JhUwV66DB1g4Hvt1UQCVMdfCu-IgAV8FXmvDU9onxd4,396
|
||||
setuptools/_vendor/tomli/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/tomli/__pycache__/_parser.cpython-312.pyc,,
|
||||
setuptools/_vendor/tomli/__pycache__/_re.cpython-312.pyc,,
|
||||
setuptools/_vendor/tomli/__pycache__/_types.cpython-312.pyc,,
|
||||
setuptools/_vendor/tomli/_parser.py,sha256=g9-ENaALS-B8dokYpCuzUFalWlog7T-SIYMjLZSWrtM,22633
|
||||
setuptools/_vendor/tomli/_re.py,sha256=dbjg5ChZT23Ka9z9DHOXfdtSpPwUfdgMXnj8NOoly-w,2943
|
||||
setuptools/_vendor/tomli/_types.py,sha256=-GTG2VUqkpxwMqzmVO4F7ybKddIbAnuAHXfmWQcTi3Q,254
|
||||
setuptools/_vendor/tomli/py.typed,sha256=8PjyZ1aVoQpRVvt71muvuq5qE-jTFZkK-GLHkhdebmc,26
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/LICENSE,sha256=YWP3mH37ONa8MgzitwsvArhivEESZRbVUu8c1DJH51g,1130
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/METADATA,sha256=z2dcHAp0TwhYCFU5Deh8x31nazElgujUz9tbuP0pjSE,3717
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/RECORD,sha256=SKUZWVgkeDUidUKM7s1473fXmsna55bjmi6vJUAoJVI,2402
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/entry_points.txt,sha256=qp7NQ1aLtiSgMQqo6gWlfGpy0IIXzoMJmeQTLpzqFZQ,48
|
||||
setuptools/_vendor/typeguard-4.3.0.dist-info/top_level.txt,sha256=4z28AhuDodwRS_c1J_l8H51t5QuwfTseskYzlxp6grs,10
|
||||
setuptools/_vendor/typeguard/__init__.py,sha256=Onh4w38elPCjtlcU3JY9k3h70NjsxXIkAflmQn-Z0FY,2071
|
||||
setuptools/_vendor/typeguard/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_checkers.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_config.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_decorators.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_exceptions.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_functions.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_importhook.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_memo.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_pytest_plugin.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_suppression.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_transformer.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_union_transformer.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/__pycache__/_utils.cpython-312.pyc,,
|
||||
setuptools/_vendor/typeguard/_checkers.py,sha256=JRrgKicdOEfIBoNEtegYCEIlhpad-a1u1Em7GCj0WCI,31360
|
||||
setuptools/_vendor/typeguard/_config.py,sha256=nIz8QwDa-oFO3L9O8_6srzlmd99pSby2wOM4Wb7F_B0,2846
|
||||
setuptools/_vendor/typeguard/_decorators.py,sha256=v6dsIeWvPhExGLP_wXF-RmDUyjZf_Ak28g7gBJ_v0-0,9033
|
||||
setuptools/_vendor/typeguard/_exceptions.py,sha256=ZIPeiV-FBd5Emw2EaWd2Fvlsrwi4ocwT2fVGBIAtHcQ,1121
|
||||
setuptools/_vendor/typeguard/_functions.py,sha256=ibgSAKa5ptIm1eR9ARG0BSozAFJPFNASZqhPVyQeqig,10393
|
||||
setuptools/_vendor/typeguard/_importhook.py,sha256=ugjCDvFcdWMU7UugqlJG91IpVNpEIxtRr-99s0h1k7M,6389
|
||||
setuptools/_vendor/typeguard/_memo.py,sha256=1juQV_vxnD2JYKbSrebiQuj4oKHz6n67v9pYA-CCISg,1303
|
||||
setuptools/_vendor/typeguard/_pytest_plugin.py,sha256=-fcSqkv54rIfIF8pDavY5YQPkj4OX8GMt_lL7CQSD4I,4416
|
||||
setuptools/_vendor/typeguard/_suppression.py,sha256=VQfzxcwIbu3if0f7VBkKM7hkYOA7tNFw9a7jMBsmMg4,2266
|
||||
setuptools/_vendor/typeguard/_transformer.py,sha256=9Ha7_QhdwoUni_6hvdY-hZbuEergowHrNL2vzHIakFY,44937
|
||||
setuptools/_vendor/typeguard/_union_transformer.py,sha256=v_42r7-6HuRX2SoFwnyJ-E5PlxXpVeUJPJR1-HU9qSo,1354
|
||||
setuptools/_vendor/typeguard/_utils.py,sha256=5HhO1rPn5f1M6ymkVAEv7Xmlz1cX-j0OnTMlyHqqrR8,5270
|
||||
setuptools/_vendor/typeguard/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/typing_extensions-4.12.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/typing_extensions-4.12.2.dist-info/LICENSE,sha256=Oy-B_iHRgcSZxZolbI4ZaEVdZonSaaqFNzv7avQdo78,13936
|
||||
setuptools/_vendor/typing_extensions-4.12.2.dist-info/METADATA,sha256=BeUQIa8cnYbrjWx-N8TOznM9UGW5Gm2DicVpDtRA8W0,3018
|
||||
setuptools/_vendor/typing_extensions-4.12.2.dist-info/RECORD,sha256=dxAALYGXHmMqpqL8M9xddKr118quIgQKZdPjFQOwXuk,571
|
||||
setuptools/_vendor/typing_extensions-4.12.2.dist-info/WHEEL,sha256=EZbGkh7Ie4PoZfRQ8I0ZuP9VklN_TvcZ6DSE5Uar4z4,81
|
||||
setuptools/_vendor/typing_extensions.py,sha256=gwekpyG9DVG3lxWKX4ni8u7nk3We5slG98mA9F3DJQw,134451
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/LICENSE.txt,sha256=MMI2GGeRCPPo6h0qZYx8pBe9_IkcmO8aifpP8MmChlQ,1107
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/METADATA,sha256=mKz84H7m7jsxJyzeIcTVORiTb0NPMV39KvOIYhGgmjA,2313
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/RECORD,sha256=1jnxrHyZPDcVvULyfGFhiba4Z5L9_RsXr9dxcNbhaYQ,4900
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
|
||||
setuptools/_vendor/wheel-0.45.1.dist-info/entry_points.txt,sha256=rTY1BbkPHhkGMm4Q3F0pIzJBzW2kMxoG1oriffvGdA0,104
|
||||
setuptools/_vendor/wheel/__init__.py,sha256=mrxMnvdXACur_LWegbUfh5g5ysWZrd63UJn890wvGNk,59
|
||||
setuptools/_vendor/wheel/__main__.py,sha256=NkMUnuTCGcOkgY0IBLgBCVC_BGGcWORx2K8jYGS12UE,455
|
||||
setuptools/_vendor/wheel/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/__main__.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/_bdist_wheel.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/_setuptools_logging.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/bdist_wheel.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/macosx_libfile.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/metadata.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/util.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/__pycache__/wheelfile.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/_bdist_wheel.py,sha256=UghCQjSH_pVfcZh6oRjzSw_TQhcf3anSx1OkiLSL82M,21694
|
||||
setuptools/_vendor/wheel/_setuptools_logging.py,sha256=-5KC-lne0ilOUWIDfOkqapUWGMFZhuKYDIavIZiB5kM,781
|
||||
setuptools/_vendor/wheel/bdist_wheel.py,sha256=tpf9WufiSO1RuEMg5oPhIfSG8DMziCZ_4muCKF69Cqo,1107
|
||||
setuptools/_vendor/wheel/cli/__init__.py,sha256=Npq6_jKi03dhIcRnmbuFhwviVJxwO0tYEnEhWMv9cJo,4402
|
||||
setuptools/_vendor/wheel/cli/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/cli/__pycache__/convert.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/cli/__pycache__/pack.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/cli/__pycache__/tags.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/cli/__pycache__/unpack.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/cli/convert.py,sha256=Bi0ntEXb9nTllCxWeTRQ4j-nPs3szWSEKipG_GgnMkQ,12634
|
||||
setuptools/_vendor/wheel/cli/pack.py,sha256=CAFcHdBVulvsHYJlndKVO7KMI9JqBTZz5ii0PKxxCOs,3103
|
||||
setuptools/_vendor/wheel/cli/tags.py,sha256=lHw-LaWrkS5Jy_qWcw-6pSjeNM6yAjDnqKI3E5JTTCU,4760
|
||||
setuptools/_vendor/wheel/cli/unpack.py,sha256=Y_J7ynxPSoFFTT7H0fMgbBlVErwyDGcObgme5MBuz58,1021
|
||||
setuptools/_vendor/wheel/macosx_libfile.py,sha256=k1x7CE3LPtOVGqj6NXQ1nTGYVPaeRrhVzUG_KPq3zDs,16572
|
||||
setuptools/_vendor/wheel/metadata.py,sha256=JC4p7jlQZu2bUTAQ2fevkqLjg_X6gnNyRhLn6OUO1tc,6171
|
||||
setuptools/_vendor/wheel/util.py,sha256=aL7aibHwYUgfc8WlolL5tXdkV4DatbJxZHb1kwHFJAU,423
|
||||
setuptools/_vendor/wheel/vendored/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/wheel/vendored/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197
|
||||
setuptools/_vendor/wheel/vendored/packaging/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174
|
||||
setuptools/_vendor/wheel/vendored/packaging/LICENSE.BSD,sha256=tw5-m3QvHMb5SLNMFqo5_-zpQZY2S8iP8NIYDwAo-sU,1344
|
||||
setuptools/_vendor/wheel/vendored/packaging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/_elffile.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/_manylinux.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/_musllinux.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/_parser.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/_structures.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/_tokenizer.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/markers.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/requirements.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/specifiers.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/tags.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/utils.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/__pycache__/version.cpython-312.pyc,,
|
||||
setuptools/_vendor/wheel/vendored/packaging/_elffile.py,sha256=hbmK8OD6Z7fY6hwinHEUcD1by7czkGiNYu7ShnFEk2k,3266
|
||||
setuptools/_vendor/wheel/vendored/packaging/_manylinux.py,sha256=P7sdR5_7XBY09LVYYPhHmydMJIIwPXWsh4olk74Uuj4,9588
|
||||
setuptools/_vendor/wheel/vendored/packaging/_musllinux.py,sha256=z1s8To2hQ0vpn_d-O2i5qxGwEK8WmGlLt3d_26V7NeY,2674
|
||||
setuptools/_vendor/wheel/vendored/packaging/_parser.py,sha256=4tT4emSl2qTaU7VTQE1Xa9o1jMPCsBezsYBxyNMUN-s,10347
|
||||
setuptools/_vendor/wheel/vendored/packaging/_structures.py,sha256=q3eVNmbWJGG_S0Dit_S3Ao8qQqz_5PYTXFAKBZe5yr4,1431
|
||||
setuptools/_vendor/wheel/vendored/packaging/_tokenizer.py,sha256=alCtbwXhOFAmFGZ6BQ-wCTSFoRAJ2z-ysIf7__MTJ_k,5292
|
||||
setuptools/_vendor/wheel/vendored/packaging/markers.py,sha256=_TSPI1BhJYO7Bp9AzTmHQxIqHEVXaTjmDh9G-w8qzPA,8232
|
||||
setuptools/_vendor/wheel/vendored/packaging/requirements.py,sha256=dgoBeVprPu2YE6Q8nGfwOPTjATHbRa_ZGLyXhFEln6Q,2933
|
||||
setuptools/_vendor/wheel/vendored/packaging/specifiers.py,sha256=IWSt0SrLSP72heWhAC8UL0eGvas7XIQHjqiViVfmPKE,39778
|
||||
setuptools/_vendor/wheel/vendored/packaging/tags.py,sha256=fedHXiOHkBxNZTXotXv8uXPmMFU9ae-TKBujgYHigcA,18950
|
||||
setuptools/_vendor/wheel/vendored/packaging/utils.py,sha256=XgdmP3yx9-wQEFjO7OvMj9RjEf5JlR5HFFR69v7SQ9E,5268
|
||||
setuptools/_vendor/wheel/vendored/packaging/version.py,sha256=PFJaYZDxBgyxkfYhH3SQw4qfE9ICCWrTmitvq14y3bs,16234
|
||||
setuptools/_vendor/wheel/vendored/vendor.txt,sha256=Z2ENjB1i5prfez8CdM1Sdr3c6Zxv2rRRolMpLmBncAE,16
|
||||
setuptools/_vendor/wheel/wheelfile.py,sha256=USCttNlJwafxt51YYFFKG7jnxz8dfhbyqAZL6jMTA9s,8411
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/METADATA,sha256=UIrk_kMIHGSwsKKChYizqMw0MMZpPRZ2ZiVpQAsN_bE,3575
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/RECORD,sha256=8xby4D_ZrefrvAsVRwaEjiu4_VaLkJNRCfDY484rm_4,1039
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
||||
setuptools/_vendor/zipp-3.19.2.dist-info/top_level.txt,sha256=iAbdoSHfaGqBfVb2XuR9JqSQHCoOsOtG6y9C_LSpqFw,5
|
||||
setuptools/_vendor/zipp/__init__.py,sha256=QuI1g00G4fRAcGt-HqbV0oWIkmSgedCGGYsHHYzNa8A,13412
|
||||
setuptools/_vendor/zipp/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/zipp/__pycache__/glob.cpython-312.pyc,,
|
||||
setuptools/_vendor/zipp/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/_vendor/zipp/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/_vendor/zipp/compat/__pycache__/py310.cpython-312.pyc,,
|
||||
setuptools/_vendor/zipp/compat/py310.py,sha256=eZpkW0zRtunkhEh8jjX3gCGe22emoKCBJw72Zt4RkhA,219
|
||||
setuptools/_vendor/zipp/glob.py,sha256=etWpnfEoRyfUvrUsi6sTiGmErvPwe6HzY6pT8jg_lUI,3082
|
||||
setuptools/archive_util.py,sha256=Tl_64hSTtc4y8x7xa98rFVUbG24oArpjzLAYGYP2_sI,7356
|
||||
setuptools/build_meta.py,sha256=3cHAWucJaLA9DU5OfCbKkkteTDiQ5bB4LokfTRMgJT4,19968
|
||||
setuptools/cli-32.exe,sha256=MqzBvFQxFsviz_EMuGd3LfLyVP8mNMhwrvC0bEtpb9s,11776
|
||||
setuptools/cli-64.exe,sha256=u7PeVwdinmpgoMI4zUd7KPB_AGaYL9qVP6b87DkHOko,14336
|
||||
setuptools/cli-arm64.exe,sha256=uafQjaiA36yLz1SOuksG-1m28JsX0zFIoPZhgyiSbGE,13824
|
||||
setuptools/cli.exe,sha256=MqzBvFQxFsviz_EMuGd3LfLyVP8mNMhwrvC0bEtpb9s,11776
|
||||
setuptools/command/__init__.py,sha256=wdSrlNR0P6nCz9_oFtCAiAkeFJMsZa1jPcpXT53f0SM,803
|
||||
setuptools/command/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/_requirestxt.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/alias.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/bdist_egg.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/bdist_rpm.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/bdist_wheel.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/build.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/build_clib.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/build_ext.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/build_py.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/develop.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/dist_info.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/easy_install.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/editable_wheel.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/egg_info.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/install.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/install_egg_info.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/install_lib.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/install_scripts.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/rotate.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/saveopts.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/sdist.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/setopt.cpython-312.pyc,,
|
||||
setuptools/command/__pycache__/test.cpython-312.pyc,,
|
||||
setuptools/command/_requirestxt.py,sha256=ItYMTJGh_i5TlQstX_nFopqEhkC4PJFadBL2Zd3V670,4228
|
||||
setuptools/command/alias.py,sha256=rDdrMt32DS6qf3K7tjZZyHD_dMKrm77AXcAtx-nBQ0I,2380
|
||||
setuptools/command/bdist_egg.py,sha256=JmtKoIbiwgEHcJBkbc7zyXCZcAF851t6ek18gme-60Q,16948
|
||||
setuptools/command/bdist_rpm.py,sha256=LyqI49w48SKk0FmuHsE9MLzX1SuXjL7YMNbZMFZqFII,1435
|
||||
setuptools/command/bdist_wheel.py,sha256=SknYPVwhrRPfXudmO_gvqNHHHhzSfU8cEmFtQomQ9xI,22247
|
||||
setuptools/command/build.py,sha256=eI7STMERGGZEpzk1tvJN8p9IOjAAXMcGLzljv2mwI3M,6052
|
||||
setuptools/command/build_clib.py,sha256=AbgpPIF_3qL8fZr3JIebI-WHTMTBiMfrFkVQz8K40G4,4528
|
||||
setuptools/command/build_ext.py,sha256=Wddi6ho4MnVh84qqZUNqTvjKLqeoWe6cbwdJOUitXCc,18465
|
||||
setuptools/command/build_py.py,sha256=DCbjvB18kkL-xUK5rvlzm0C6twTeOxNhyvJDxxa7fII,15539
|
||||
setuptools/command/develop.py,sha256=1dsb2lkjcPQQAlQNVVlfPIJUBZ9di0l5bs4l83g9-9Y,1610
|
||||
setuptools/command/dist_info.py,sha256=HU752iLLmmYMHbsDBgz2ubRjkgJobugOp8H71LzzDys,3450
|
||||
setuptools/command/easy_install.py,sha256=XrN5cV51mfzbCDoapZ6iT8nCzaLpumdwJYRKeMHEjCQ,780
|
||||
setuptools/command/editable_wheel.py,sha256=MXyQx41gwu3d1raYSZGgzCVp5kkVtlCKftZKvTma3wY,34836
|
||||
setuptools/command/egg_info.py,sha256=GXyvq5E8huO4g-FDoNzf3MHjeXfxzPoS0Hkvbta_zc8,25878
|
||||
setuptools/command/install.py,sha256=4x2hiNgBGQrFEXKuPBQMrb8ecSwIfYF4TYHZQLjPVAg,5066
|
||||
setuptools/command/install_egg_info.py,sha256=3I9IPCH7D59Sh-6aVYz-h6wwyxq-wkxrKwKg3nDdJqs,2075
|
||||
setuptools/command/install_lib.py,sha256=9n1_U83eHcERL_a_rv_LhHCkhXlLdqyZ4SdBow-9qcE,4319
|
||||
setuptools/command/install_scripts.py,sha256=JmDGngHzCO2Y1j4maFNdHB_ILhGPhk-b5KhxsZwUwiQ,2490
|
||||
setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628
|
||||
setuptools/command/rotate.py,sha256=XNd_BEEOWAJHW1FcLTMUWWl4QB6zAuk7b8VWQg3FHos,2187
|
||||
setuptools/command/saveopts.py,sha256=Np0PVb7SD7oTbu9Z9sosS7D-CkkIkU7x4glu5Es1tjA,692
|
||||
setuptools/command/sdist.py,sha256=5ZiA8yfdNfl-kLTnfPAht1yKnS1o_HrSFphsJd-9foU,7369
|
||||
setuptools/command/setopt.py,sha256=xZF2RCc4ABvE9eHHAzF50-fkQg3au8fcRUVVGd58k3U,5100
|
||||
setuptools/command/test.py,sha256=k7xcq7D7bEehgxarbw-dW3AtmGZORqz8HjKR6FGJ3jk,1343
|
||||
setuptools/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/compat/__pycache__/py310.cpython-312.pyc,,
|
||||
setuptools/compat/__pycache__/py311.cpython-312.pyc,,
|
||||
setuptools/compat/__pycache__/py312.cpython-312.pyc,,
|
||||
setuptools/compat/__pycache__/py39.cpython-312.pyc,,
|
||||
setuptools/compat/py310.py,sha256=JwjQZ3cNTizfpDLNl9GLsUGzBr-tVlMPxmMYVDTlhiI,344
|
||||
setuptools/compat/py311.py,sha256=e6tJAFwZEP82hmMBl10HYeSypelo_Ti2wTjKZVKLwOE,790
|
||||
setuptools/compat/py312.py,sha256=vYKVtdrdOTsO_R90dJkEXsFwfMJFuIFJflhIgHrjJ-Y,366
|
||||
setuptools/compat/py39.py,sha256=BJMtnkfcqyTfccqjYQxfoRtU2nTnWaEESBVkshTiXqY,493
|
||||
setuptools/config/NOTICE,sha256=Ld3wiBgpejuJ1D2V_2WdjahXQRCMkTbfo6TYVsBiO9g,493
|
||||
setuptools/config/__init__.py,sha256=aiPnL9BJn1O6MfmuNXyn8W2Lp8u9qizRVqwPiOdPIjY,1499
|
||||
setuptools/config/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/config/__pycache__/_apply_pyprojecttoml.cpython-312.pyc,,
|
||||
setuptools/config/__pycache__/expand.cpython-312.pyc,,
|
||||
setuptools/config/__pycache__/pyprojecttoml.cpython-312.pyc,,
|
||||
setuptools/config/__pycache__/setupcfg.cpython-312.pyc,,
|
||||
setuptools/config/_apply_pyprojecttoml.py,sha256=SUyTw7A2btZ1lBuWKN5o42-Diyv95eGTiYJ3rZOnGSc,19120
|
||||
setuptools/config/_validate_pyproject/NOTICE,sha256=XTANv6ZDE4sBO3WsnK7uWR-VG4sO4kKIw0zNkmxHgMg,18737
|
||||
setuptools/config/_validate_pyproject/__init__.py,sha256=dnp6T7ePP1R5z4OuC7Fd2dkFlIrtIfizUfvpGJP6nz0,1042
|
||||
setuptools/config/_validate_pyproject/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/config/_validate_pyproject/__pycache__/error_reporting.cpython-312.pyc,,
|
||||
setuptools/config/_validate_pyproject/__pycache__/extra_validations.cpython-312.pyc,,
|
||||
setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_exceptions.cpython-312.pyc,,
|
||||
setuptools/config/_validate_pyproject/__pycache__/fastjsonschema_validations.cpython-312.pyc,,
|
||||
setuptools/config/_validate_pyproject/__pycache__/formats.cpython-312.pyc,,
|
||||
setuptools/config/_validate_pyproject/error_reporting.py,sha256=meldD7nBQdolQhvG-43r1Ue-gU1n7ORAJR86vh3Rrvk,11813
|
||||
setuptools/config/_validate_pyproject/extra_validations.py,sha256=-GUG5S--ijY8WfXbdXPoHl6ywGsyEF9dtDpenSoJPHg,2858
|
||||
setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py,sha256=w749JgqKi8clBFcObdcbZVqsmF4oJ_QByhZ1SGbUFNw,1612
|
||||
setuptools/config/_validate_pyproject/fastjsonschema_validations.py,sha256=FihD5ZcM6p77BPZ04CGqh3BEwVNoPMKJZJAyuJpkAU0,354682
|
||||
setuptools/config/_validate_pyproject/formats.py,sha256=TETokJBK9hjl-cVg1olsojkJwLxfP7_chgJQNmzAB98,13564
|
||||
setuptools/config/distutils.schema.json,sha256=Tcp32kRnhwORGw_9p6GEi08lj2h15tQRzOYBbzGmcBU,972
|
||||
setuptools/config/expand.py,sha256=JNAktRCsyyRB-rQodbPnCucmLWqcYvzCDC8Ebn2Z7xM,16041
|
||||
setuptools/config/pyprojecttoml.py,sha256=YMu5PdbJJI5azp6kR_boM1mflf5nqOA-InF4s6LnLgw,18320
|
||||
setuptools/config/setupcfg.py,sha256=VZDkwE7DYv45SbadJD8CwKrDtiXvjgllL8PYSvoRCyg,26575
|
||||
setuptools/config/setuptools.schema.json,sha256=dZBRuSEnZkatoVlt1kVwG8ocTeRdO7BD0xvOWKH54PY,16071
|
||||
setuptools/depends.py,sha256=jKYfjmt_2ZQYVghb8L9bU7LJ6erHJ5ze-K_fKV1BMXk,5965
|
||||
setuptools/discovery.py,sha256=-42c3XhwzkfodDKKP50C2YBzr11fncAgmUzBdBRb0-Q,21258
|
||||
setuptools/dist.py,sha256=jrLGf-4udZjoZyULuGrXEPzgFDVq1CHCfGsqjTq52Gg,44887
|
||||
setuptools/errors.py,sha256=gY2x2PIaIgy01yRANRC-zcCwxDCqCScgJoCOZFe0yio,3024
|
||||
setuptools/extension.py,sha256=KCnv9p3tgm0ZVqtgE451fyILsm4hCyvOiUtOu787D-4,6683
|
||||
setuptools/glob.py,sha256=AC_B33DY8g-CHELxDsJrtwFrpiucSAZsakPFdSOQzhc,6062
|
||||
setuptools/gui-32.exe,sha256=hdrh6V13hF8stZvKw9Sv50u-TJGpvMW_SnHNQxBNvnw,11776
|
||||
setuptools/gui-64.exe,sha256=NHG2FA6txkEid9u-_j_vjDRaDxpZd2CGuAo2GMOoPjs,14336
|
||||
setuptools/gui-arm64.exe,sha256=5pT0dDQFyLWSb_RX22_n8aEt7HwWqcOGR4TT9OB64Jc,13824
|
||||
setuptools/gui.exe,sha256=hdrh6V13hF8stZvKw9Sv50u-TJGpvMW_SnHNQxBNvnw,11776
|
||||
setuptools/installer.py,sha256=veio-PDCseWN0J1E_1gjvVLkcIhPpQLlEKpSaA03WWk,5093
|
||||
setuptools/launch.py,sha256=IBb5lEv69CyuZ9ewIrmKlXh154kdLmP29LKfTMkximE,820
|
||||
setuptools/logging.py,sha256=W16iHJ1HcCXYQ0RxyrEfJ83FT4175tCtoYg-E6uSpVI,1261
|
||||
setuptools/modified.py,sha256=ZwbfBfCFP88ltvbv_dJDz-t1LsQjnM-JUpgZnnQZjjM,568
|
||||
setuptools/monkey.py,sha256=FwMWl2n1v2bHbeqBy-o9g8yUNaAkYFbszCbXe9d5Za8,3717
|
||||
setuptools/msvc.py,sha256=vmM0qL4rIzrtD9pia9ZEwtqZ4LbbrgL0dU0EANVYRm8,41631
|
||||
setuptools/namespaces.py,sha256=2GGqYY1BNDEhMtBc1rHTv7klgmNVRdksJeW-L1f--ys,3171
|
||||
setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218
|
||||
setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138
|
||||
setuptools/tests/__init__.py,sha256=AnBfls2iJbTDQzmMKeLRt-9lxhaOHUVOZEgXv89Uwvs,335
|
||||
setuptools/tests/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/contexts.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/environment.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/fixtures.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/mod_with_constant.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/namespaces.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/script-with-bom.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_archive_util.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_bdist_deprecations.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_bdist_egg.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_bdist_wheel.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_build.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_build_clib.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_build_ext.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_build_meta.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_build_py.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_config_discovery.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_core_metadata.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_depends.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_develop.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_dist.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_dist_info.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_distutils_adoption.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_editable_install.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_egg_info.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_extern.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_find_packages.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_find_py_modules.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_glob.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_install_scripts.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_logging.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_manifest.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_namespaces.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_scripts.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_sdist.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_setopt.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_setuptools.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_shutil_wrapper.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_unicode_utils.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_virtualenv.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_warnings.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_wheel.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/test_windows_wrappers.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/text.cpython-312.pyc,,
|
||||
setuptools/tests/__pycache__/textwrap.cpython-312.pyc,,
|
||||
setuptools/tests/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/tests/compat/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/tests/compat/__pycache__/py39.cpython-312.pyc,,
|
||||
setuptools/tests/compat/py39.py,sha256=eUy7_F-6KRTOIKl-veshUu6I0EdTSdBZMh0EV0lZ1-g,135
|
||||
setuptools/tests/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/tests/config/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/tests/config/__pycache__/test_apply_pyprojecttoml.cpython-312.pyc,,
|
||||
setuptools/tests/config/__pycache__/test_expand.cpython-312.pyc,,
|
||||
setuptools/tests/config/__pycache__/test_pyprojecttoml.cpython-312.pyc,,
|
||||
setuptools/tests/config/__pycache__/test_pyprojecttoml_dynamic_deps.cpython-312.pyc,,
|
||||
setuptools/tests/config/__pycache__/test_setupcfg.cpython-312.pyc,,
|
||||
setuptools/tests/config/downloads/__init__.py,sha256=9ixnDEdyL_arKbUzfuiJftAj9bGxKz8M9alOFZMjx9Y,1827
|
||||
setuptools/tests/config/downloads/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/tests/config/downloads/__pycache__/preload.cpython-312.pyc,,
|
||||
setuptools/tests/config/downloads/preload.py,sha256=sIGGZpY3cmMpMwiJYYYYHG2ifZJkvJgEotRFtiulV1I,450
|
||||
setuptools/tests/config/setupcfg_examples.txt,sha256=cAbVvCbkFZuTUL6xRRzRgqyB0rLvJTfvw3D30glo2OE,1912
|
||||
setuptools/tests/config/test_apply_pyprojecttoml.py,sha256=l6nE4d8WLU_eSWRic7VSoqeKv9Bi7CZGHcEuB2ehk2w,28807
|
||||
setuptools/tests/config/test_expand.py,sha256=S0oT6JvgA_oujR4YS4RUuf5gmOt1CTQV66RQDzV8xd4,8933
|
||||
setuptools/tests/config/test_pyprojecttoml.py,sha256=0LefSljUhA6MqtJ5AVzLhomqZcYiFKdu_1ckDeMT1LY,12406
|
||||
setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py,sha256=9W73-yLhZJmvCiO4rTiQoBpZT5wNA90Xbd5n2HCshd4,3271
|
||||
setuptools/tests/config/test_setupcfg.py,sha256=ZvN-O-2Dgon1adp6oM6il8JWdgT9y196fRvqESU5ELI,33427
|
||||
setuptools/tests/contexts.py,sha256=Ozdfc2KydF9x9wODUsdun800myLuP27uxoeT06Gbk7M,3166
|
||||
setuptools/tests/environment.py,sha256=95_UtTaRiuvwYC9eXKEHbn02kDtZysvZq3UZJmPUj1I,3102
|
||||
setuptools/tests/fixtures.py,sha256=aPewdPHlKHRAsMo9H828c3ZC8l3OJqgyfRYwpLBvgCk,11705
|
||||
setuptools/tests/indexes/test_links_priority/external.html,sha256=eL9euOuE93JKZdqlXxBOlHbKwIuNuIdq7GBRpsaPMcU,92
|
||||
setuptools/tests/indexes/test_links_priority/simple/foobar/index.html,sha256=DD-TKr7UU4zAjHHz4VexYDNSAzR27levSh1c-k3ZdLE,174
|
||||
setuptools/tests/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
||||
setuptools/tests/integration/__pycache__/__init__.cpython-312.pyc,,
|
||||
setuptools/tests/integration/__pycache__/helpers.cpython-312.pyc,,
|
||||
setuptools/tests/integration/__pycache__/test_pbr.cpython-312.pyc,,
|
||||
setuptools/tests/integration/__pycache__/test_pip_install_sdist.cpython-312.pyc,,
|
||||
setuptools/tests/integration/helpers.py,sha256=3PHcS9SCA-fwVJmUP2ad5NQOttJAETI5Nnoc_xroO5k,2522
|
||||
setuptools/tests/integration/test_pbr.py,sha256=2eKuklFNmpnBgA_eEhYPBr6rLLG2Xm4MY6PlcmzZgGU,432
|
||||
setuptools/tests/integration/test_pip_install_sdist.py,sha256=SFbvuYF_hDzt6OtsQ5GjFNnxmoJ_eElfvpYsiyyGJ-g,8256
|
||||
setuptools/tests/mod_with_constant.py,sha256=X_Kj80M55w1tmQ4f7uZY91ZTALo4hKVT6EHxgYocUMQ,22
|
||||
setuptools/tests/namespaces.py,sha256=HPcI3nR5MCFWXpaADIJ1fwKxymcQgBkuw87Ic5PUSAQ,2774
|
||||
setuptools/tests/script-with-bom.py,sha256=hRRgIizEULGiG_ZTNoMY46HhKhxpWfy5FGcD6Qbh5fc,18
|
||||
setuptools/tests/test_archive_util.py,sha256=buuKdY8XkW26Pe3IKAoBRGHG0MDumnuNoPg2WsAQzIg,845
|
||||
setuptools/tests/test_bdist_deprecations.py,sha256=75Xq3gYn79LIIyusEltbHan0bEgAt2e_CaL7KLS8-KQ,775
|
||||
setuptools/tests/test_bdist_egg.py,sha256=6PaYN1F3JDbIh1uK0urv7yJFcx98z5dn9SOJ8Mv91l8,1957
|
||||
setuptools/tests/test_bdist_wheel.py,sha256=dZ9a7OT_UyRvLnoCi2KGEIbtzhEQjM3YutYMA6ZCezs,23083
|
||||
setuptools/tests/test_build.py,sha256=wJgMz2hwHADcLFg-nXrwRVhus7hjmAeEGgrpIQwCGnA,798
|
||||
setuptools/tests/test_build_clib.py,sha256=bX51XRAf4uO7IuHFpjePnoK8mE74N2gsoeEqF-ofgws,3123
|
||||
setuptools/tests/test_build_ext.py,sha256=e4ZSxsYPB5zq1KSqGEuATZ0t0PJQzMhjjkKJ-hIjcgc,10099
|
||||
setuptools/tests/test_build_meta.py,sha256=kvi0Bn4p9DBVme3zyWQsn3QgB9oPdq8S15agj1m69L0,33289
|
||||
setuptools/tests/test_build_py.py,sha256=gobME_Cvzf6Ugxq70iWfXekb_xyyT61khwjFq8zkwfw,14186
|
||||
setuptools/tests/test_config_discovery.py,sha256=FqV-lOtkqaI-ayzU2zocSdD5TaRAgCZnixNDilKA6FQ,22580
|
||||
setuptools/tests/test_core_metadata.py,sha256=vbVJ5_Lsx_hsO_GdB6nQEXJRjA2ydx6_qSbr5LpheAA,20881
|
||||
setuptools/tests/test_depends.py,sha256=yQBXoQbNQlJit6mbRVoz6Bb553f3sNrq02lZimNz5XY,424
|
||||
setuptools/tests/test_develop.py,sha256=MHYL_YDqNMU5jhKkjsBUGKMGCkrva8CFR8dRc6kkYKE,3072
|
||||
setuptools/tests/test_dist.py,sha256=_IYleHR9YVqzV-nLq_JqSup6DNeUdPzuQ0EXhp009Uk,8893
|
||||
setuptools/tests/test_dist_info.py,sha256=F_xTXc5TGhjiujtGukFt6wNstqpTW7sVQtUnL1IX7yo,4988
|
||||
setuptools/tests/test_distutils_adoption.py,sha256=_eynrOfyEqXFEmjUJhzpe8GXPyTUPvNSObs4qAAmBy8,5987
|
||||
setuptools/tests/test_editable_install.py,sha256=Tg4kunvwYoDLYsfvSkggneUgpKQferUDx3EEvvdfmwE,42619
|
||||
setuptools/tests/test_egg_info.py,sha256=R7nT27YhVz9oSuDyimAGerWglkbRWiMSPBs5FzcSnBM,44941
|
||||
setuptools/tests/test_extern.py,sha256=rpKU6oCcksumLwf5TeKlDluFQ0TUfbPwTLQbpxcFrCU,296
|
||||
setuptools/tests/test_find_packages.py,sha256=CTLAcTzWGWBLCcd2aAsUVkvO3ibrlqexFBdDKOWPoq8,7819
|
||||
setuptools/tests/test_find_py_modules.py,sha256=zQjuhIG5TQN2SJPix9ARo4DL_w84Ln8QsHDUjjbrtAQ,2404
|
||||
setuptools/tests/test_glob.py,sha256=P3JvpH-kXQ4BZ3zvRF-zKxOgwyWzwIaQIz0WHdxS0kk,887
|
||||
setuptools/tests/test_install_scripts.py,sha256=scIrJ6a_ssKqg4vIBNaUjmAKHEYLUUZ9WKnPeKnE6gc,3433
|
||||
setuptools/tests/test_logging.py,sha256=zlE5DlldukC7Jc54FNvDV_7ux3ErAkrfrN5CSsnNOUQ,2099
|
||||
setuptools/tests/test_manifest.py,sha256=eMg65pIA52DizB6mpktSU-b8CjwaNCS5MSgL_V1LrFI,18562
|
||||
setuptools/tests/test_namespaces.py,sha256=Y6utoe5PHHqL_DlgawqB9F8XpsUDPvvw1sQMenK04e0,4515
|
||||
setuptools/tests/test_scripts.py,sha256=_ra506yQF7n72ROUDcz2r3CTsGsawO1m-1oqA9EQCfw,379
|
||||
setuptools/tests/test_sdist.py,sha256=RYLvPa_nfyC1ZmoinzqMzJynTDG4RtPYC19_0LU6pvs,32872
|
||||
setuptools/tests/test_setopt.py,sha256=3VxxM4ATfP-P4AGnDjoWCnHr5-i9CSEQTFYU1-FTnvI,1365
|
||||
setuptools/tests/test_setuptools.py,sha256=_eIhqKf45-OtHqxRf20KndOZJlJdS0PuFLXBO3M-LN8,9008
|
||||
setuptools/tests/test_shutil_wrapper.py,sha256=g15E11PtZxG-InB2BWNFyH-svObXx2XcMhgMLJPuFnc,641
|
||||
setuptools/tests/test_unicode_utils.py,sha256=xWfEEl8jkQCt9othUTXJfFmdyATAFggJs2tTxjbumbw,316
|
||||
setuptools/tests/test_virtualenv.py,sha256=g-njC_9JTAs1YVx_1dGJ_Q6RlInO4qKVu9-XAgNb6TY,3730
|
||||
setuptools/tests/test_warnings.py,sha256=zwR2zcnCeCeDqILZlJOPAcuyPHoDvGu1OtOVYiLMk74,3347
|
||||
setuptools/tests/test_wheel.py,sha256=I709mQO4YCztxI2L8x7bu_rE818vC9SXHR8qtZPwZW8,18752
|
||||
setuptools/tests/test_windows_wrappers.py,sha256=wBjXN3iGldkzRGTgKTrx99xqUqwPJ0V-ldyiB1pWD-g,7868
|
||||
setuptools/tests/text.py,sha256=a12197pMVTvB6FAWQ0ujT8fIQiLIWJlFAl1UCaDUDfg,123
|
||||
setuptools/tests/textwrap.py,sha256=FNNNq_MiaEJx88PnsbJQIRxmj1qmgcAOCXXRsODPJN4,98
|
||||
setuptools/unicode_utils.py,sha256=ukMGh8pEAw6F_Ezb-K5D3c-078RgA_GcF0oW6lg4lSs,3189
|
||||
setuptools/version.py,sha256=WJCeUuyq74Aok2TeK9-OexZOu8XrlQy7-y0BEuWNovQ,161
|
||||
setuptools/warnings.py,sha256=oY0Se5eOqje_FEyjTgonUc0XGwgsrI5cgm1kkwulz_w,3796
|
||||
setuptools/wheel.py,sha256=_JuhinWmlQwBHJrdIh1yfhrDS7GFMacCiJiOY3H5gwA,9477
|
||||
setuptools/windows_support.py,sha256=wW4IYLM1Bv7Z1MaauP2xmPjyy-wkmQnXdyvXscAf9fw,726
|
@@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: setuptools (80.9.0)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
@@ -0,0 +1,51 @@
|
||||
[distutils.commands]
|
||||
alias = setuptools.command.alias:alias
|
||||
bdist_egg = setuptools.command.bdist_egg:bdist_egg
|
||||
bdist_rpm = setuptools.command.bdist_rpm:bdist_rpm
|
||||
bdist_wheel = setuptools.command.bdist_wheel:bdist_wheel
|
||||
build = setuptools.command.build:build
|
||||
build_clib = setuptools.command.build_clib:build_clib
|
||||
build_ext = setuptools.command.build_ext:build_ext
|
||||
build_py = setuptools.command.build_py:build_py
|
||||
develop = setuptools.command.develop:develop
|
||||
dist_info = setuptools.command.dist_info:dist_info
|
||||
easy_install = setuptools.command.easy_install:easy_install
|
||||
editable_wheel = setuptools.command.editable_wheel:editable_wheel
|
||||
egg_info = setuptools.command.egg_info:egg_info
|
||||
install = setuptools.command.install:install
|
||||
install_egg_info = setuptools.command.install_egg_info:install_egg_info
|
||||
install_lib = setuptools.command.install_lib:install_lib
|
||||
install_scripts = setuptools.command.install_scripts:install_scripts
|
||||
rotate = setuptools.command.rotate:rotate
|
||||
saveopts = setuptools.command.saveopts:saveopts
|
||||
sdist = setuptools.command.sdist:sdist
|
||||
setopt = setuptools.command.setopt:setopt
|
||||
|
||||
[distutils.setup_keywords]
|
||||
dependency_links = setuptools.dist:assert_string_list
|
||||
eager_resources = setuptools.dist:assert_string_list
|
||||
entry_points = setuptools.dist:check_entry_points
|
||||
exclude_package_data = setuptools.dist:check_package_data
|
||||
extras_require = setuptools.dist:check_extras
|
||||
include_package_data = setuptools.dist:assert_bool
|
||||
install_requires = setuptools.dist:check_requirements
|
||||
namespace_packages = setuptools.dist:check_nsp
|
||||
package_data = setuptools.dist:check_package_data
|
||||
packages = setuptools.dist:check_packages
|
||||
python_requires = setuptools.dist:check_specifier
|
||||
setup_requires = setuptools.dist:check_requirements
|
||||
use_2to3 = setuptools.dist:invalid_unless_false
|
||||
zip_safe = setuptools.dist:assert_bool
|
||||
|
||||
[egg_info.writers]
|
||||
PKG-INFO = setuptools.command.egg_info:write_pkg_info
|
||||
dependency_links.txt = setuptools.command.egg_info:overwrite_arg
|
||||
eager_resources.txt = setuptools.command.egg_info:overwrite_arg
|
||||
entry_points.txt = setuptools.command.egg_info:write_entries
|
||||
namespace_packages.txt = setuptools.command.egg_info:overwrite_arg
|
||||
requires.txt = setuptools.command.egg_info:write_requirements
|
||||
top_level.txt = setuptools.command.egg_info:write_toplevel_names
|
||||
|
||||
[setuptools.finalize_distribution_options]
|
||||
keywords = setuptools.dist:Distribution._finalize_setup_keywords
|
||||
parent_finalize = setuptools.dist:_Distribution.finalize_options
|
@@ -0,0 +1,17 @@
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to
|
||||
deal in the Software without restriction, including without limitation the
|
||||
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
sell copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
@@ -0,0 +1,3 @@
|
||||
_distutils_hack
|
||||
pkg_resources
|
||||
setuptools
|
@@ -0,0 +1,248 @@
|
||||
"""Extensions to the 'distutils' for large or complex distributions"""
|
||||
# mypy: disable_error_code=override
|
||||
# Command.reinitialize_command has an extra **kw param that distutils doesn't have
|
||||
# Can't disable on the exact line because distutils doesn't exists on Python 3.12
|
||||
# and mypy isn't aware of distutils_hack, causing distutils.core.Command to be Any,
|
||||
# and a [unused-ignore] to be raised on 3.12+
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import functools
|
||||
import os
|
||||
import sys
|
||||
from abc import abstractmethod
|
||||
from collections.abc import Mapping
|
||||
from typing import TYPE_CHECKING, TypeVar, overload
|
||||
|
||||
sys.path.extend(((vendor_path := os.path.join(os.path.dirname(os.path.dirname(__file__)), 'setuptools', '_vendor')) not in sys.path) * [vendor_path]) # fmt: skip
|
||||
# workaround for #4476
|
||||
sys.modules.pop('backports', None)
|
||||
|
||||
import _distutils_hack.override # noqa: F401
|
||||
|
||||
from . import logging, monkey
|
||||
from .depends import Require
|
||||
from .discovery import PackageFinder, PEP420PackageFinder
|
||||
from .dist import Distribution
|
||||
from .extension import Extension
|
||||
from .version import __version__ as __version__
|
||||
from .warnings import SetuptoolsDeprecationWarning
|
||||
|
||||
import distutils.core
|
||||
|
||||
__all__ = [
|
||||
'setup',
|
||||
'Distribution',
|
||||
'Command',
|
||||
'Extension',
|
||||
'Require',
|
||||
'SetuptoolsDeprecationWarning',
|
||||
'find_packages',
|
||||
'find_namespace_packages',
|
||||
]
|
||||
|
||||
_CommandT = TypeVar("_CommandT", bound="_Command")
|
||||
|
||||
bootstrap_install_from = None
|
||||
|
||||
find_packages = PackageFinder.find
|
||||
find_namespace_packages = PEP420PackageFinder.find
|
||||
|
||||
|
||||
def _install_setup_requires(attrs):
|
||||
# Note: do not use `setuptools.Distribution` directly, as
|
||||
# our PEP 517 backend patch `distutils.core.Distribution`.
|
||||
class MinimalDistribution(distutils.core.Distribution):
|
||||
"""
|
||||
A minimal version of a distribution for supporting the
|
||||
fetch_build_eggs interface.
|
||||
"""
|
||||
|
||||
def __init__(self, attrs: Mapping[str, object]) -> None:
|
||||
_incl = 'dependency_links', 'setup_requires'
|
||||
filtered = {k: attrs[k] for k in set(_incl) & set(attrs)}
|
||||
super().__init__(filtered)
|
||||
# Prevent accidentally triggering discovery with incomplete set of attrs
|
||||
self.set_defaults._disable()
|
||||
|
||||
def _get_project_config_files(self, filenames=None):
|
||||
"""Ignore ``pyproject.toml``, they are not related to setup_requires"""
|
||||
try:
|
||||
cfg, _toml = super()._split_standard_project_metadata(filenames)
|
||||
except Exception:
|
||||
return filenames, ()
|
||||
return cfg, ()
|
||||
|
||||
def finalize_options(self):
|
||||
"""
|
||||
Disable finalize_options to avoid building the working set.
|
||||
Ref #2158.
|
||||
"""
|
||||
|
||||
dist = MinimalDistribution(attrs)
|
||||
|
||||
# Honor setup.cfg's options.
|
||||
dist.parse_config_files(ignore_option_errors=True)
|
||||
if dist.setup_requires:
|
||||
_fetch_build_eggs(dist)
|
||||
|
||||
|
||||
def _fetch_build_eggs(dist: Distribution):
|
||||
try:
|
||||
dist.fetch_build_eggs(dist.setup_requires)
|
||||
except Exception as ex:
|
||||
msg = """
|
||||
It is possible a package already installed in your system
|
||||
contains an version that is invalid according to PEP 440.
|
||||
You can try `pip install --use-pep517` as a workaround for this problem,
|
||||
or rely on a new virtual environment.
|
||||
|
||||
If the problem refers to a package that is not installed yet,
|
||||
please contact that package's maintainers or distributors.
|
||||
"""
|
||||
if "InvalidVersion" in ex.__class__.__name__:
|
||||
if hasattr(ex, "add_note"):
|
||||
ex.add_note(msg) # PEP 678
|
||||
else:
|
||||
dist.announce(f"\n{msg}\n")
|
||||
raise
|
||||
|
||||
|
||||
def setup(**attrs):
|
||||
logging.configure()
|
||||
# Make sure we have any requirements needed to interpret 'attrs'.
|
||||
_install_setup_requires(attrs)
|
||||
return distutils.core.setup(**attrs)
|
||||
|
||||
|
||||
setup.__doc__ = distutils.core.setup.__doc__
|
||||
|
||||
if TYPE_CHECKING:
|
||||
# Work around a mypy issue where type[T] can't be used as a base: https://github.com/python/mypy/issues/10962
|
||||
from distutils.core import Command as _Command
|
||||
else:
|
||||
_Command = monkey.get_unpatched(distutils.core.Command)
|
||||
|
||||
|
||||
class Command(_Command):
|
||||
"""
|
||||
Setuptools internal actions are organized using a *command design pattern*.
|
||||
This means that each action (or group of closely related actions) executed during
|
||||
the build should be implemented as a ``Command`` subclass.
|
||||
|
||||
These commands are abstractions and do not necessarily correspond to a command that
|
||||
can (or should) be executed via a terminal, in a CLI fashion (although historically
|
||||
they would).
|
||||
|
||||
When creating a new command from scratch, custom defined classes **SHOULD** inherit
|
||||
from ``setuptools.Command`` and implement a few mandatory methods.
|
||||
Between these mandatory methods, are listed:
|
||||
:meth:`initialize_options`, :meth:`finalize_options` and :meth:`run`.
|
||||
|
||||
A useful analogy for command classes is to think of them as subroutines with local
|
||||
variables called "options". The options are "declared" in :meth:`initialize_options`
|
||||
and "defined" (given their final values, aka "finalized") in :meth:`finalize_options`,
|
||||
both of which must be defined by every command class. The "body" of the subroutine,
|
||||
(where it does all the work) is the :meth:`run` method.
|
||||
Between :meth:`initialize_options` and :meth:`finalize_options`, ``setuptools`` may set
|
||||
the values for options/attributes based on user's input (or circumstance),
|
||||
which means that the implementation should be careful to not overwrite values in
|
||||
:meth:`finalize_options` unless necessary.
|
||||
|
||||
Please note that other commands (or other parts of setuptools) may also overwrite
|
||||
the values of the command's options/attributes multiple times during the build
|
||||
process.
|
||||
Therefore it is important to consistently implement :meth:`initialize_options` and
|
||||
:meth:`finalize_options`. For example, all derived attributes (or attributes that
|
||||
depend on the value of other attributes) **SHOULD** be recomputed in
|
||||
:meth:`finalize_options`.
|
||||
|
||||
When overwriting existing commands, custom defined classes **MUST** abide by the
|
||||
same APIs implemented by the original class. They also **SHOULD** inherit from the
|
||||
original class.
|
||||
"""
|
||||
|
||||
command_consumes_arguments = False
|
||||
distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution
|
||||
|
||||
def __init__(self, dist: Distribution, **kw) -> None:
|
||||
"""
|
||||
Construct the command for dist, updating
|
||||
vars(self) with any keyword parameters.
|
||||
"""
|
||||
super().__init__(dist)
|
||||
vars(self).update(kw)
|
||||
|
||||
@overload
|
||||
def reinitialize_command(
|
||||
self, command: str, reinit_subcommands: bool = False, **kw
|
||||
) -> _Command: ...
|
||||
@overload
|
||||
def reinitialize_command(
|
||||
self, command: _CommandT, reinit_subcommands: bool = False, **kw
|
||||
) -> _CommandT: ...
|
||||
def reinitialize_command(
|
||||
self, command: str | _Command, reinit_subcommands: bool = False, **kw
|
||||
) -> _Command:
|
||||
cmd = _Command.reinitialize_command(self, command, reinit_subcommands)
|
||||
vars(cmd).update(kw)
|
||||
return cmd # pyright: ignore[reportReturnType] # pypa/distutils#307
|
||||
|
||||
@abstractmethod
|
||||
def initialize_options(self) -> None:
|
||||
"""
|
||||
Set or (reset) all options/attributes/caches used by the command
|
||||
to their default values. Note that these values may be overwritten during
|
||||
the build.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def finalize_options(self) -> None:
|
||||
"""
|
||||
Set final values for all options/attributes used by the command.
|
||||
Most of the time, each option/attribute/cache should only be set if it does not
|
||||
have any value yet (e.g. ``if self.attr is None: self.attr = val``).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
@abstractmethod
|
||||
def run(self) -> None:
|
||||
"""
|
||||
Execute the actions intended by the command.
|
||||
(Side effects **SHOULD** only take place when :meth:`run` is executed,
|
||||
for example, creating new files or writing to the terminal output).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def _find_all_simple(path):
|
||||
"""
|
||||
Find all files under 'path'
|
||||
"""
|
||||
results = (
|
||||
os.path.join(base, file)
|
||||
for base, dirs, files in os.walk(path, followlinks=True)
|
||||
for file in files
|
||||
)
|
||||
return filter(os.path.isfile, results)
|
||||
|
||||
|
||||
def findall(dir=os.curdir):
|
||||
"""
|
||||
Find all files under 'dir' and return the list of full filenames.
|
||||
Unless dir is '.', return full filenames with dir prepended.
|
||||
"""
|
||||
files = _find_all_simple(dir)
|
||||
if dir == os.curdir:
|
||||
make_rel = functools.partial(os.path.relpath, start=dir)
|
||||
files = map(make_rel, files)
|
||||
return list(files)
|
||||
|
||||
|
||||
class sic(str):
|
||||
"""Treat this string as-is (https://en.wikipedia.org/wiki/Sic)"""
|
||||
|
||||
|
||||
# Apply monkey patches
|
||||
monkey.patch_all()
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,337 @@
|
||||
"""
|
||||
Handling of Core Metadata for Python packages (including reading and writing).
|
||||
|
||||
See: https://packaging.python.org/en/latest/specifications/core-metadata/
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import stat
|
||||
import textwrap
|
||||
from email import message_from_file
|
||||
from email.message import Message
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
from packaging.markers import Marker
|
||||
from packaging.requirements import Requirement
|
||||
from packaging.utils import canonicalize_name, canonicalize_version
|
||||
from packaging.version import Version
|
||||
|
||||
from . import _normalization, _reqs
|
||||
from ._static import is_static
|
||||
from .warnings import SetuptoolsDeprecationWarning
|
||||
|
||||
from distutils.util import rfc822_escape
|
||||
|
||||
|
||||
def get_metadata_version(self):
|
||||
mv = getattr(self, 'metadata_version', None)
|
||||
if mv is None:
|
||||
mv = Version('2.4')
|
||||
self.metadata_version = mv
|
||||
return mv
|
||||
|
||||
|
||||
def rfc822_unescape(content: str) -> str:
|
||||
"""Reverse RFC-822 escaping by removing leading whitespaces from content."""
|
||||
lines = content.splitlines()
|
||||
if len(lines) == 1:
|
||||
return lines[0].lstrip()
|
||||
return '\n'.join((lines[0].lstrip(), textwrap.dedent('\n'.join(lines[1:]))))
|
||||
|
||||
|
||||
def _read_field_from_msg(msg: Message, field: str) -> str | None:
|
||||
"""Read Message header field."""
|
||||
value = msg[field]
|
||||
if value == 'UNKNOWN':
|
||||
return None
|
||||
return value
|
||||
|
||||
|
||||
def _read_field_unescaped_from_msg(msg: Message, field: str) -> str | None:
|
||||
"""Read Message header field and apply rfc822_unescape."""
|
||||
value = _read_field_from_msg(msg, field)
|
||||
if value is None:
|
||||
return value
|
||||
return rfc822_unescape(value)
|
||||
|
||||
|
||||
def _read_list_from_msg(msg: Message, field: str) -> list[str] | None:
|
||||
"""Read Message header field and return all results as list."""
|
||||
values = msg.get_all(field, None)
|
||||
if values == []:
|
||||
return None
|
||||
return values
|
||||
|
||||
|
||||
def _read_payload_from_msg(msg: Message) -> str | None:
|
||||
value = str(msg.get_payload()).strip()
|
||||
if value == 'UNKNOWN' or not value:
|
||||
return None
|
||||
return value
|
||||
|
||||
|
||||
def read_pkg_file(self, file):
|
||||
"""Reads the metadata values from a file object."""
|
||||
msg = message_from_file(file)
|
||||
|
||||
self.metadata_version = Version(msg['metadata-version'])
|
||||
self.name = _read_field_from_msg(msg, 'name')
|
||||
self.version = _read_field_from_msg(msg, 'version')
|
||||
self.description = _read_field_from_msg(msg, 'summary')
|
||||
# we are filling author only.
|
||||
self.author = _read_field_from_msg(msg, 'author')
|
||||
self.maintainer = None
|
||||
self.author_email = _read_field_from_msg(msg, 'author-email')
|
||||
self.maintainer_email = None
|
||||
self.url = _read_field_from_msg(msg, 'home-page')
|
||||
self.download_url = _read_field_from_msg(msg, 'download-url')
|
||||
self.license = _read_field_unescaped_from_msg(msg, 'license')
|
||||
self.license_expression = _read_field_unescaped_from_msg(msg, 'license-expression')
|
||||
|
||||
self.long_description = _read_field_unescaped_from_msg(msg, 'description')
|
||||
if self.long_description is None and self.metadata_version >= Version('2.1'):
|
||||
self.long_description = _read_payload_from_msg(msg)
|
||||
self.description = _read_field_from_msg(msg, 'summary')
|
||||
|
||||
if 'keywords' in msg:
|
||||
self.keywords = _read_field_from_msg(msg, 'keywords').split(',')
|
||||
|
||||
self.platforms = _read_list_from_msg(msg, 'platform')
|
||||
self.classifiers = _read_list_from_msg(msg, 'classifier')
|
||||
|
||||
# PEP 314 - these fields only exist in 1.1
|
||||
if self.metadata_version == Version('1.1'):
|
||||
self.requires = _read_list_from_msg(msg, 'requires')
|
||||
self.provides = _read_list_from_msg(msg, 'provides')
|
||||
self.obsoletes = _read_list_from_msg(msg, 'obsoletes')
|
||||
else:
|
||||
self.requires = None
|
||||
self.provides = None
|
||||
self.obsoletes = None
|
||||
|
||||
self.license_files = _read_list_from_msg(msg, 'license-file')
|
||||
|
||||
|
||||
def single_line(val):
|
||||
"""
|
||||
Quick and dirty validation for Summary pypa/setuptools#1390.
|
||||
"""
|
||||
if '\n' in val:
|
||||
# TODO: Replace with `raise ValueError("newlines not allowed")`
|
||||
# after reviewing #2893.
|
||||
msg = "newlines are not allowed in `summary` and will break in the future"
|
||||
SetuptoolsDeprecationWarning.emit("Invalid config.", msg)
|
||||
# due_date is undefined. Controversial change, there was a lot of push back.
|
||||
val = val.strip().split('\n')[0]
|
||||
return val
|
||||
|
||||
|
||||
def write_pkg_info(self, base_dir):
|
||||
"""Write the PKG-INFO file into the release tree."""
|
||||
temp = ""
|
||||
final = os.path.join(base_dir, 'PKG-INFO')
|
||||
try:
|
||||
# Use a temporary file while writing to avoid race conditions
|
||||
# (e.g. `importlib.metadata` reading `.egg-info/PKG-INFO`):
|
||||
with NamedTemporaryFile("w", encoding="utf-8", dir=base_dir, delete=False) as f:
|
||||
temp = f.name
|
||||
self.write_pkg_file(f)
|
||||
permissions = stat.S_IMODE(os.lstat(temp).st_mode)
|
||||
os.chmod(temp, permissions | stat.S_IRGRP | stat.S_IROTH)
|
||||
os.replace(temp, final) # atomic operation.
|
||||
finally:
|
||||
if temp and os.path.exists(temp):
|
||||
os.remove(temp)
|
||||
|
||||
|
||||
# Based on Python 3.5 version
|
||||
def write_pkg_file(self, file): # noqa: C901 # is too complex (14) # FIXME
|
||||
"""Write the PKG-INFO format data to a file object."""
|
||||
version = self.get_metadata_version()
|
||||
|
||||
def write_field(key, value):
|
||||
file.write(f"{key}: {value}\n")
|
||||
|
||||
write_field('Metadata-Version', str(version))
|
||||
write_field('Name', self.get_name())
|
||||
write_field('Version', self.get_version())
|
||||
|
||||
summary = self.get_description()
|
||||
if summary:
|
||||
write_field('Summary', single_line(summary))
|
||||
|
||||
optional_fields = (
|
||||
('Home-page', 'url'),
|
||||
('Download-URL', 'download_url'),
|
||||
('Author', 'author'),
|
||||
('Author-email', 'author_email'),
|
||||
('Maintainer', 'maintainer'),
|
||||
('Maintainer-email', 'maintainer_email'),
|
||||
)
|
||||
|
||||
for field, attr in optional_fields:
|
||||
attr_val = getattr(self, attr, None)
|
||||
if attr_val is not None:
|
||||
write_field(field, attr_val)
|
||||
|
||||
if license_expression := self.license_expression:
|
||||
write_field('License-Expression', license_expression)
|
||||
elif license := self.get_license():
|
||||
write_field('License', rfc822_escape(license))
|
||||
|
||||
for label, url in self.project_urls.items():
|
||||
write_field('Project-URL', f'{label}, {url}')
|
||||
|
||||
keywords = ','.join(self.get_keywords())
|
||||
if keywords:
|
||||
write_field('Keywords', keywords)
|
||||
|
||||
platforms = self.get_platforms() or []
|
||||
for platform in platforms:
|
||||
write_field('Platform', platform)
|
||||
|
||||
self._write_list(file, 'Classifier', self.get_classifiers())
|
||||
|
||||
# PEP 314
|
||||
self._write_list(file, 'Requires', self.get_requires())
|
||||
self._write_list(file, 'Provides', self.get_provides())
|
||||
self._write_list(file, 'Obsoletes', self.get_obsoletes())
|
||||
|
||||
# Setuptools specific for PEP 345
|
||||
if hasattr(self, 'python_requires'):
|
||||
write_field('Requires-Python', self.python_requires)
|
||||
|
||||
# PEP 566
|
||||
if self.long_description_content_type:
|
||||
write_field('Description-Content-Type', self.long_description_content_type)
|
||||
|
||||
safe_license_files = map(_safe_license_file, self.license_files or [])
|
||||
self._write_list(file, 'License-File', safe_license_files)
|
||||
_write_requirements(self, file)
|
||||
|
||||
for field, attr in _POSSIBLE_DYNAMIC_FIELDS.items():
|
||||
if (val := getattr(self, attr, None)) and not is_static(val):
|
||||
write_field('Dynamic', field)
|
||||
|
||||
long_description = self.get_long_description()
|
||||
if long_description:
|
||||
file.write(f"\n{long_description}")
|
||||
if not long_description.endswith("\n"):
|
||||
file.write("\n")
|
||||
|
||||
|
||||
def _write_requirements(self, file):
|
||||
for req in _reqs.parse(self.install_requires):
|
||||
file.write(f"Requires-Dist: {req}\n")
|
||||
|
||||
processed_extras = {}
|
||||
for augmented_extra, reqs in self.extras_require.items():
|
||||
# Historically, setuptools allows "augmented extras": `<extra>:<condition>`
|
||||
unsafe_extra, _, condition = augmented_extra.partition(":")
|
||||
unsafe_extra = unsafe_extra.strip()
|
||||
extra = _normalization.safe_extra(unsafe_extra)
|
||||
|
||||
if extra:
|
||||
_write_provides_extra(file, processed_extras, extra, unsafe_extra)
|
||||
for req in _reqs.parse_strings(reqs):
|
||||
r = _include_extra(req, extra, condition.strip())
|
||||
file.write(f"Requires-Dist: {r}\n")
|
||||
|
||||
return processed_extras
|
||||
|
||||
|
||||
def _include_extra(req: str, extra: str, condition: str) -> Requirement:
|
||||
r = Requirement(req) # create a fresh object that can be modified
|
||||
parts = (
|
||||
f"({r.marker})" if r.marker else None,
|
||||
f"({condition})" if condition else None,
|
||||
f"extra == {extra!r}" if extra else None,
|
||||
)
|
||||
r.marker = Marker(" and ".join(x for x in parts if x))
|
||||
return r
|
||||
|
||||
|
||||
def _write_provides_extra(file, processed_extras, safe, unsafe):
|
||||
previous = processed_extras.get(safe)
|
||||
if previous == unsafe:
|
||||
SetuptoolsDeprecationWarning.emit(
|
||||
'Ambiguity during "extra" normalization for dependencies.',
|
||||
f"""
|
||||
{previous!r} and {unsafe!r} normalize to the same value:\n
|
||||
{safe!r}\n
|
||||
In future versions, setuptools might halt the build process.
|
||||
""",
|
||||
see_url="https://peps.python.org/pep-0685/",
|
||||
)
|
||||
else:
|
||||
processed_extras[safe] = unsafe
|
||||
file.write(f"Provides-Extra: {safe}\n")
|
||||
|
||||
|
||||
# from pypa/distutils#244; needed only until that logic is always available
|
||||
def get_fullname(self):
|
||||
return _distribution_fullname(self.get_name(), self.get_version())
|
||||
|
||||
|
||||
def _distribution_fullname(name: str, version: str) -> str:
|
||||
"""
|
||||
>>> _distribution_fullname('setup.tools', '1.0-2')
|
||||
'setup_tools-1.0.post2'
|
||||
>>> _distribution_fullname('setup-tools', '1.2post2')
|
||||
'setup_tools-1.2.post2'
|
||||
>>> _distribution_fullname('setup-tools', '1.0-r2')
|
||||
'setup_tools-1.0.post2'
|
||||
>>> _distribution_fullname('setup.tools', '1.0.post')
|
||||
'setup_tools-1.0.post0'
|
||||
>>> _distribution_fullname('setup.tools', '1.0+ubuntu-1')
|
||||
'setup_tools-1.0+ubuntu.1'
|
||||
"""
|
||||
return "{}-{}".format(
|
||||
canonicalize_name(name).replace('-', '_'),
|
||||
canonicalize_version(version, strip_trailing_zero=False),
|
||||
)
|
||||
|
||||
|
||||
def _safe_license_file(file):
|
||||
# XXX: Do we need this after the deprecation discussed in #4892, #4896??
|
||||
normalized = os.path.normpath(file).replace(os.sep, "/")
|
||||
if "../" in normalized:
|
||||
return os.path.basename(normalized) # Temporarily restore pre PEP639 behaviour
|
||||
return normalized
|
||||
|
||||
|
||||
_POSSIBLE_DYNAMIC_FIELDS = {
|
||||
# Core Metadata Field x related Distribution attribute
|
||||
"author": "author",
|
||||
"author-email": "author_email",
|
||||
"classifier": "classifiers",
|
||||
"description": "long_description",
|
||||
"description-content-type": "long_description_content_type",
|
||||
"download-url": "download_url",
|
||||
"home-page": "url",
|
||||
"keywords": "keywords",
|
||||
"license": "license",
|
||||
# XXX: License-File is complicated because the user gives globs that are expanded
|
||||
# during the build. Without special handling it is likely always
|
||||
# marked as Dynamic, which is an acceptable outcome according to:
|
||||
# https://github.com/pypa/setuptools/issues/4629#issuecomment-2331233677
|
||||
"license-file": "license_files",
|
||||
"license-expression": "license_expression", # PEP 639
|
||||
"maintainer": "maintainer",
|
||||
"maintainer-email": "maintainer_email",
|
||||
"obsoletes": "obsoletes",
|
||||
# "obsoletes-dist": "obsoletes_dist", # NOT USED
|
||||
"platform": "platforms",
|
||||
"project-url": "project_urls",
|
||||
"provides": "provides",
|
||||
# "provides-dist": "provides_dist", # NOT USED
|
||||
"provides-extra": "extras_require",
|
||||
"requires": "requires",
|
||||
"requires-dist": "install_requires",
|
||||
# "requires-external": "requires_external", # NOT USED
|
||||
"requires-python": "python_requires",
|
||||
"summary": "description",
|
||||
# "supported-platform": "supported_platforms", # NOT USED
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
import functools
|
||||
import operator
|
||||
|
||||
import packaging.requirements
|
||||
|
||||
|
||||
# from coherent.build.discovery
|
||||
def extras_from_dep(dep):
|
||||
try:
|
||||
markers = packaging.requirements.Requirement(dep).marker._markers
|
||||
except AttributeError:
|
||||
markers = ()
|
||||
return set(
|
||||
marker[2].value
|
||||
for marker in markers
|
||||
if isinstance(marker, tuple) and marker[0].value == 'extra'
|
||||
)
|
||||
|
||||
|
||||
def extras_from_deps(deps):
|
||||
"""
|
||||
>>> extras_from_deps(['requests'])
|
||||
set()
|
||||
>>> extras_from_deps(['pytest; extra == "test"'])
|
||||
{'test'}
|
||||
>>> sorted(extras_from_deps([
|
||||
... 'requests',
|
||||
... 'pytest; extra == "test"',
|
||||
... 'pytest-cov; extra == "test"',
|
||||
... 'sphinx; extra=="doc"']))
|
||||
['doc', 'test']
|
||||
"""
|
||||
return functools.reduce(operator.or_, map(extras_from_dep, deps), set())
|
@@ -0,0 +1,14 @@
|
||||
import importlib
|
||||
import sys
|
||||
|
||||
__version__, _, _ = sys.version.partition(' ')
|
||||
|
||||
|
||||
try:
|
||||
# Allow Debian and pkgsrc (only) to customize system
|
||||
# behavior. Ref pypa/distutils#2 and pypa/distutils#16.
|
||||
# This hook is deprecated and no other environments
|
||||
# should use it.
|
||||
importlib.import_module('_distutils_system_mod')
|
||||
except ImportError:
|
||||
pass
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user