diff --git a/uno/.gitrepo b/uno/.gitrepo index f3bec285..d04a1074 100644 --- a/uno/.gitrepo +++ b/uno/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/prrvchr/uno.git branch = main - commit = 329d17790433add56bc56bb30bb4c0b8a7fae0ae - parent = 509ba9ed9fd424d5aa374ff0b69bbff65f3a7c38 + commit = 3b8ab224b181540e1c06dfdaf6bde35455374759 + parent = 5314a054f9e48f4801dffdc4bbd260d4ced40f38 method = merge cmdver = 0.4.3 diff --git a/uno/lib/python/_distutils_hack/__init__.py b/uno/lib/python/_distutils_hack/__init__.py index 35ab5cad..b05d04e9 100644 --- a/uno/lib/python/_distutils_hack/__init__.py +++ b/uno/lib/python/_distutils_hack/__init__.py @@ -1,7 +1,6 @@ # don't import any costly modules -import sys import os - +import sys report_url = ( "https://github.com/pypa/setuptools/issues/new?" diff --git a/uno/lib/python/pkg_resources/__init__.py b/uno/lib/python/pkg_resources/__init__.py index 3c88d8d3..76aa5e77 100644 --- a/uno/lib/python/pkg_resources/__init__.py +++ b/uno/lib/python/pkg_resources/__init__.py @@ -27,62 +27,60 @@ if sys.version_info < (3, 8): # noqa: UP036 # Check for unsupported versions raise RuntimeError("Python 3.8 or later is required") -import os +import _imp +import collections +import email.parser +import errno +import functools +import importlib +import importlib.abc +import importlib.machinery +import inspect import io -import time +import ntpath +import operator +import os +import pkgutil +import platform +import plistlib +import posixpath import re +import stat +import tempfile +import textwrap +import time import types +import warnings +import zipfile +import zipimport +from pkgutil import get_importer from typing import ( + TYPE_CHECKING, Any, BinaryIO, - Literal, + Callable, Dict, + Iterable, Iterator, + Literal, Mapping, MutableSequence, NamedTuple, NoReturn, - Tuple, - Union, - TYPE_CHECKING, Protocol, - Callable, - Iterable, + Tuple, TypeVar, + Union, overload, ) -import zipfile -import zipimport -import warnings -import stat -import functools -import pkgutil -import operator -import platform -import collections -import plistlib -import email.parser -import errno -import tempfile -import textwrap -import inspect -import ntpath -import posixpath -import importlib -import importlib.abc -import importlib.machinery -from pkgutil import get_importer - -import _imp 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) # capture these to bypass sandboxing -from os import utime -from os import open as os_open -from os.path import isdir, split +from os import open as os_open, utime # isort: skip +from os.path import isdir, split # isort: skip try: from os import mkdir, rename, unlink @@ -92,21 +90,17 @@ # no write support, probably under GAE WRITE_SUPPORT = False +import packaging.markers +import packaging.requirements import packaging.specifiers -from jaraco.text import ( - yield_lines, - drop_comment, - join_continuation, -) -from packaging import markers as _packaging_markers -from packaging import requirements as _packaging_requirements -from packaging import utils as _packaging_utils -from packaging import version as _packaging_version +import packaging.utils +import packaging.version +from jaraco.text import drop_comment, join_continuation, yield_lines from platformdirs import user_cache_dir as _user_cache_dir if TYPE_CHECKING: - from _typeshed import BytesPath, StrPath, StrOrBytesPath - from typing_extensions import Self + from _typeshed import BytesPath, StrOrBytesPath, StrPath + from typing_extensions import Self, TypeAlias warnings.warn( "pkg_resources is deprecated as an API. " @@ -118,20 +112,20 @@ _T = TypeVar("_T") _DistributionT = TypeVar("_DistributionT", bound="Distribution") # Type aliases -_NestedStr = Union[str, Iterable[Union[str, Iterable["_NestedStr"]]]] -_InstallerTypeT = Callable[["Requirement"], "_DistributionT"] -_InstallerType = Callable[["Requirement"], Union["Distribution", None]] -_PkgReqType = Union[str, "Requirement"] -_EPDistType = Union["Distribution", _PkgReqType] -_MetadataType = Union["IResourceProvider", None] -_ResolvedEntryPoint = Any # Can be any attribute in the module -_ResourceStream = Any # TODO / Incomplete: A readable file-like object +_NestedStr: TypeAlias = Union[str, Iterable[Union[str, Iterable["_NestedStr"]]]] +_StrictInstallerType: TypeAlias = Callable[["Requirement"], "_DistributionT"] +_InstallerType: TypeAlias = Callable[["Requirement"], Union["Distribution", None]] +_PkgReqType: TypeAlias = Union[str, "Requirement"] +_EPDistType: TypeAlias = Union["Distribution", _PkgReqType] +_MetadataType: TypeAlias = Union["IResourceProvider", None] +_ResolvedEntryPoint: TypeAlias = Any # Can be any attribute in the module +_ResourceStream: TypeAlias = Any # TODO / Incomplete: A readable file-like object # Any object works, but let's indicate we expect something like a module (optionally has __loader__ or __file__) -_ModuleLike = Union[object, types.ModuleType] +_ModuleLike: TypeAlias = Union[object, types.ModuleType] # Any: Should be _ModuleLike but we end up with issues where _ModuleLike doesn't have _ZipLoaderModule's __loader__ -_ProviderFactoryType = Callable[[Any], "IResourceProvider"] -_DistFinderType = Callable[[_T, str, bool], Iterable["Distribution"]] -_NSHandlerType = Callable[[_T, str, str, types.ModuleType], Union[str, None]] +_ProviderFactoryType: TypeAlias = Callable[[Any], "IResourceProvider"] +_DistFinderType: TypeAlias = Callable[[_T, str, bool], Iterable["Distribution"]] +_NSHandlerType: TypeAlias = Callable[[_T, str, str, types.ModuleType], Union[str, None]] _AdapterT = TypeVar( "_AdapterT", _DistFinderType[Any], _ProviderFactoryType, _NSHandlerType[Any] ) @@ -156,7 +150,7 @@ class PEP440Warning(RuntimeWarning): """ -parse_version = _packaging_version.Version +parse_version = packaging.version.Version _state_vars: dict[str, str] = {} @@ -801,7 +795,7 @@ def add( return self.by_key[dist.key] = dist - normalized_name = _packaging_utils.canonicalize_name(dist.key) + normalized_name = packaging.utils.canonicalize_name(dist.key) self.normalized_to_canonical_keys[normalized_name] = dist.key if dist.key not in keys: keys.append(dist.key) @@ -814,7 +808,7 @@ def resolve( self, requirements: Iterable[Requirement], env: Environment | None, - installer: _InstallerTypeT[_DistributionT], + installer: _StrictInstallerType[_DistributionT], replace_conflicting: bool = False, extras: tuple[str, ...] | None = None, ) -> list[_DistributionT]: ... @@ -824,7 +818,7 @@ def resolve( requirements: Iterable[Requirement], env: Environment | None = None, *, - installer: _InstallerTypeT[_DistributionT], + installer: _StrictInstallerType[_DistributionT], replace_conflicting: bool = False, extras: tuple[str, ...] | None = None, ) -> list[_DistributionT]: ... @@ -841,7 +835,7 @@ def resolve( self, requirements: Iterable[Requirement], env: Environment | None = None, - installer: _InstallerType | None | _InstallerTypeT[_DistributionT] = None, + installer: _InstallerType | None | _StrictInstallerType[_DistributionT] = None, replace_conflicting: bool = False, extras: tuple[str, ...] | None = None, ) -> list[Distribution] | list[_DistributionT]: @@ -947,7 +941,7 @@ def find_plugins( self, plugin_env: Environment, full_env: Environment | None, - installer: _InstallerTypeT[_DistributionT], + installer: _StrictInstallerType[_DistributionT], fallback: bool = True, ) -> tuple[list[_DistributionT], dict[Distribution, Exception]]: ... @overload @@ -956,7 +950,7 @@ def find_plugins( plugin_env: Environment, full_env: Environment | None = None, *, - installer: _InstallerTypeT[_DistributionT], + installer: _StrictInstallerType[_DistributionT], fallback: bool = True, ) -> tuple[list[_DistributionT], dict[Distribution, Exception]]: ... @overload @@ -971,7 +965,7 @@ def find_plugins( self, plugin_env: Environment, full_env: Environment | None = None, - installer: _InstallerType | None | _InstallerTypeT[_DistributionT] = None, + installer: _InstallerType | None | _StrictInstallerType[_DistributionT] = None, fallback: bool = True, ) -> tuple[ list[Distribution] | list[_DistributionT], @@ -1217,7 +1211,7 @@ def best_match( self, req: Requirement, working_set: WorkingSet, - installer: _InstallerTypeT[_DistributionT], + installer: _StrictInstallerType[_DistributionT], replace_conflicting: bool = False, ) -> _DistributionT: ... @overload @@ -1232,7 +1226,7 @@ def best_match( self, req: Requirement, working_set: WorkingSet, - installer: _InstallerType | None | _InstallerTypeT[_DistributionT] = None, + installer: _InstallerType | None | _StrictInstallerType[_DistributionT] = None, replace_conflicting: bool = False, ) -> Distribution | None: """Find distribution best matching `req` and usable on `working_set` @@ -1265,7 +1259,7 @@ def best_match( def obtain( self, requirement: Requirement, - installer: _InstallerTypeT[_DistributionT], + installer: _StrictInstallerType[_DistributionT], ) -> _DistributionT: ... @overload def obtain( @@ -1285,7 +1279,7 @@ def obtain( installer: Callable[[Requirement], None] | _InstallerType | None - | _InstallerTypeT[_DistributionT] = None, + | _StrictInstallerType[_DistributionT] = None, ) -> Distribution | None: """Obtain a distribution matching `requirement` (e.g. via download) @@ -1561,8 +1555,8 @@ def safe_version(version: str) -> str: """ try: # normalize the version - return str(_packaging_version.Version(version)) - except _packaging_version.InvalidVersion: + return str(packaging.version.Version(version)) + except packaging.version.InvalidVersion: version = version.replace(' ', '.') return re.sub('[^A-Za-z0-9.]+', '-', version) @@ -1639,9 +1633,9 @@ def evaluate_marker(text: str, extra: str | None = None) -> bool: This implementation uses the 'pyparsing' module. """ try: - marker = _packaging_markers.Marker(text) + marker = packaging.markers.Marker(text) return marker.evaluate() - except _packaging_markers.InvalidMarker as e: + except packaging.markers.InvalidMarker as e: raise SyntaxError(e) from e @@ -3001,12 +2995,12 @@ def parsed_version(self): if not hasattr(self, "_parsed_version"): try: self._parsed_version = parse_version(self.version) - except _packaging_version.InvalidVersion as ex: + except packaging.version.InvalidVersion as ex: info = f"(package: {self.project_name})" if hasattr(ex, "add_note"): ex.add_note(info) # PEP 678 raise - raise _packaging_version.InvalidVersion(f"{str(ex)} {info}") from None + raise packaging.version.InvalidVersion(f"{str(ex)} {info}") from None return self._parsed_version @@ -3014,7 +3008,7 @@ def parsed_version(self): def _forgiving_parsed_version(self): try: return self.parsed_version - except _packaging_version.InvalidVersion as ex: + except packaging.version.InvalidVersion as ex: self._parsed_version = parse_version(_forgiving_version(self.version)) notes = "\n".join(getattr(ex, "__notes__", [])) # PEP 678 @@ -3194,7 +3188,7 @@ def from_filename( def as_requirement(self): """Return a ``Requirement`` that matches this distribution exactly""" - if isinstance(self.parsed_version, _packaging_version.Version): + if isinstance(self.parsed_version, packaging.version.Version): spec = "%s==%s" % (self.project_name, self.parsed_version) else: spec = "%s===%s" % (self.project_name, self.parsed_version) @@ -3452,11 +3446,11 @@ def parse_requirements(strs: _NestedStr) -> map[Requirement]: return map(Requirement, join_continuation(map(drop_comment, yield_lines(strs)))) -class RequirementParseError(_packaging_requirements.InvalidRequirement): +class RequirementParseError(packaging.requirements.InvalidRequirement): "Compatibility wrapper for InvalidRequirement" -class Requirement(_packaging_requirements.Requirement): +class Requirement(packaging.requirements.Requirement): # prefer variable length tuple to set (as found in # packaging.requirements.Requirement) extras: tuple[str, ...] # type: ignore[assignment] diff --git a/uno/lib/python/pkg_resources/tests/test_find_distributions.py b/uno/lib/python/pkg_resources/tests/test_find_distributions.py index 8263ca6c..301b36d6 100644 --- a/uno/lib/python/pkg_resources/tests/test_find_distributions.py +++ b/uno/lib/python/pkg_resources/tests/test_find_distributions.py @@ -1,8 +1,9 @@ -from pathlib import Path import shutil +from pathlib import Path + import pytest -import pkg_resources +import pkg_resources TESTS_DATA_DIR = Path(__file__).parent / 'data' diff --git a/uno/lib/python/pkg_resources/tests/test_pkg_resources.py b/uno/lib/python/pkg_resources/tests/test_pkg_resources.py index 424d5ac4..023adf60 100644 --- a/uno/lib/python/pkg_resources/tests/test_pkg_resources.py +++ b/uno/lib/python/pkg_resources/tests/test_pkg_resources.py @@ -1,28 +1,23 @@ from __future__ import annotations import builtins -import sys -import tempfile -import os -import zipfile import datetime +import os import plistlib -import subprocess import stat -import distutils.dist -import distutils.command.install_egg_info - +import subprocess +import sys +import tempfile +import zipfile from unittest import mock -from pkg_resources import ( - DistInfoDistribution, - Distribution, - EggInfoDistribution, -) - import pytest import pkg_resources +from pkg_resources import DistInfoDistribution, Distribution, EggInfoDistribution + +import distutils.command.install_egg_info +import distutils.dist class EggRemover(str): diff --git a/uno/lib/python/pkg_resources/tests/test_resources.py b/uno/lib/python/pkg_resources/tests/test_resources.py index 9837c271..3b672969 100644 --- a/uno/lib/python/pkg_resources/tests/test_resources.py +++ b/uno/lib/python/pkg_resources/tests/test_resources.py @@ -1,23 +1,23 @@ +import itertools import os -import sys -import string import platform -import itertools +import string +import sys import pytest from packaging.specifiers import SpecifierSet import pkg_resources from pkg_resources import ( - parse_requirements, - VersionConflict, - parse_version, Distribution, EntryPoint, Requirement, - safe_version, - safe_name, + VersionConflict, WorkingSet, + parse_requirements, + parse_version, + safe_name, + safe_version, ) @@ -862,8 +862,8 @@ def test_path_order(self, symlinked_tmpdir): (subpkg / '__init__.py').write_text(vers_str % number, encoding='utf-8') with pytest.warns(DeprecationWarning, match="pkg_resources.declare_namespace"): - import nspkg.subpkg import nspkg + import nspkg.subpkg expected = [str(site.realpath() / 'nspkg') for site in site_dirs] assert nspkg.__path__ == expected assert nspkg.subpkg.__version__ == 1 diff --git a/uno/lib/python/pkg_resources/tests/test_working_set.py b/uno/lib/python/pkg_resources/tests/test_working_set.py index 57f62b54..0537bb69 100644 --- a/uno/lib/python/pkg_resources/tests/test_working_set.py +++ b/uno/lib/python/pkg_resources/tests/test_working_set.py @@ -1,7 +1,7 @@ +import functools import inspect import re import textwrap -import functools import pytest diff --git a/uno/lib/python/setuptools-72.1.0.dist-info/LICENSE b/uno/lib/python/setuptools-73.0.1.dist-info/LICENSE similarity index 100% rename from uno/lib/python/setuptools-72.1.0.dist-info/LICENSE rename to uno/lib/python/setuptools-73.0.1.dist-info/LICENSE diff --git a/uno/lib/python/setuptools-72.1.0.dist-info/METADATA b/uno/lib/python/setuptools-73.0.1.dist-info/METADATA similarity index 98% rename from uno/lib/python/setuptools-72.1.0.dist-info/METADATA rename to uno/lib/python/setuptools-73.0.1.dist-info/METADATA index b05eed6d..68e280c6 100644 --- a/uno/lib/python/setuptools-72.1.0.dist-info/METADATA +++ b/uno/lib/python/setuptools-73.0.1.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: setuptools -Version: 72.1.0 +Version: 73.0.1 Summary: Easily download, build, install, upgrade, and uninstall Python packages Author-email: Python Packaging Authority Project-URL: Source, https://github.com/pypa/setuptools @@ -22,7 +22,6 @@ License-File: LICENSE Provides-Extra: certs Provides-Extra: core Requires-Dist: packaging >=24 ; extra == 'core' -Requires-Dist: ordered-set >=3.1.1 ; extra == 'core' Requires-Dist: more-itertools >=8.8 ; extra == 'core' Requires-Dist: jaraco.text >=3.7 ; extra == 'core' Requires-Dist: wheel >=0.43.0 ; extra == 'core' @@ -44,6 +43,7 @@ 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: test Requires-Dist: pytest !=8.1.*,>=6 ; extra == 'test' @@ -52,7 +52,7 @@ Requires-Dist: pytest-cov ; extra == 'test' Requires-Dist: pytest-mypy ; extra == 'test' Requires-Dist: pytest-enabler >=2.2 ; extra == 'test' Requires-Dist: virtualenv >=13.0.0 ; extra == 'test' -Requires-Dist: wheel ; extra == 'test' +Requires-Dist: wheel >=0.44.0 ; extra == 'test' Requires-Dist: pip >=19.1 ; extra == 'test' Requires-Dist: packaging >=23.2 ; extra == 'test' Requires-Dist: jaraco.envs >=2.2 ; extra == 'test' diff --git a/uno/lib/python/setuptools-72.1.0.dist-info/RECORD b/uno/lib/python/setuptools-73.0.1.dist-info/RECORD similarity index 75% rename from uno/lib/python/setuptools-72.1.0.dist-info/RECORD rename to uno/lib/python/setuptools-73.0.1.dist-info/RECORD index 613083f9..284a337c 100644 --- a/uno/lib/python/setuptools-72.1.0.dist-info/RECORD +++ b/uno/lib/python/setuptools-73.0.1.dist-info/RECORD @@ -1,16 +1,16 @@ distutils-precedence.pth,sha256=JjjOniUA5XKl4N5_rtZmHrVp0baW_LoHsN0iPaX10iQ,151 -_distutils_hack/__init__.py,sha256=FULjC20HFW9EerS8rsSjozD-uTFn1dyvVI9tayzbhSw,6715 +_distutils_hack/__init__.py,sha256=m3N8LMzi2tLolqz7YoXHCEGRIQeMACMaVDmnZHzdcuQ,6714 _distutils_hack/override.py,sha256=Eu_s-NF6VIZ4Cqd0tbbA5wtWky2IZPNd8et6GLt1mzo,44 -pkg_resources/__init__.py,sha256=qByZdJ3gxx4K0oufeWaa8zs2jvVjrVWDPuxUCad-qWk,125561 +pkg_resources/__init__.py,sha256=8ib9YwdjdeZ0k-vbAPwF5y0GZ5d9zNTw9HeTHgCerjo,125634 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/test_find_distributions.py,sha256=dF1Epm9g6czEmkVDTs6p9PGPotyG0y3vI7QJy4M0aUs,1971 +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=MucZUjJspUVbRV96TKL_OrLrr6me4RBwVjXB2PZfuIY,15029 -pkg_resources/tests/test_resources.py,sha256=qzrksI8ej0-GwlcWuIWIoea1EyzXYJtMGBRpXCQGhsQ,30972 -pkg_resources/tests/test_working_set.py,sha256=2QGLQZCo3-xWgSpOrmGryTFAZ6ilFXZCxIk5ZvCwmsE,8531 +pkg_resources/tests/test_pkg_resources.py,sha256=axfvXPX20QI_ntVQUz8fBzzmj2Z-QxlKvRlPjNKXhnM,15011 +pkg_resources/tests/test_resources.py,sha256=DuDLOi0i7lkwvCP9czHLuPkAj_1JvQ7VJu0GltG22KM,30972 +pkg_resources/tests/test_working_set.py,sha256=v3lf3NSsGGNwKJFZY7y1C5_cp-dnXsoxBuSxe1Rwk78,8531 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 @@ -20,79 +20,79 @@ pkg_resources/tests/data/my-test-package_unpacked-egg/my_test_package-1.0-py3.7. 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 -setuptools/__init__.py,sha256=mXyYHiwEBKUk4KGzFsdIUVHbdJSpHYyByo-GL8xcJX8,9183 -setuptools/_core_metadata.py,sha256=GAZTfUBCN5ccXT791Z1dQ_HnalAmJROtizE5W-uONHM,9794 -setuptools/_entry_points.py,sha256=rULqJUpOGivhOzSCKjWHCgAQ1SqnVF5jxttaLXSLai4,2309 -setuptools/_imp.py,sha256=as9Lnjl7cZHSD2SE1ShiSOK9kP7oy0MBps_MD832sFw,2443 -setuptools/_importlib.py,sha256=m6-DRZm7CGzskrN9FBnzk_5DLhbz5J13Npbou9b2bwk,328 +setuptools/__init__.py,sha256=xFHPI93oU3aCRxN54z_uX0MYo4tw23JNfNGrCYZVUoU,9988 +setuptools/_core_metadata.py,sha256=7xeUsLocaSZQlgRQ81-HVRMWUWFXMyFJpVyjCDJgXS0,9795 +setuptools/_entry_points.py,sha256=Y3QUE9JKFW_YyquDnpffNWSs6f3jKEt1e-dnx--9-Kw,2310 +setuptools/_imp.py,sha256=b5sEz-EOJKApMsmb-yJPPgkGqZBeZFeLtoWhysLre-0,2441 +setuptools/_importlib.py,sha256=rrebj_YuvTeVM-A3gFJMp8lRgSAmD2fA-NPXVsxzt5w,327 setuptools/_itertools.py,sha256=jWRfsIrpC7myooz3hDURj9GtvpswZeKXg2HakmEhNjo,657 setuptools/_normalization.py,sha256=t-SeXc0jU2weQY9BA3qGlRThzBND1oYK5Hpzg1_533g,4536 -setuptools/_path.py,sha256=kT1Ebtb267LcnNPQKl6dgY9DASdsiK3zyTZyY_e2L5Y,2564 -setuptools/_reqs.py,sha256=X00y1BCHtoKrKPxDvU8z_HCr_ee1avBF2-yD77aef6k,1076 -setuptools/archive_util.py,sha256=lRK7l7GkpLJeNqnESJWUfDre4q4wR9x6Z8WD3cIagXc,7331 -setuptools/build_meta.py,sha256=uSejNun9NOavDq6h-G04G9VrVMZSM5mVoTCrBxVGPws,19085 +setuptools/_path.py,sha256=cjrnds-WCfAgBYPHh2FsnZF294pcKQnJiVa7VnqA4_I,2700 +setuptools/_reqs.py,sha256=28m-PB3CB-RGoir1989VRUrsaff9FTB5Lqy2CkFe7ws,1201 +setuptools/archive_util.py,sha256=8C7X1KZXphqLkVpZdgme8bm2U9CPQ3tmnxpWMpbH0mM,7332 +setuptools/build_meta.py,sha256=nIE9Q3gA5Uc6KgHWPmxSoYdpEw-KDVGEueORjTrTid0,19169 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/depends.py,sha256=1qkpuCWfs6-f76K3LxkZ6b5BLvl32ZnhUv5FrxuL9ME,5543 -setuptools/discovery.py,sha256=8ZxnrjbbY68LF0TtsZA0F3YTyk6uCX-STt3USDwsR3U,21124 -setuptools/dist.py,sha256=3D5XYKAJEfUVpHlSwemqP68WdzmnP_743tMJkVZs5sc,36562 -setuptools/errors.py,sha256=FS-3MTIzgv7ciswOrK71KMuEUcYh9kkWUYXd895Gbew,2669 -setuptools/extension.py,sha256=uOCt-FHrzKTZxzd4MLSIfPV3cT_9uPJiL3q_Z4r14ho,5794 -setuptools/glob.py,sha256=BYhyV7s5INjv-JMsz4SNuQWGTzY4lZVLD5_euTYsFxc,4852 +setuptools/depends.py,sha256=IsPdLBE6XpptUyp8WtihOD8O-PBnr2RezeiKBFT5Stc,5542 +setuptools/discovery.py,sha256=kEBc8vqi1Zq8kIGH80q0Q_xp4fFdHabQQM2EGg2eGY0,21104 +setuptools/dist.py,sha256=P0uyYmIKtISAVGvd6pz1v5ExGcz4mWHPXGLnvqnJuzw,36673 +setuptools/errors.py,sha256=evIv0G0hsXR7XiczaycfOjMhmN1AqUpSePhlPKX6d34,2668 +setuptools/extension.py,sha256=6lOZpKueecpGv50GhZIe0RkCpQne4z93t62FahwhBUk,6399 +setuptools/glob.py,sha256=iMCy0lhirF29sz2fa9B6KVGVvUniy11SFpdLl1UCb-I,4852 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=2U2xHSbylwS8lxyy6PvLpSJGmKaiDzN3SjTB-e0oL4I,4969 -setuptools/launch.py,sha256=TyPT-Ic1T2EnYvGO26gfNRP4ysBlrhpbRjQxWsiO414,812 -setuptools/logging.py,sha256=JA7DVtLlC3gskysgtORtm9-4UWh9kWr9FjbXbdQsIRo,1239 -setuptools/modified.py,sha256=lDbr7ds0ZpxYN8i8b4DmwuGJhDED5QmvQKEd49gZbAY,190 -setuptools/monkey.py,sha256=VsbcIY2Q91n9_QYRrlrwqylxeTC3XBeUjx6koWrRgQk,4333 -setuptools/msvc.py,sha256=IdfYJkZ2chSFrN0DfXq6W24536VjhGadyN_BaLuOUD0,47515 -setuptools/namespaces.py,sha256=PpeN81NZawysr88ApCWgGsvNBcMfHZc1Yw8Pp9jAPek,3128 -setuptools/package_index.py,sha256=QsRnWsY8Zs2y67-DyrdGX_RqrQ1mVh2SYvBbA6x82JI,39064 -setuptools/sandbox.py,sha256=3n5KOFt1d1ljurLKB9E6Nym0CDlbgSkHs0C2v-Yplaw,14730 +setuptools/installer.py,sha256=WF8FZiQXP2rNs_LpX_8C_A8l7sZivn5Xzk9g6lQG2g4,4970 +setuptools/launch.py,sha256=VsYBvZhikv-o_uJc60yM-2_PCQB5P5vSFnLl5C5BJ5A,812 +setuptools/logging.py,sha256=BYKd0bzbiCvUB9XEtfCYaYh9F_QNpxYjRsF2Xmw51k8,1241 +setuptools/modified.py,sha256=GGzc71yEkfwLV1-HqXRwwsnzhnb97k1D3R7H8EE_0z4,190 +setuptools/monkey.py,sha256=Embqr5Rp6Ce8iJUeHBVRLUJVJDqsYU4smXoXCW9D24c,4332 +setuptools/msvc.py,sha256=ysRxMyEhYo-EUDWmJXqbVIEss4qepVNtA9HG0uHtdEM,47516 +setuptools/namespaces.py,sha256=T__C4WtJJsCRgJ86czU4eAvqDJOBCxWt-78k5_RnWVM,3128 +setuptools/package_index.py,sha256=-MGtTaI8QsiOLJxrKhmwikvSWaFyuR1baOIh6UbzwAM,39064 +setuptools/sandbox.py,sha256=knPGmiieNsDFk2B5L2wWf4_Rg5HMjb0Y7G5Qu4E7cHw,14173 setuptools/script (dev).tmpl,sha256=RUzQzCQUaXtwdLtYHWYbIQmOaES5Brqq1FvUA_tu-5I,218 setuptools/script.tmpl,sha256=WGTt5piezO27c-Dbx6l5Q4T3Ff20A5z7872hv3aAhYY,138 -setuptools/unicode_utils.py,sha256=LlYPwQMxTjLr_YTbMrd1qSADh9gGH7DUiwJBIBGQ7GY,3181 +setuptools/unicode_utils.py,sha256=aDvIZZPtMn3eC1cpS4ta0WugZSZ7spoKyxGqZd7AHzw,3181 setuptools/version.py,sha256=WJCeUuyq74Aok2TeK9-OexZOu8XrlQy7-y0BEuWNovQ,161 setuptools/warnings.py,sha256=Xz3eESrYEdP0dYlVerP8BA0es-UbkFRAE4gOnXUmxuI,3714 -setuptools/wheel.py,sha256=9L1nJ05QBR40jTfRhtuYOZpElB0kGuhLgNVf6n8KoVU,8629 -setuptools/windows_support.py,sha256=0qLEFTYEBly5quTV1EciqKwrvS4ZtU4oHWP0Z3-BOYI,720 +setuptools/wheel.py,sha256=w-F8n9qddusDCadC8PWJlkZ5uvlXkaGytQgnkenZGiw,8628 +setuptools/windows_support.py,sha256=wW4IYLM1Bv7Z1MaauP2xmPjyy-wkmQnXdyvXscAf9fw,726 setuptools/_distutils/__init__.py,sha256=xGYuhWwLG07J0Q49BVnEjPy6wyDcd6veJMDJX7ljlyM,359 -setuptools/_distutils/_collections.py,sha256=d7LOPjTlBpUHK7Wrkqo1Trjeo5sJ-ONRKpWIzfUzS0I,5440 +setuptools/_distutils/_collections.py,sha256=jbayD_dCSuJr7YJ63pKAgGbNzrHtnvz0bd-63WDKmDY,1366 setuptools/_distutils/_functools.py,sha256=X0hb3XXNlzU0KNmF1oUO6rMpeAi12wxD5tSJZiXd3Zc,1771 setuptools/_distutils/_itertools.py,sha256=dhBUItrpJTFwXeC-RdfkU_YP8JXRoUl6VluRV2op8kY,1453 setuptools/_distutils/_log.py,sha256=i-lNTTcXS8TmWITJ6DODGvtW5z5tMattJQ76h8rZxQU,42 setuptools/_distutils/_macos_compat.py,sha256=JzUGhF4E5yIITHbUaPobZEWjGHdrrcNV63z86S4RjBc,239 -setuptools/_distutils/_modified.py,sha256=IIq_EfKm5QKtOIWLT3mm_sSPGZTkqFhZuceppFudHmM,2410 +setuptools/_distutils/_modified.py,sha256=D-6zIm54enmSK_9BpoG8vFSuEdaL1rUZ5HS8xxi6TQ0,2440 setuptools/_distutils/_msvccompiler.py,sha256=KtAe0ydUZuISYQhtFwDHM_Bp1w84Vx1I9XPdgh1XUHc,19641 setuptools/_distutils/archive_util.py,sha256=KpEFAoCJUvr2uWtB3QbWXXt1CIH6CU0a8JVONGLfc6U,8551 -setuptools/_distutils/bcppcompiler.py,sha256=UnEoAvmqpTjvgjaOQZ2MKMrAEo5QyIZVL644gqf05lw,14674 -setuptools/_distutils/ccompiler.py,sha256=XtqhQoxIatMnc4jBUj5V0eP9u0bc5zbeDRtkr0Uj3E4,48935 +setuptools/_distutils/bcppcompiler.py,sha256=KOWXKflXxzTNNwR02kf_rrsxhxez9FAnrN88MQEqTHU,14647 +setuptools/_distutils/ccompiler.py,sha256=h3xwcs4Y-OP_uxqqKXPNea9WG6iBy6XZBwEzidgQhOM,48869 setuptools/_distutils/cmd.py,sha256=sZeDnYHuZqykNMOlX4usslxJ4jwPjAXKJvXYu5o7tns,17877 setuptools/_distutils/config.py,sha256=5MRWmllnvszIvl4OXnzmTdOhMHQZ90ci-n7TDp82nJc,5226 setuptools/_distutils/core.py,sha256=0H9EOr1daiLCThjEQLxD1oiRAo1IlGdJgkC7GdO0p5w,9318 -setuptools/_distutils/cygwinccompiler.py,sha256=EjfJ1fdsID-mnZwmonqtlvek1Zk4LZmsi28NCU4SBkc,11954 +setuptools/_distutils/cygwinccompiler.py,sha256=IwUsN38uC-IYzZvx4X9-pgiwqRstvmZ4fYogub8pNdQ,11676 setuptools/_distutils/debug.py,sha256=N6MrTAqK6l9SVk6tWweR108PM8Ol7qNlfyV-nHcLhsY,139 setuptools/_distutils/dep_util.py,sha256=xN75p6ZpHhMiHEc-rpL2XilJQynHnDNiafHteaZ4tjU,349 setuptools/_distutils/dir_util.py,sha256=D2B5iwrxwjhPpp6cmc0gbjTuQz7CCiSYJFi9vK5k82c,8007 -setuptools/_distutils/dist.py,sha256=5iKkKGsGjmxb0HJm-UNfpp-0pJkHWHgl0wlTs1-NjY4,50977 +setuptools/_distutils/dist.py,sha256=alTHPy8l3JCs7BBd_O3rdDWTC2wSzCPEj5Pta-RKO8c,50770 setuptools/_distutils/errors.py,sha256=ZtBwnhDpQA2bxIazPXNDQ25uNxM4p2omsaSRNpV3rpE,3589 -setuptools/_distutils/extension.py,sha256=i7FkjlbsiT6MB49upTcBqmP3t_WL-4sjelH3sWfV6s4,10206 +setuptools/_distutils/extension.py,sha256=i0MEoODqWaZVg74aLJF-9jhmxA82W5hlHJ75ZWUOvv4,10342 setuptools/_distutils/fancy_getopt.py,sha256=FfBKjfzAXOwg1wJIVDBIoTgals9-XLpQdi-YbZS82Jw,17822 setuptools/_distutils/file_util.py,sha256=HA16zlO-FTPXoo4eo8xzkv57IOcelHpAAr8eonCJsVU,7944 setuptools/_distutils/filelist.py,sha256=PjeVfpvvjY00sOwofd4d79EUjmI_c7udePCL6REbYzM,13654 setuptools/_distutils/log.py,sha256=VyBs5j7z4-K6XTEEBThUc9HyMpoPLGtQpERqbz5ylww,1200 -setuptools/_distutils/msvc9compiler.py,sha256=sBCSRZ3uhfUpBRDi7CH0j7o5xtEJ_XrXMXkTlEejDeU,30129 -setuptools/_distutils/msvccompiler.py,sha256=uz7sAiZKN_8zmIN3Db1ar-ggf4ahwZBnz73oTvJWIP0,23451 -setuptools/_distutils/spawn.py,sha256=W8ooTzSH6C4rtcGWRbILRt6KshH-fDvEAv7740L12BY,3626 -setuptools/_distutils/sysconfig.py,sha256=L9QY1FTEeOTZymnStiKMe1exFiODiy5z_WN54azfZFk,18747 +setuptools/_distutils/msvc9compiler.py,sha256=ftD8A7UjszHuwJb8HLjKUZO9_uszOFXqB_cwst7er-8,30079 +setuptools/_distutils/msvccompiler.py,sha256=XmlP5bxLVdQxc3An3WiKBOpJICWDN8TkykT_9y0x7_Y,23401 +setuptools/_distutils/spawn.py,sha256=u5srFcVoBxOweFlWtZRjO9L__tRcOQvLH8DAel5kZSg,3625 +setuptools/_distutils/sysconfig.py,sha256=7QkLODF-NcCPkWkvPeMNwaqBzAGCt-uM4x3P4UfH3es,19221 setuptools/_distutils/text_file.py,sha256=EV8hDCetYeKq6c_uPfwGgkUw8hugeEoSJcXpy_EkQGo,12098 -setuptools/_distutils/unixccompiler.py,sha256=g6bXe7nNkrwgOz6_TglaMgjlg0UPhHVxI34DDTKeaOs,15698 -setuptools/_distutils/util.py,sha256=wW9xrzJGihNfrxP-yXQCb7lMMBC7QtNjdk3BpJMOfOs,18093 +setuptools/_distutils/unixccompiler.py,sha256=QJHNcQiMtWcOQ4WzupzIv1nQwBENo-bNkeVCSVmT4Jk,15437 +setuptools/_distutils/util.py,sha256=ZibjM8bCOu9bbC-RWY7_1cTBfxgCPYNnlUGeqsSU0d0,17648 setuptools/_distutils/version.py,sha256=KlbDjAvGBybVJqRDxNLNMvZLl5XL2FP0dpVjgzfm0zY,12634 setuptools/_distutils/versionpredicate.py,sha256=qBWQ6wTj12ODytoTmIydefIY2jb4uY1sdbgbuLn-IJM,5205 setuptools/_distutils/zosccompiler.py,sha256=bb2dQoGnsv4LmoQBfjhDsaOpt_p5R7y_28l1cltmG94,6589 @@ -114,25 +114,25 @@ setuptools/_distutils/_vendor/packaging/utils.py,sha256=XgdmP3yx9-wQEFjO7OvMj9Rj setuptools/_distutils/_vendor/packaging/version.py,sha256=XjRBLNK17UMDgLeP8UHnqwiY3TdSi03xFQURtec211A,16236 setuptools/_distutils/command/__init__.py,sha256=CeFXxDglGoEJs2OaPuOGVx_eWb_yIOua3nkBfzjdwQU,416 setuptools/_distutils/command/_framework_compat.py,sha256=0iZdSJYzGRWCCvzRDKE-R0-_yaAYvFMd1ylXb2eYXug,1609 -setuptools/_distutils/command/bdist.py,sha256=e5S7gGwr0sTpUIzdRpPuhSGzgqgESR929eTKnK_3nmQ,5354 +setuptools/_distutils/command/bdist.py,sha256=kALmrhET0pRKlSqY3EdvF-Y0zz-iJUx4_jorH9Mdadk,5346 setuptools/_distutils/command/bdist_dumb.py,sha256=Gi_d1Nz4l6Gz_xU4LRfRVRKBri22WoNPM7uYyX2ksdk,4582 setuptools/_distutils/command/bdist_rpm.py,sha256=DfZgvPmm3PTAd39YzLeQ8fmbyRGaXo-nmnUzYEtccg0,21686 setuptools/_distutils/command/build.py,sha256=_jUqG3GWKIddOeMVktPUtVv05hSBt-_0zLrTByu3_qA,5729 setuptools/_distutils/command/build_clib.py,sha256=qTpvz-Db2wEjKkX_kPwYQzFUCoP5HZrcbLu4HGKTJ0o,7684 -setuptools/_distutils/command/build_ext.py,sha256=O1aQtyhQbg19dSrKBr7yWjbOq_0PEROy7ow6keYx_V0,31850 +setuptools/_distutils/command/build_ext.py,sha256=c5UD0OHwOpxSSX3qkQcPZSuk-lAZFicojtTG05-brRk,31786 setuptools/_distutils/command/build_py.py,sha256=cNe8vwMhyPJ2gN6jot9cOY5OuUPUvT6j9fIFcC-Fcik,16552 setuptools/_distutils/command/build_scripts.py,sha256=EHCVyCiP9APE9X74SkOWj4AdS5iBCue7PqpLQP86e1Y,5534 -setuptools/_distutils/command/check.py,sha256=QqPYr7psFKQ-QwmO4u0RClh3Q9IrI_16ZUYWcwN1ExY,4928 +setuptools/_distutils/command/check.py,sha256=OM9_pYSz62maIzl3LtzrtTQ658OZQ93sOls86ITghaI,4897 setuptools/_distutils/command/clean.py,sha256=qlKth74jWLZjKa2nxOay_2Fua6MVNTroApaQOva2dwc,2595 setuptools/_distutils/command/config.py,sha256=FKd2vUSVOp0rpVUer4bj6D94-fyxyF8HJxitRlZFc9c,13008 setuptools/_distutils/command/install.py,sha256=vTWoCdpV0pfHJHmmzZxUVj5005imD6cpNdi6XgWwxos,30079 -setuptools/_distutils/command/install_data.py,sha256=acC0nyOBSp_a70CnQcLY9iOFzgtSjGshar41_CRymcA,2764 +setuptools/_distutils/command/install_data.py,sha256=TqzaoQ8PIj7tTc25WKPQ81aZvP_dTYY4p9r_tqtdmg8,2816 setuptools/_distutils/command/install_egg_info.py,sha256=Sy2fuBqvCGlQVhJcUteGbdG0KCx2BBN7jAzWEMA9rp8,2788 setuptools/_distutils/command/install_headers.py,sha256=Wmpw2npRNUGYPR1BAbRpRaFbDFFf-KKCEVzUGyEuyvY,1184 -setuptools/_distutils/command/install_lib.py,sha256=F0k4EEkS29BmfMWwhrEYwSfLNYKCv_cZNvr8h18kpFY,8410 +setuptools/_distutils/command/install_lib.py,sha256=N1kybEY_o8G2JG9pOroXqPS_mHn1SktgSvYK44TA7-A,8372 setuptools/_distutils/command/install_scripts.py,sha256=Qw8KrC24mcIeJEvcBNKISMpi75npSm6jzW6BOzA9G7g,1937 setuptools/_distutils/command/register.py,sha256=oQZJSgGEadj-hu-yNS_AWxURDx4wmDPScHh3bxqCdoI,11793 -setuptools/_distutils/command/sdist.py,sha256=kPPvS602kzFCYXSUoo3Jki94gRBHR8pUQCXrh7kd75A,19196 +setuptools/_distutils/command/sdist.py,sha256=VuPtonywrD_DZjkiK8Br4cPp5jnRUWeV8Kc3Q4zn_ig,19175 setuptools/_distutils/command/upload.py,sha256=_uOrBBz6C5P6abyohiUmErSez-qxuCOvk-App3u7wmI,7493 setuptools/_distutils/command/wininst-10.0-amd64.exe,sha256=suMrP6RLOpqP36kGYnNV9vSLSCGSn5vOXe0tB4lDYdQ,222208 setuptools/_distutils/command/wininst-10.0.exe,sha256=GqOSfHmFOG1CdZZWZlx7Qi7iJt8WoZRGr22aZhO4rps,190976 @@ -144,17 +144,17 @@ setuptools/_distutils/command/wininst-8.0.exe,sha256=42JnD5PN2VIzWxpB5VKfGE8gIup setuptools/_distutils/command/wininst-9.0-amd64.exe,sha256=hP54JHF7tV1_MsdIfjcBKhvGzUyMAgK-S_sH53D43FE,224256 setuptools/_distutils/command/wininst-9.0.exe,sha256=E7mIRLL6Sjmk2Ou0FPx5RQ1atPDI9RQawG1AsqBDHqQ,196096 setuptools/_distutils/compat/__init__.py,sha256=AhMdi3AzX62KYnNdOCcEuNXLuBOxhvOSQHtdji4g8z8,429 -setuptools/_distutils/compat/py38.py,sha256=MORBlUI9tX_l0mAM_p6CqLvY1_AfIKfIvucf-hC5V0g,790 +setuptools/_distutils/compat/py38.py,sha256=QnIRFSvDKiQNGpQebTXKmC_2ZLumH08j5z8y8-J04VM,791 setuptools/_distutils/compat/py39.py,sha256=hOsD6lwZLqZoMnacNJ3P6nUA-LJQhEpVtYTzVH0o96M,1964 setuptools/_distutils/tests/__init__.py,sha256=bE9qRiJgLJnfPLHIU21uY7uXYCcHY9dx-V0x1vNT_-M,1476 setuptools/_distutils/tests/support.py,sha256=tjsYsyxvpTK4NrkCseh2ujvDIGV0Mf_b5SI5fP2T0yM,4099 -setuptools/_distutils/tests/test_archive_util.py,sha256=fV7LmuWCWUfrnVgHsYKVK-m7PM2gCbTUx9NsfH1TWZc,12911 +setuptools/_distutils/tests/test_archive_util.py,sha256=c3ANASiJb4cDjOZXyMcNZlaY5iv-amiSS94_vPU_NL4,12911 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=YGv9442JC4K3Mh_f1xY6xx3XFZexdIkNdjNChC6_Fe4,3933 -setuptools/_distutils/tests/test_build.py,sha256=gYI8vE8ZGTQb10lwUGN5t2BhYyMqp4Euaa9DDOdZPhA,1719 +setuptools/_distutils/tests/test_build.py,sha256=Lf66SO9Wi_exzKgsEE5WpVPgdNYHFr1ivOhKQ2gxC1o,1698 setuptools/_distutils/tests/test_build_clib.py,sha256=Mo1ZFb4C1VXBYOGvnallwN7YCnTtr24akLDO8Zi4CsY,4331 -setuptools/_distutils/tests/test_build_ext.py,sha256=AOIxMygZfEwbGJ5mA0mZfnelL04PkBAxUwuLBurPj6A,19961 +setuptools/_distutils/tests/test_build_ext.py,sha256=hyxOeHXp6sDb8CHxaGkR4---nP5nwbPtr9JoAJcT9YU,19961 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_ccompiler.py,sha256=eVzZZE8JMIcl4OjwiuhdSNpNdKknAPOnlIe2DnFX-38,2964 @@ -164,30 +164,30 @@ setuptools/_distutils/tests/test_cmd.py,sha256=bgRB79mitoOKR1OiyZHnCogvGxt3pWkxe setuptools/_distutils/tests/test_config.py,sha256=LRrpSY1KYyKgEmeLod8soGP3DtfIYJjs1Pt6lXxtVc4,2725 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_cygwinccompiler.py,sha256=CJJLxK07fQunX9K5LU6HiFmz7E_4ybz-X7-AtRna6vU,4055 +setuptools/_distutils/tests/test_cygwinccompiler.py,sha256=iqxsDy0Z5ZTRgxM8ARzPXakitQod2V8aG5qet_J5tTg,2753 setuptools/_distutils/tests/test_dir_util.py,sha256=KWN3VrlPL8viRpS9Indmx0Oxe9pgCsP4s8S636EeZE4,3854 -setuptools/_distutils/tests/test_dist.py,sha256=nFRbkwV89MweaDOK-rBIjjHOAMd0dMLIffdLLKuSlFE,18447 -setuptools/_distutils/tests/test_extension.py,sha256=1bN7bZd0Nlq8f_O7C59YuaCzHoFkLkf1kAc72vdpYNU,2930 +setuptools/_distutils/tests/test_dist.py,sha256=CFlBpbM3wJH2WjsgCGsTV4n5Z3BpfLSln6dixBxeqpM,18459 +setuptools/_distutils/tests/test_extension.py,sha256=SLJYnLhshfj4u72Q91E_5jnzVpbPljv6_xqV7yKB1Ds,3094 setuptools/_distutils/tests/test_file_util.py,sha256=r3MNC-g3BZPKRZdHGMqSatM93D_aooTHBn-Vm4IiEDU,3502 setuptools/_distutils/tests/test_filelist.py,sha256=Co8dDWCC5K_DUw5T6TQygBsh_PQVCoOlYQOcsl2agHc,10766 setuptools/_distutils/tests/test_install.py,sha256=TfCB0ykhIxydIC2Q4SuTAZzSHvteMHgrBL9whoSgK9Q,8618 -setuptools/_distutils/tests/test_install_data.py,sha256=rq6VdB98zUGk5vtO0Aogk0xwSqUAojt3WllHDlbSXm4,2105 +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_mingwccompiler.py,sha256=gwTK-kV5nmqWEnALqLIhSz-YTC9bMsx_0fm7zje3UGc,2150 -setuptools/_distutils/tests/test_modified.py,sha256=GCMKXnYdmeveSKgE4jenFBbHmzZwygat28n31IENG-Y,4042 +setuptools/_distutils/tests/test_mingwccompiler.py,sha256=mBl8W8QIO2xy4eOj6aAEVom4lobwpHM-HvFUIXu6q0c,2202 +setuptools/_distutils/tests/test_modified.py,sha256=h1--bOWmtJo1bpVV6uRhdnS9br71CBiNDM1MDwSGpug,4221 setuptools/_distutils/tests/test_msvc9compiler.py,sha256=BTkxYriZs0gEulnm-oOftXh8uatSEZZ7C7iLaEdoih0,5782 setuptools/_distutils/tests/test_msvccompiler.py,sha256=Va7s0OE3vvWaJbhG6k9xXiIwNB-y2ACc7bbQqxXKzJc,3569 setuptools/_distutils/tests/test_register.py,sha256=N81pT28dnGCqylLzLfMlEHtUVguzfnmNPkNUB8IH58U,8839 setuptools/_distutils/tests/test_sdist.py,sha256=VerukBsyT4SnfZFBTbiDxMoOLyNW_ELOjA7kZL3VMGQ,15392 -setuptools/_distutils/tests/test_spawn.py,sha256=TxYs4LFnzsZDoGKXbeBze23iNkhzymy4jJ9Sz4IGf3g,4613 -setuptools/_distutils/tests/test_sysconfig.py,sha256=REwsjXECY-_sh0MaHIsevqGXhLQAl-kbKdgV9dP4Sf4,11935 +setuptools/_distutils/tests/test_spawn.py,sha256=bxk4RmNWFmCnyYpAlqtG8VfXfk5TdzcjV53lOxFyyh4,4613 +setuptools/_distutils/tests/test_sysconfig.py,sha256=iH4Y9E8UHrfl3P-VSt0lbgJMlHuoQsIOorxrsVRQnE8,12010 setuptools/_distutils/tests/test_text_file.py,sha256=WQWSB5AfdBDZaMA8BFgipJPnsJb_2SKMfL90fSkRVtw,3460 -setuptools/_distutils/tests/test_unixccompiler.py,sha256=gRIMaw6JsQdboE07W-v7fAfiVE7LuKRXZlCCVVnGGe4,10584 +setuptools/_distutils/tests/test_unixccompiler.py,sha256=wcJQJhXtkUUE3I64TyDvM3Yo7G9a0ug_Mp7DbZLwT4Q,11840 setuptools/_distutils/tests/test_upload.py,sha256=OsMgqJX-UosIP7eQfAyxVtGBH7el2HNYBAP7qzsp0Qc,6638 -setuptools/_distutils/tests/test_util.py,sha256=vCSaGZ6Q_q-WyJKACapIywudD8VTry5hpNGAau-Eh2g,8351 +setuptools/_distutils/tests/test_util.py,sha256=H9zlZ4z4Vh4TfjNYDBsxP7wguQLpxCfJYyOcm1yZU3c,7988 setuptools/_distutils/tests/test_version.py,sha256=b0UMdMRBofyySAhUYnziYhImdB3CzsU7696brKDP0XM,2750 setuptools/_distutils/tests/test_versionpredicate.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 setuptools/_distutils/tests/unix_compat.py,sha256=z-op6C2iVdX1aq5BIBR7cqOxijKE97alNwJqHNdLpoI,386 @@ -288,8 +288,6 @@ setuptools/_vendor/more_itertools/more.pyi,sha256=iXXeqt48Nxe8VGmIWpkVXuKpR2FYNu 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/ordered_set/__init__.py,sha256=ytazgKsyBKi9uFtBt938yXxQtdat1VCC681s9s0CMqg,17146 -setuptools/_vendor/ordered_set/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 setuptools/_vendor/packaging/__init__.py,sha256=dtw2bNmWCQ9WnMoK3bk_elL1svSlikXtLpZhCFIB9SE,496 setuptools/_vendor/packaging/_elffile.py,sha256=_LcJW4YNKywYsl4169B2ukKRqwxjxst_8H0FRVQKlz8,3282 setuptools/_vendor/packaging/_manylinux.py,sha256=Xo4V0PZz8sbuVCbTni0t1CR0AHeir_7ib4lTmV8scD4,9586 @@ -366,121 +364,128 @@ setuptools/_vendor/zipp/__init__.py,sha256=QuI1g00G4fRAcGt-HqbV0oWIkmSgedCGGYsHH setuptools/_vendor/zipp/glob.py,sha256=etWpnfEoRyfUvrUsi6sTiGmErvPwe6HzY6pT8jg_lUI,3082 setuptools/_vendor/zipp/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 setuptools/_vendor/zipp/compat/py310.py,sha256=eZpkW0zRtunkhEh8jjX3gCGe22emoKCBJw72Zt4RkhA,219 -setuptools/command/__init__.py,sha256=HZlSppOB8Vro73ffvP-xrORuMrh4GnVkOqJspFRG8Pg,396 -setuptools/command/_requirestxt.py,sha256=go0VFq7l2IvrjnT6OeORuVquS2zq_iGgDMdISQ_Fsck,4227 -setuptools/command/alias.py,sha256=1holrSsdYxp1Esoa2yfRHLjiYlCRi3jYZy2yWm62YVU,2383 -setuptools/command/bdist_egg.py,sha256=fUev2ZaXNM_wgwvOFDs7XjdpKjtVFj4hNSJYmKmqrj8,16525 -setuptools/command/bdist_rpm.py,sha256=ilQc1XVNBxv1O-8URD3iSTqszndQ2SWBpZVmrR2awO0,1289 -setuptools/command/bdist_wheel.py,sha256=0fyLqgMRtYFpTTgs-ym0ohYqRO4lWFTbcdaODSGKNQQ,21403 -setuptools/command/build.py,sha256=ISZYvjumNAWFNJcPeV5ASTK5ZJwv3Hr84Q-OERxXb5s,5816 -setuptools/command/build_clib.py,sha256=0Ab0Kppziw4ng_51ODfQxF8HxU6ea89EEyBC8kWHtnc,4539 -setuptools/command/build_ext.py,sha256=Gv6BkEFuOdproKeSbZl9Cv-fDDWNmpQJJAi3KTFtpsc,17760 -setuptools/command/build_py.py,sha256=RW8vkLDHZtMw08qGephkx4tVmiEXtKSEy-TbY5y0ef0,15184 -setuptools/command/develop.py,sha256=1TBybRw1VSURZpeY8L-89WTVh9NsM3x1V2BR1b2UPfs,6892 -setuptools/command/dist_info.py,sha256=jMQq6ZfXGw7enlJv1q0XBTmKVtVyEsOLivS9eRLQ9kg,3507 -setuptools/command/easy_install.py,sha256=lhNxl6pvPDIgvJ2fcSBS0OJaU7nmZmMtajB772YYmyw,86986 -setuptools/command/editable_wheel.py,sha256=NgwUYFYlLOWxxMpC_aC7sARsd0cJ0dsT8KvYlhPNiEQ,35006 -setuptools/command/egg_info.py,sha256=R4igMF2ULn_O1qNG0a4ozuQS9VxHg6SOICLFiRVm3fM,25960 -setuptools/command/install.py,sha256=P8BZgNz6wpX3yVEdX1uCJM3H546nh8BNfxjOHEHcfBQ,6068 -setuptools/command/install_egg_info.py,sha256=zpDDCmOJspfkEekUON7wU0ABFNW-0uXUZpzpHRYUdiI,2066 -setuptools/command/install_lib.py,sha256=LTf3U-nh6fiF4JWzwHRhwyrXjIGwwL7UaUqpL_14hH8,3991 -setuptools/command/install_scripts.py,sha256=YBWMaKfJCKq7VqXazNFaY2AXSYy5l0F37iQ1bmhthjM,2474 +setuptools/command/__init__.py,sha256=JbA5PmpnZ2AHQRFVT2rz5u_PjJFs5647GOIO5OuJzDQ,397 +setuptools/command/_requirestxt.py,sha256=s2MIv5vWc7N_5mHziUIPvl6VjoPIUJsiv0cS4iXEy5M,4227 +setuptools/command/alias.py,sha256=aiGMw1AeN4rqJjr3Nr3SVDbLXjgjufriwcMM1nBmiHY,2383 +setuptools/command/bdist_egg.py,sha256=MmzT4GB9e7FUJ-KyoWyyDGRdk77qzsg8N1VQvVLx35E,16526 +setuptools/command/bdist_rpm.py,sha256=99wVFBa8EF3gHbEq10QojuYcpx3zX_NLCYZNpbG66GU,1427 +setuptools/command/bdist_wheel.py,sha256=qIKiwKyWBHjTBO5YfNB10X-y62cgZ5MbzRlQPDqnnKE,22200 +setuptools/command/build.py,sha256=QusufGrwyNZ5R2LII2fjAX_jqfBEzCidPPmX9wNrlZI,5956 +setuptools/command/build_clib.py,sha256=lO7aVa6VbCt6KjY366Sbay1_LOzkNotc-sogodad3yE,4678 +setuptools/command/build_ext.py,sha256=5-sMik_z2KRHdIKwAqNGTYSda7XWT7FH2c1No-gidLU,17893 +setuptools/command/build_py.py,sha256=d1BNjWsfpVZQ11lf6DQspEjsSyl7TEkdL4Ex-j8ZcxI,15322 +setuptools/command/develop.py,sha256=ENdCXuHpdD3aRFvNyT1OY1x5paR8Wm0ckEkxVvtlaQc,6849 +setuptools/command/dist_info.py,sha256=FueFqI-t7-KeP1E8PyG9A0f4tDCfrw0XXf7vnaYHjY4,3508 +setuptools/command/easy_install.py,sha256=lzo2YswhTh1udybi4rqazxVTzYTlavZ6jcxo5n59QBw,87264 +setuptools/command/editable_wheel.py,sha256=uwnu8aTRXfwOuo0wdlkcGJXF7h37H8fHgWQvOfM2RZs,35041 +setuptools/command/egg_info.py,sha256=oac3-2LEpL4y2DBD21dAhQ5JIWOHjjhNT999j6JjcTk,25979 +setuptools/command/install.py,sha256=qOT-JZSBS5te3tGjvXr3Aqgoghn6HI9w1Ud4SkMrVN0,6208 +setuptools/command/install_egg_info.py,sha256=brYRRGb0_8zJ3-fQ0fnkeXCzX2raLNX05Ja7n73cJJI,2046 +setuptools/command/install_lib.py,sha256=3-_JRnvnQxTD0lSV9AtnxokwtIpvNaPBlKGp2i5S5x8,4133 +setuptools/command/install_scripts.py,sha256=mQbIx9cuMISaEj2FOi6Yu7_u_q3go_beB6gphwBCrwI,2614 setuptools/command/launcher manifest.xml,sha256=xlLbjWrB01tKC0-hlVkOKkiSPbzMml2eOPtJ_ucCnbE,628 -setuptools/command/register.py,sha256=NntRm0YtZ8MOhN0jmkWfwiogiAdpE70K1ZbEGTPiHk0,466 -setuptools/command/rotate.py,sha256=LKHQnx90ZymRKc_GTS2F7V96QP0hU22lXr2nEIY1b-E,2144 +setuptools/command/register.py,sha256=CSws23FWnqLoi6ueJcB89l31GCFKNuElIeXqLV32Xlw,605 +setuptools/command/rotate.py,sha256=9r8g3tkbvj7yOVkr6c2cmcxv5LNqyAijADbmjJ_Zy24,2145 setuptools/command/saveopts.py,sha256=mVAPMRIGE98gl6eXQ3C2Wo-qPOgl9lbH-Q_YsbLuqeg,657 -setuptools/command/sdist.py,sha256=FkbbBr0-cBKsD9sLkE8xQCNx-U1sZd3kGiKENGJ0o4U,6808 -setuptools/command/setopt.py,sha256=w_7z7z_DDPNlY7rZIIsgdABfZD3VxCdLre3Edu8JloE,5018 +setuptools/command/sdist.py,sha256=6GdBfPsVSCTOXvhB1SlwbMnCimD00HyNaf-pqpeTIWU,6946 +setuptools/command/setopt.py,sha256=MjJy-0pCjnKCouYlg_ouTyB2HZn9Gz4CY0JupdXE3no,5019 setuptools/command/test.py,sha256=YXZTxa_BbHXRVAMLqmRhip-xV48s0TOT5DJ-87Sw_OQ,1178 -setuptools/command/upload.py,sha256=J1tGiJPJMQlD1SIegkuu2KEiY1ycoKkaNJUGqgOl_XI,460 -setuptools/command/upload_docs.py,sha256=1MJd-TFDmilsGutLbjd9Nwu8-3OdxwHXIGRN4NTaa6U,7754 +setuptools/command/upload.py,sha256=8Z91fjY6SCZtKCAlcbNYicVY1jERiqGhW1NAJUUR6Fs,607 +setuptools/command/upload_docs.py,sha256=W-rtW1V4erPjn4SVzPSF1EzwCZLBURVvfPnEyf0DNqM,7754 setuptools/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -setuptools/compat/py310.py,sha256=qh7fqYmHDoILn5Nm9mWS6Xo1PEHDHUNBt7vhN6_c46c,142 -setuptools/compat/py311.py,sha256=HKYJZD-9v_womvvK5gOgRTdiAryumnLRLhcg7xt9s8w,735 +setuptools/compat/py310.py,sha256=8sqwWczIcrkzeAbhaim4pKVd4tXZdcqmebgdvzji0rc,141 +setuptools/compat/py311.py,sha256=e6tJAFwZEP82hmMBl10HYeSypelo_Ti2wTjKZVKLwOE,790 setuptools/compat/py39.py,sha256=BJMtnkfcqyTfccqjYQxfoRtU2nTnWaEESBVkshTiXqY,493 +setuptools/config/NOTICE,sha256=Ld3wiBgpejuJ1D2V_2WdjahXQRCMkTbfo6TYVsBiO9g,493 setuptools/config/__init__.py,sha256=aiPnL9BJn1O6MfmuNXyn8W2Lp8u9qizRVqwPiOdPIjY,1499 -setuptools/config/_apply_pyprojecttoml.py,sha256=Q0AUCRDCu5amVFbbhUGvFGJkr8Wq0FRtC1FwCU87zHE,14681 -setuptools/config/expand.py,sha256=4YaO2k4AgJz-bpoS0exrg9Xmd2pZFH5wacXPyVk0j4o,15507 -setuptools/config/pyprojecttoml.py,sha256=eq9RLRVF-GPzjbUqIMllw_IyARCz-TN2hMkOYP1D2sI,17658 -setuptools/config/setupcfg.py,sha256=_BfHbrXuV-nVIYwxZVhWvGj5pXlqBXRKk8LKEIVncXY,25573 +setuptools/config/_apply_pyprojecttoml.py,sha256=XGiPPxjidEpnBFVkYssrccuovQQvrAlSn4JQzaHN5Bg,14973 +setuptools/config/distutils.schema.json,sha256=Tcp32kRnhwORGw_9p6GEi08lj2h15tQRzOYBbzGmcBU,972 +setuptools/config/expand.py,sha256=iCbofi5Hsz98u9-r1sdwnXiSbYS3dzRVNRGlqHX06t8,15475 +setuptools/config/pyprojecttoml.py,sha256=LhJRIjap-GrTPNs7SsdHXEQaW6l2I7Wt7fn9WT6EJNg,17608 +setuptools/config/setupcfg.py,sha256=lGSxCWBomOxgndw7cPNu8SkWwVUW_yG7xHK6qPzIDAY,25553 +setuptools/config/setuptools.schema.json,sha256=Nx1r_NN2xa9AoVQhix_n_-DmyLMHQAZDY36maVb9irQ,13758 +setuptools/config/_validate_pyproject/NOTICE,sha256=Ccm86pXKCG-Lxb7RdOQLyDWyl9QPtfhru7Vw_gpVgac,18737 setuptools/config/_validate_pyproject/__init__.py,sha256=dnp6T7ePP1R5z4OuC7Fd2dkFlIrtIfizUfvpGJP6nz0,1042 -setuptools/config/_validate_pyproject/error_reporting.py,sha256=_w11R1Znez8UKLlbgXMY_ky6-eb8N94NbG1fjwNFAEg,11862 +setuptools/config/_validate_pyproject/error_reporting.py,sha256=meldD7nBQdolQhvG-43r1Ue-gU1n7ORAJR86vh3Rrvk,11813 setuptools/config/_validate_pyproject/extra_validations.py,sha256=kd0SWYrsp3IXF9KGAM8QpeaKpGyMsNgL-tjh9TPfhyY,1625 setuptools/config/_validate_pyproject/fastjsonschema_exceptions.py,sha256=w749JgqKi8clBFcObdcbZVqsmF4oJ_QByhZ1SGbUFNw,1612 -setuptools/config/_validate_pyproject/fastjsonschema_validations.py,sha256=WIbuTZNpogmqw2iMwn87SPsDOaiiwUj_SUMVbIXKRwY,295453 -setuptools/config/_validate_pyproject/formats.py,sha256=bUDUtvvjEfMrh5YUm35mli_lh96DT8SwgxabqrtQ0D0,12062 -setuptools/tests/__init__.py,sha256=V1stvNezhug0glFmyPDVYZW8nsroEEW1NzS7a5uM9pg,324 -setuptools/tests/contexts.py,sha256=0gUHBm85rn_hFrCsch1bmIXndw1qNqLdLUeJhooo1FI,3480 -setuptools/tests/environment.py,sha256=7wCgXgWT1LwP9RoFm_xcUMbSqykGhknEL8k_nCQO3Rk,3102 -setuptools/tests/fixtures.py,sha256=ph58aQDoLL0byxNIFX-Do3nhjeWv2eqlKyiXHv_SuMc,5197 +setuptools/config/_validate_pyproject/fastjsonschema_validations.py,sha256=3jd-Qzt5Qduose78vV9OQL_ciCxkDKIbaunTsDwvWFk,295781 +setuptools/config/_validate_pyproject/formats.py,sha256=Mjz6Rjx1BMDw2XTMAfS-sM5x5Fv5aX2Zk_q5M_7rf_c,12814 +setuptools/tests/__init__.py,sha256=AnBfls2iJbTDQzmMKeLRt-9lxhaOHUVOZEgXv89Uwvs,335 +setuptools/tests/contexts.py,sha256=TAdZKxmmodx1ExMVo01o4QpRjpIpo4X3IWKq_BnjxpU,3480 +setuptools/tests/environment.py,sha256=95_UtTaRiuvwYC9eXKEHbn02kDtZysvZq3UZJmPUj1I,3102 +setuptools/tests/fixtures.py,sha256=-V7iD6BeE2E0Rw6dVvTOCm36JG8ZTTnrXhN0GISlgrg,5197 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/server.py,sha256=qqCMMboZwclsaF5eyMbcRf571Ry4AOFImeeFHSG9jyY,2403 -setuptools/tests/test_archive_util.py,sha256=pBpV3uhoIRdt3KjXFwu_9-tAz22qPzaufaqi5z6hRSk,845 -setuptools/tests/test_bdist_deprecations.py,sha256=v4r806VYQEevANWVxDfYUzeXob6HZFRC5EnFHs02lRk,775 +setuptools/tests/server.py,sha256=ZRJOKKQGUoa03ijPFrFiqNId428Eb9uy_ysOZtagUNs,2403 +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=cdfZsWpFmDRSbZeVu-69T0QiCc-246rbUjtkuB7iBiY,1851 -setuptools/tests/test_bdist_wheel.py,sha256=pWEXhsaDS-TBUoVwenMNCfLK70LD_Be7Ri_hA3pq6-E,19235 -setuptools/tests/test_build.py,sha256=2Yjm1HKMPZCExlcHwMQHn-15wqYDdOoLpnbw9Du_4d4,798 -setuptools/tests/test_build_clib.py,sha256=ipypN2J-6qVSM6iKebqfp4_grBkNs_31Za9_-eQyOHs,3122 -setuptools/tests/test_build_ext.py,sha256=keQIABsGJVvgKqGrVBwR9cAora4URqt56P7CbdyXzPg,9993 -setuptools/tests/test_build_meta.py,sha256=2WKQFNvr1HQ71P3H4jczY5pUYUchJ31RHrW1thjHsNE,33588 -setuptools/tests/test_build_py.py,sha256=GbHAIutuQQuiLQfzoXagmIDbN_4PiHrFFJuREuggnl8,14185 -setuptools/tests/test_config_discovery.py,sha256=Tiarwlwnt1Jl-WCq3JDLnSwgZp-DeOr-VkEFRElMRng,22466 -setuptools/tests/test_core_metadata.py,sha256=LHBmEct551p1iH-vv8-Fw3Qi8o3sWVY1AoTFmM3SUt0,12188 +setuptools/tests/test_bdist_wheel.py,sha256=wfI9qDa43rFfIkICaR4GIOkyE_GFI-oV6HgVj1HO6RQ,19236 +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=MeRBCTkd7HqR4fAzNshknbOi15VayGR91W6EtKFb9MM,10054 +setuptools/tests/test_build_meta.py,sha256=q7VrmCKVPBnBWYSD8Vypjj-FFJSBxHYha-xlqFD9-7s,33589 +setuptools/tests/test_build_py.py,sha256=2MOiPfZ9CvwIOd5TNV6hCq9UrXA3HXJm5vj5GK7opsw,14185 +setuptools/tests/test_config_discovery.py,sha256=8WlsWLyrJJ3BRONIuHG2pXCpu9Bjod-ST67HAFQBjCc,22471 +setuptools/tests/test_core_metadata.py,sha256=7xWmlSgjI_r_tUscBVt-kg2JP10Et5hMNI0f8nMtKPA,12183 setuptools/tests/test_depends.py,sha256=yQBXoQbNQlJit6mbRVoz6Bb553f3sNrq02lZimNz5XY,424 -setuptools/tests/test_develop.py,sha256=_5zo_LaL4eXN3ohK35Y27Z2k4W5pALF_I3IPoHgjZbM,5154 -setuptools/tests/test_dist.py,sha256=kU6fCFW44GsNWvaFHv1nmicQL_su3862PYQ2Bd7MIGE,8810 -setuptools/tests/test_dist_info.py,sha256=MZTwQcXIkyD0dMldzcyor7CK3J9BrqP5xY4aMmvbz7c,7090 -setuptools/tests/test_distutils_adoption.py,sha256=1jTOjrm46pZug7IhNjkLA0AFHS7JKq2a53ATL2pln4o,4748 -setuptools/tests/test_easy_install.py,sha256=hzPeThyv1BvEtW2NFWjD9tzxpY5VPFaOT0XYFmxWwhE,52806 -setuptools/tests/test_editable_install.py,sha256=PF--eriMnAR3U8RDGQkm6hMOeoGv9sufhNHjKPjHTIM,43304 -setuptools/tests/test_egg_info.py,sha256=HKNz_N7dXC_MWdmMOzMqoLUmzlzY2M6UIsqaZ8ITunM,44175 -setuptools/tests/test_extern.py,sha256=cfeNqUaufgnwOznf4OuSC0fTq5p42QLAwDjCQKDKAdw,450 -setuptools/tests/test_find_packages.py,sha256=WGNPsPyTod9Mo0vB911e6-rjla6dTmPWLdhEd2g6Bmg,7841 -setuptools/tests/test_find_py_modules.py,sha256=rn9_hJGEmwYtPz7ayfFXujB684zRtKu5rrZ0HPTRVQg,2404 +setuptools/tests/test_develop.py,sha256=CLzXZ8-b5-VFTuau4P4yXEdLx1UdyTFcOfrV0qyUIdE,5142 +setuptools/tests/test_dist.py,sha256=nG7y41IulZ9pjH-biwOctcQOafpRbNYz0I5sDX8d1pA,8811 +setuptools/tests/test_dist_info.py,sha256=exqqU5XSksRiXjUu4mx1SmN-_jnPoIPPWwsLqBc8fQQ,7090 +setuptools/tests/test_distutils_adoption.py,sha256=ZpdJ2wCyq2zGxsBAcjT2X72Vsj0YXIpW-7fhynb361I,4747 +setuptools/tests/test_easy_install.py,sha256=tlhYfUuyiKL-BwFp9-oCef80JUsvc1Lp5aBSCfiPs8Y,52782 +setuptools/tests/test_editable_install.py,sha256=W2k8YmcO9sCZleIjEtL1b_e9M16KO5L9a1GgTmNx2uY,43304 +setuptools/tests/test_egg_info.py,sha256=MvJWvIn5YZRi3vQGph4SW0AGHCf73G3L3Hdz9AnAZwk,44145 +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=pXMUqidIfGG2TM-5Z9M2T7Dz_OLPD6X-aX8QiUpFv2U,881 -setuptools/tests/test_install_scripts.py,sha256=bxX08lwKJ4VMsUdk8whMg-tYouxvkQM21z2OWOvIOvU,3440 -setuptools/tests/test_integration.py,sha256=3zvaqL1esjNHkkWVswMlBHhUPtvgzwqnmDd0NkDy7no,3883 -setuptools/tests/test_logging.py,sha256=ElpVxCTWqHyW4IjjEFztuMwtqVt0Zhc45dJ6Lu3OhfU,2093 -setuptools/tests/test_manifest.py,sha256=jiRGTKrOYfY3pE1Nrmf-_hXG9e9VlyEjSEot1XvsdYU,18761 -setuptools/tests/test_msvc14.py,sha256=mmvMNb0G1hE1qho_VfMQ7AXM-ZsYVwC-pMlruIQc7Ok,2783 -setuptools/tests/test_namespaces.py,sha256=ZWtJ1_c4Es5kPrDokzJiwVudl9e_O2uxlrpllPHoGao,4515 -setuptools/tests/test_packageindex.py,sha256=jTLXMFiF0-a0Ere-au5C60JZvbv1ip1c6J_iRA_prxg,8974 -setuptools/tests/test_register.py,sha256=HLHLStf_4t748eGRy3CUyRI4AWt7Kycc0Mz_LqeDUUo,517 +setuptools/tests/test_install_scripts.py,sha256=bJFXiOYmMd-7ZgB9Kueh_vmiiBtTD3jDFOCSkzSys9Q,3441 +setuptools/tests/test_integration.py,sha256=zQ-TCRQc4gqRZogcdorgal9IM5uZEK5UiQSoubDdvKU,3882 +setuptools/tests/test_logging.py,sha256=9MeqJ_jgQTlE9M4WN7YuFC9iYhKrT9fsJIaKG1L73p4,2095 +setuptools/tests/test_manifest.py,sha256=N4UY8Y1TvjOiKerLHSF6LkHuenXGl8tw6o-ivlj3e5A,18761 +setuptools/tests/test_msvc14.py,sha256=jkqKD7aD_6yB5ULMYYFF1eoV53wXwS-jrvO4VPHVwVA,2785 +setuptools/tests/test_namespaces.py,sha256=Y6utoe5PHHqL_DlgawqB9F8XpsUDPvvw1sQMenK04e0,4515 +setuptools/tests/test_packageindex.py,sha256=zewHXX48XhgYmOwFOshw0eNT40ShsUzt5MnYB9PzRHM,8975 +setuptools/tests/test_register.py,sha256=9fgE2FyPPmHdwS8Ex3PBRo0xRr-HwgCtjXEITfbZ_Zc,517 setuptools/tests/test_sandbox.py,sha256=UQHDEQB-YOnfXIgasm4DiqkvdXWP1Krb4v9vcNp_b9w,4326 -setuptools/tests/test_sdist.py,sha256=0jir6NMKO230a-hrw4rzobt__fJy7dG_pAr2s3McSQg,29579 +setuptools/tests/test_sdist.py,sha256=FyITZ-qKYhw8Jt0zOo51DrcZNhhUh80lnUGjhjrS0GM,29557 setuptools/tests/test_setopt.py,sha256=3VxxM4ATfP-P4AGnDjoWCnHr5-i9CSEQTFYU1-FTnvI,1365 -setuptools/tests/test_setuptools.py,sha256=YESATQve_a6t-1_PIHohOrhXN18Vf45JrvkFemy-wSY,8892 +setuptools/tests/test_setuptools.py,sha256=romaG0DpwycEElTxWRqKF4C2bDX-h1pYADvuqCHU_rQ,8892 setuptools/tests/test_unicode_utils.py,sha256=xWfEEl8jkQCt9othUTXJfFmdyATAFggJs2tTxjbumbw,316 -setuptools/tests/test_upload.py,sha256=c-fVbf_c2dbtuN9RbyEY1VtH_U5YiyrIYrltaqsg2jA,507 -setuptools/tests/test_virtualenv.py,sha256=9sSuF44Lm9ZirgMrCsvYFY910t6vH98wqhOuOMw2lHM,3810 -setuptools/tests/test_warnings.py,sha256=GTmxhGeMQWb4jaHFtbUqWdY1ELx6VpHXZSpJrnajr9Q,3348 -setuptools/tests/test_wheel.py,sha256=o8NEB2DMCJik7TkMSUjqytKmjmr9c27qkFgqsGLRaeQ,19252 -setuptools/tests/test_windows_wrappers.py,sha256=E2nLBwncLeBYnQRKSXZcwUSY46tlIXaBFBfIn3pxBrg,7894 +setuptools/tests/test_upload.py,sha256=wKH3zSINflmZk9XTwF4-YIPr65AcgWpHkg0bUyJYroc,507 +setuptools/tests/test_virtualenv.py,sha256=OlgHQrcrF-KtA5Noh0Iw2VVvHmkvJDZ6CWUzq4etKrE,3809 +setuptools/tests/test_warnings.py,sha256=zwR2zcnCeCeDqILZlJOPAcuyPHoDvGu1OtOVYiLMk74,3347 +setuptools/tests/test_wheel.py,sha256=BeqEOP1x6HliF_ZYpqUMQ7QTNaUcI3yDoo1XIqEvUZM,19252 +setuptools/tests/test_windows_wrappers.py,sha256=2FmgEfFGX5OV0kVOpPPEZICAL76TrcNbfa2uTCzs134,7894 setuptools/tests/text.py,sha256=a12197pMVTvB6FAWQ0ujT8fIQiLIWJlFAl1UCaDUDfg,123 setuptools/tests/textwrap.py,sha256=FNNNq_MiaEJx88PnsbJQIRxmj1qmgcAOCXXRsODPJN4,98 setuptools/tests/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -setuptools/tests/compat/py39.py,sha256=2fCP3qpxTPhf0eQ3BvlWLkEqwQ-5BHP2zZsCIl5PcCE,136 +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/setupcfg_examples.txt,sha256=cAbVvCbkFZuTUL6xRRzRgqyB0rLvJTfvw3D30glo2OE,1912 -setuptools/tests/config/test_apply_pyprojecttoml.py,sha256=sJTLFZ69qpdMgsBx6rXVNHfSdLaODkSOLq_ciISw5P0,17528 -setuptools/tests/config/test_expand.py,sha256=H9dvnCsqigmz14CxuEclJf3Y61dHpPwPpfSHAuxdzQw,8110 -setuptools/tests/config/test_pyprojecttoml.py,sha256=uz23l2PthELFMJ7sTRpTE2aHla5kZ4hEfelAxqSofIY,12394 +setuptools/tests/config/test_apply_pyprojecttoml.py,sha256=STdSbHcN0DK6_ByNpnP9beTpR_1YUOuVsmowNs2Uo2U,18473 +setuptools/tests/config/test_expand.py,sha256=yJmhq52MqTPEft6QOSlZR8yN6dkJVtlOcTo9D7pqGXU,8111 +setuptools/tests/config/test_pyprojecttoml.py,sha256=MxQewMcnZcZTZAhoJbGRMVvRs2eRlbHQsnAJBOqlHec,12398 setuptools/tests/config/test_pyprojecttoml_dynamic_deps.py,sha256=h3f9fPy-oxtC_HPgxtMGM1LgdFz01RYtTL47ubFZp5M,3072 -setuptools/tests/config/test_setupcfg.py,sha256=CV16RQj9_cD3w__NUlseP1eLpmH_YAzEqbF-Y8LvLuI,33359 +setuptools/tests/config/test_setupcfg.py,sha256=t12suujLW4E-xARDfExy01RmSkGF1l2lsBvXqhBPfts,33361 setuptools/tests/config/downloads/__init__.py,sha256=0WrIXZDfFnFkRVio3a-Z6RffRMZbc3AuJstWaTrorxg,1762 -setuptools/tests/config/downloads/preload.py,sha256=ZAhZpkdu67QJC176xJgL8x5yyStUg9pFCa0LkZpD6eQ,451 +setuptools/tests/config/downloads/preload.py,sha256=sIGGZpY3cmMpMwiJYYYYHG2ifZJkvJgEotRFtiulV1I,450 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/helpers.py,sha256=xnBxC5HF6GlmNGeE_X7wy1TTAEFt1th3kzipWncfZ2M,2522 -setuptools/tests/integration/test_pip_install_sdist.py,sha256=kMOuHG9wtSPSD9vO8Ts58I0mUoSNlWyHYEU4kd4PZMk,8257 -setuptools-72.1.0.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 -setuptools-72.1.0.dist-info/METADATA,sha256=AFE7tXDpug8BfcpJLfRc8J4KmI0ys7NdoeUlX0nt7ZQ,6569 -setuptools-72.1.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91 -setuptools-72.1.0.dist-info/entry_points.txt,sha256=vrJkNDLAQaVfqJRF2XS-UT5wsuNLH09WS536cjDi0DE,2506 -setuptools-72.1.0.dist-info/top_level.txt,sha256=d9yL39v_W7qmKDDSH6sT4bE0j_Ls1M3P161OGgdsm4g,41 +setuptools/tests/integration/helpers.py,sha256=3PHcS9SCA-fwVJmUP2ad5NQOttJAETI5Nnoc_xroO5k,2522 +setuptools/tests/integration/test_pip_install_sdist.py,sha256=FKP55wdxgkQtpo2vNPg9bLx4Xqee2ObS6o8cyM91mCM,8263 +setuptools-73.0.1.dist-info/LICENSE,sha256=htoPAa6uRjSKPD1GUZXcHOzN55956HdppkuNoEsqR0E,1023 +setuptools-73.0.1.dist-info/METADATA,sha256=nlwmiIWxZfugLU-BrCuX4oNkh7UBawyddCx3-FcMBq4,6573 +setuptools-73.0.1.dist-info/WHEEL,sha256=Mdi9PDNwEZptOjTlUcAth7XJDFtKrHYaQMPulZeBCiQ,91 +setuptools-73.0.1.dist-info/entry_points.txt,sha256=vrJkNDLAQaVfqJRF2XS-UT5wsuNLH09WS536cjDi0DE,2506 +setuptools-73.0.1.dist-info/top_level.txt,sha256=d9yL39v_W7qmKDDSH6sT4bE0j_Ls1M3P161OGgdsm4g,41 +setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197 +setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174 +setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.BSD,sha256=tw5-m3QvHMb5SLNMFqo5_-zpQZY2S8iP8NIYDwAo-sU,1344 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 @@ -539,11 +544,6 @@ setuptools/_vendor/more_itertools-10.3.0.dist-info/METADATA,sha256=BFO90O-fLNiVQ 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/ordered_set-4.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -setuptools/_vendor/ordered_set-4.1.0.dist-info/METADATA,sha256=FqVN_VUTJTCDQ-vtnmXrbgapDjciET-54gSNJ47sro8,5340 -setuptools/_vendor/ordered_set-4.1.0.dist-info/RECORD,sha256=kGT-NmA85gPdPQP2jMGdN-2aQ5gie_1UQ4QACG3MIPo,614 -setuptools/_vendor/ordered_set-4.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -setuptools/_vendor/ordered_set-4.1.0.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81 setuptools/_vendor/packaging-24.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 setuptools/_vendor/packaging-24.1.dist-info/LICENSE,sha256=ytHvW9NA1z4HS6YU0m996spceUDD2MNIUuZcSQlobEg,197 setuptools/_vendor/packaging-24.1.dist-info/LICENSE.APACHE,sha256=DVQuDIgE45qn836wDaWnYhSdxoLXgpRRKH4RuTjpRZQ,10174 @@ -589,4 +589,4 @@ setuptools/_vendor/zipp-3.19.2.dist-info/RECORD,sha256=8xby4D_ZrefrvAsVRwaEjiu4_ 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-72.1.0.dist-info/RECORD,, +setuptools-73.0.1.dist-info/RECORD,, diff --git a/uno/lib/python/setuptools-72.1.0.dist-info/WHEEL b/uno/lib/python/setuptools-73.0.1.dist-info/WHEEL similarity index 65% rename from uno/lib/python/setuptools-72.1.0.dist-info/WHEEL rename to uno/lib/python/setuptools-73.0.1.dist-info/WHEEL index 1a9c5358..50e1e84e 100644 --- a/uno/lib/python/setuptools-72.1.0.dist-info/WHEEL +++ b/uno/lib/python/setuptools-73.0.1.dist-info/WHEEL @@ -1,5 +1,5 @@ Wheel-Version: 1.0 -Generator: setuptools (72.1.0) +Generator: setuptools (73.0.1) Root-Is-Purelib: true Tag: py3-none-any diff --git a/uno/lib/python/setuptools-72.1.0.dist-info/entry_points.txt b/uno/lib/python/setuptools-73.0.1.dist-info/entry_points.txt similarity index 100% rename from uno/lib/python/setuptools-72.1.0.dist-info/entry_points.txt rename to uno/lib/python/setuptools-73.0.1.dist-info/entry_points.txt diff --git a/uno/lib/python/setuptools-72.1.0.dist-info/top_level.txt b/uno/lib/python/setuptools-73.0.1.dist-info/top_level.txt similarity index 100% rename from uno/lib/python/setuptools-72.1.0.dist-info/top_level.txt rename to uno/lib/python/setuptools-73.0.1.dist-info/top_level.txt diff --git a/uno/lib/python/setuptools/__init__.py b/uno/lib/python/setuptools/__init__.py index afca08be..1d3156ff 100644 --- a/uno/lib/python/setuptools/__init__.py +++ b/uno/lib/python/setuptools/__init__.py @@ -1,27 +1,31 @@ """Extensions to the 'distutils' for large or complex distributions""" +from __future__ import annotations + import functools import os import re import sys -from typing import TYPE_CHECKING +from abc import abstractmethod +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 -import distutils.core -from distutils.errors import DistutilsOptionError from . import logging, monkey -from . import version as _version_module 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 +from distutils.errors import DistutilsOptionError + __all__ = [ 'setup', 'Distribution', @@ -33,11 +37,10 @@ 'find_namespace_packages', ] -__version__ = _version_module.__version__ +_CommandT = TypeVar("_CommandT", bound="_Command") bootstrap_install_from = None - find_packages = PackageFinder.find find_namespace_packages = PEP420PackageFinder.find @@ -130,42 +133,25 @@ class Command(_Command): 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: - - .. method:: initialize_options(self) - - 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. - - .. method:: finalize_options(self) - - 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``). - - .. method:: run(self) - - Execute the actions intended by the command. - (Side effects **SHOULD** only take place when ``run`` is executed, - for example, creating new files or writing to the terminal output). + :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 ``initialize_options()`` - and "defined" (given their final values, aka "finalized") in ``finalize_options()``, + 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 ``run()`` method. - Between ``initialize_options()`` and ``finalize_options()``, ``setuptools`` may set + (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 - ``finalize_options`` unless necessary. + :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 ``initialize_options()`` and - ``finalize_options()``. For example, all derived attributes (or attributes that + 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 - ``finalize_options``. + :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 @@ -221,11 +207,48 @@ def ensure_string_list(self, option): "'%s' must be a list of strings (got %r)" % (option, val) ) - def reinitialize_command(self, command, reinit_subcommands=False, **kw): + @overload # type:ignore[override] # Extra **kw param + 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 + @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): """ diff --git a/uno/lib/python/setuptools/_core_metadata.py b/uno/lib/python/setuptools/_core_metadata.py index 82ec19fc..2e9c48a7 100644 --- a/uno/lib/python/setuptools/_core_metadata.py +++ b/uno/lib/python/setuptools/_core_metadata.py @@ -13,15 +13,16 @@ from email.message import Message from tempfile import NamedTemporaryFile -from distutils.util import rfc822_escape - -from . import _normalization, _reqs 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 .warnings import SetuptoolsDeprecationWarning +from distutils.util import rfc822_escape + def get_metadata_version(self): mv = getattr(self, 'metadata_version', None) diff --git a/uno/lib/python/setuptools/_distutils/_collections.py b/uno/lib/python/setuptools/_distutils/_collections.py index d11a8346..863030b3 100644 --- a/uno/lib/python/setuptools/_distutils/_collections.py +++ b/uno/lib/python/setuptools/_distutils/_collections.py @@ -1,11 +1,7 @@ from __future__ import annotations import collections -import functools import itertools -import operator -from collections.abc import Mapping -from typing import Any # from jaraco.collections 3.5.1 @@ -60,144 +56,3 @@ def __contains__(self, other): def __len__(self): return len(list(iter(self))) - - -# from jaraco.collections 5.0.1 -class RangeMap(dict): - """ - A dictionary-like object that uses the keys as bounds for a range. - Inclusion of the value for that range is determined by the - key_match_comparator, which defaults to less-than-or-equal. - A value is returned for a key if it is the first key that matches in - the sorted list of keys. - - One may supply keyword parameters to be passed to the sort function used - to sort keys (i.e. key, reverse) as sort_params. - - Create a map that maps 1-3 -> 'a', 4-6 -> 'b' - - >>> r = RangeMap({3: 'a', 6: 'b'}) # boy, that was easy - >>> r[1], r[2], r[3], r[4], r[5], r[6] - ('a', 'a', 'a', 'b', 'b', 'b') - - Even float values should work so long as the comparison operator - supports it. - - >>> r[4.5] - 'b' - - Notice that the way rangemap is defined, it must be open-ended - on one side. - - >>> r[0] - 'a' - >>> r[-1] - 'a' - - One can close the open-end of the RangeMap by using undefined_value - - >>> r = RangeMap({0: RangeMap.undefined_value, 3: 'a', 6: 'b'}) - >>> r[0] - Traceback (most recent call last): - ... - KeyError: 0 - - One can get the first or last elements in the range by using RangeMap.Item - - >>> last_item = RangeMap.Item(-1) - >>> r[last_item] - 'b' - - .last_item is a shortcut for Item(-1) - - >>> r[RangeMap.last_item] - 'b' - - Sometimes it's useful to find the bounds for a RangeMap - - >>> r.bounds() - (0, 6) - - RangeMap supports .get(key, default) - - >>> r.get(0, 'not found') - 'not found' - - >>> r.get(7, 'not found') - 'not found' - - One often wishes to define the ranges by their left-most values, - which requires use of sort params and a key_match_comparator. - - >>> r = RangeMap({1: 'a', 4: 'b'}, - ... sort_params=dict(reverse=True), - ... key_match_comparator=operator.ge) - >>> r[1], r[2], r[3], r[4], r[5], r[6] - ('a', 'a', 'a', 'b', 'b', 'b') - - That wasn't nearly as easy as before, so an alternate constructor - is provided: - - >>> r = RangeMap.left({1: 'a', 4: 'b', 7: RangeMap.undefined_value}) - >>> r[1], r[2], r[3], r[4], r[5], r[6] - ('a', 'a', 'a', 'b', 'b', 'b') - - """ - - def __init__( - self, - source, - sort_params: Mapping[str, Any] = {}, - key_match_comparator=operator.le, - ): - dict.__init__(self, source) - self.sort_params = sort_params - self.match = key_match_comparator - - @classmethod - def left(cls, source): - return cls( - source, sort_params=dict(reverse=True), key_match_comparator=operator.ge - ) - - def __getitem__(self, item): - sorted_keys = sorted(self.keys(), **self.sort_params) - if isinstance(item, RangeMap.Item): - result = self.__getitem__(sorted_keys[item]) - else: - key = self._find_first_match_(sorted_keys, item) - result = dict.__getitem__(self, key) - if result is RangeMap.undefined_value: - raise KeyError(key) - return result - - def get(self, key, default=None): - """ - Return the value for key if key is in the dictionary, else default. - If default is not given, it defaults to None, so that this method - never raises a KeyError. - """ - try: - return self[key] - except KeyError: - return default - - def _find_first_match_(self, keys, item): - is_match = functools.partial(self.match, item) - matches = list(filter(is_match, keys)) - if matches: - return matches[0] - raise KeyError(item) - - def bounds(self): - sorted_keys = sorted(self.keys(), **self.sort_params) - return (sorted_keys[RangeMap.first_item], sorted_keys[RangeMap.last_item]) - - # some special values for the RangeMap - undefined_value = type('RangeValueUndefined', (), {})() - - class Item(int): - "RangeMap Item" - - first_item = Item(0) - last_item = Item(-1) diff --git a/uno/lib/python/setuptools/_distutils/_modified.py b/uno/lib/python/setuptools/_distutils/_modified.py index 6532aa10..b7bdaa29 100644 --- a/uno/lib/python/setuptools/_distutils/_modified.py +++ b/uno/lib/python/setuptools/_distutils/_modified.py @@ -63,7 +63,7 @@ def missing_as_newer(source): return missing == 'newer' and not os.path.exists(source) ignored = os.path.exists if missing == 'ignore' else None - return any( + return not os.path.exists(target) or any( missing_as_newer(source) or _newer(source, target) for source in filter(ignored, sources) ) diff --git a/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE b/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE new file mode 100644 index 00000000..6f62d44e --- /dev/null +++ b/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE @@ -0,0 +1,3 @@ +This software is made available under the terms of *either* of the licenses +found in LICENSE.APACHE or LICENSE.BSD. Contributions to this software is made +under the terms of *both* these licenses. diff --git a/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.APACHE b/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.APACHE new file mode 100644 index 00000000..f433b1a5 --- /dev/null +++ b/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.APACHE @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.BSD b/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.BSD new file mode 100644 index 00000000..42ce7b75 --- /dev/null +++ b/uno/lib/python/setuptools/_distutils/_vendor/packaging-24.0.dist-info/LICENSE.BSD @@ -0,0 +1,23 @@ +Copyright (c) Donald Stufft and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/uno/lib/python/setuptools/_distutils/bcppcompiler.py b/uno/lib/python/setuptools/_distutils/bcppcompiler.py index e47dca5d..9157b433 100644 --- a/uno/lib/python/setuptools/_distutils/bcppcompiler.py +++ b/uno/lib/python/setuptools/_distutils/bcppcompiler.py @@ -236,8 +236,7 @@ def link( # noqa: C901 temp_dir = os.path.dirname(objects[0]) # preserve tree structure def_file = os.path.join(temp_dir, f'{modname}.def') contents = ['EXPORTS'] - for sym in export_symbols or []: - contents.append(f' {sym}=_{sym}') + contents.extend(f' {sym}=_{sym}' for sym in export_symbols) self.execute(write_file, (def_file, contents), f"writing {def_file}") # Borland C++ has problems with '/' in paths diff --git a/uno/lib/python/setuptools/_distutils/ccompiler.py b/uno/lib/python/setuptools/_distutils/ccompiler.py index 9d5297b9..bc4743bc 100644 --- a/uno/lib/python/setuptools/_distutils/ccompiler.py +++ b/uno/lib/python/setuptools/_distutils/ccompiler.py @@ -22,7 +22,7 @@ ) from .file_util import move_file from .spawn import spawn -from .util import execute, split_quoted, is_mingw +from .util import execute, is_mingw, split_quoted class CCompiler: @@ -1124,10 +1124,10 @@ def show_compilers(): # commands that use it. from distutils.fancy_getopt import FancyGetopt - compilers = [] - for compiler in compiler_class.keys(): - compilers.append(("compiler=" + compiler, None, compiler_class[compiler][2])) - compilers.sort() + compilers = sorted( + ("compiler=" + compiler, None, compiler_class[compiler][2]) + for compiler in compiler_class.keys() + ) pretty_printer = FancyGetopt(compilers) pretty_printer.print_help("List of available compilers:") @@ -1218,8 +1218,7 @@ def gen_preprocess_options(macros, include_dirs): # shell at all costs when we spawn the command! pp_opts.append("-D{}={}".format(*macro)) - for dir in include_dirs: - pp_opts.append(f"-I{dir}") + pp_opts.extend(f"-I{dir}" for dir in include_dirs) return pp_opts @@ -1230,10 +1229,7 @@ def gen_lib_options(compiler, library_dirs, runtime_library_dirs, libraries): directories. Returns a list of command-line options suitable for use with some compiler (depending on the two format strings passed in). """ - lib_opts = [] - - for dir in library_dirs: - lib_opts.append(compiler.library_dir_option(dir)) + lib_opts = [compiler.library_dir_option(dir) for dir in library_dirs] for dir in runtime_library_dirs: lib_opts.extend(always_iterable(compiler.runtime_library_dir_option(dir))) diff --git a/uno/lib/python/setuptools/_distutils/command/bdist.py b/uno/lib/python/setuptools/_distutils/command/bdist.py index 1738f4e5..f3340751 100644 --- a/uno/lib/python/setuptools/_distutils/command/bdist.py +++ b/uno/lib/python/setuptools/_distutils/command/bdist.py @@ -15,9 +15,10 @@ def show_formats(): """Print list of available formats (arguments to "--format" option).""" from ..fancy_getopt import FancyGetopt - formats = [] - for format in bdist.format_commands: - formats.append(("formats=" + format, None, bdist.format_commands[format][1])) + formats = [ + ("formats=" + format, None, bdist.format_commands[format][1]) + for format in bdist.format_commands + ] pretty_printer = FancyGetopt(formats) pretty_printer.print_help("List of available distribution formats:") diff --git a/uno/lib/python/setuptools/_distutils/command/build_ext.py b/uno/lib/python/setuptools/_distutils/command/build_ext.py index 18e1601a..cf475fe8 100644 --- a/uno/lib/python/setuptools/_distutils/command/build_ext.py +++ b/uno/lib/python/setuptools/_distutils/command/build_ext.py @@ -465,10 +465,7 @@ def get_outputs(self): # And build the list of output (built) filenames. Note that this # ignores the 'inplace' flag, and assumes everything goes in the # "build" tree. - outputs = [] - for ext in self.extensions: - outputs.append(self.get_ext_fullpath(ext.name)) - return outputs + return [self.get_ext_fullpath(ext.name) for ext in self.extensions] def build_extensions(self): # First, sanity-check the 'extensions' list diff --git a/uno/lib/python/setuptools/_distutils/command/check.py b/uno/lib/python/setuptools/_distutils/command/check.py index 58b3f949..93d754e7 100644 --- a/uno/lib/python/setuptools/_distutils/command/check.py +++ b/uno/lib/python/setuptools/_distutils/command/check.py @@ -100,10 +100,9 @@ def check_metadata(self): """ metadata = self.distribution.metadata - missing = [] - for attr in 'name', 'version': - if not getattr(metadata, attr, None): - missing.append(attr) + missing = [ + attr for attr in ('name', 'version') if not getattr(metadata, attr, None) + ] if missing: self.warn("missing required meta-data: {}".format(', '.join(missing))) diff --git a/uno/lib/python/setuptools/_distutils/command/install_data.py b/uno/lib/python/setuptools/_distutils/command/install_data.py index 624c0b90..a90ec3b4 100644 --- a/uno/lib/python/setuptools/_distutils/command/install_data.py +++ b/uno/lib/python/setuptools/_distutils/command/install_data.py @@ -5,7 +5,11 @@ # contributed by Bastian Kleineidam +from __future__ import annotations + +import functools import os +from typing import Iterable from ..core import Command from ..util import change_root, convert_path @@ -46,36 +50,42 @@ def finalize_options(self): def run(self): self.mkpath(self.install_dir) for f in self.data_files: - if isinstance(f, str): - # it's a simple file, so copy it - f = convert_path(f) - if self.warn_dir: - self.warn( - "setup script did not provide a directory for " - f"'{f}' -- installing right in '{self.install_dir}'" - ) - (out, _) = self.copy_file(f, self.install_dir) + self._copy(f) + + @functools.singledispatchmethod + def _copy(self, f: tuple[str | os.PathLike, Iterable[str | os.PathLike]]): + # it's a tuple with path to install to and a list of files + dir = convert_path(f[0]) + if not os.path.isabs(dir): + dir = os.path.join(self.install_dir, dir) + elif self.root: + dir = change_root(self.root, dir) + self.mkpath(dir) + + if f[1] == []: + # If there are no files listed, the user must be + # trying to create an empty directory, so add the + # directory to the list of output files. + self.outfiles.append(dir) + else: + # Copy files, adding them to the list of output files. + for data in f[1]: + data = convert_path(data) + (out, _) = self.copy_file(data, dir) self.outfiles.append(out) - else: - # it's a tuple with path to install to and a list of files - dir = convert_path(f[0]) - if not os.path.isabs(dir): - dir = os.path.join(self.install_dir, dir) - elif self.root: - dir = change_root(self.root, dir) - self.mkpath(dir) - - if f[1] == []: - # If there are no files listed, the user must be - # trying to create an empty directory, so add the - # directory to the list of output files. - self.outfiles.append(dir) - else: - # Copy files, adding them to the list of output files. - for data in f[1]: - data = convert_path(data) - (out, _) = self.copy_file(data, dir) - self.outfiles.append(out) + + @_copy.register(str) + @_copy.register(os.PathLike) + def _(self, f: str | os.PathLike): + # it's a simple file, so copy it + f = convert_path(f) + if self.warn_dir: + self.warn( + "setup script did not provide a directory for " + f"'{f}' -- installing right in '{self.install_dir}'" + ) + (out, _) = self.copy_file(f, self.install_dir) + self.outfiles.append(out) def get_inputs(self): return self.data_files or [] diff --git a/uno/lib/python/setuptools/_distutils/command/install_lib.py b/uno/lib/python/setuptools/_distutils/command/install_lib.py index 54a12d38..01579d46 100644 --- a/uno/lib/python/setuptools/_distutils/command/install_lib.py +++ b/uno/lib/python/setuptools/_distutils/command/install_lib.py @@ -161,9 +161,7 @@ def _mutate_outputs(self, has_any, build_cmd, cmd_option, output_dir): build_dir = getattr(build_cmd, cmd_option) prefix_len = len(build_dir) + len(os.sep) - outputs = [] - for file in build_files: - outputs.append(os.path.join(output_dir, file[prefix_len:])) + outputs = [os.path.join(output_dir, file[prefix_len:]) for file in build_files] return outputs diff --git a/uno/lib/python/setuptools/_distutils/command/sdist.py b/uno/lib/python/setuptools/_distutils/command/sdist.py index 04333dd2..e8abb739 100644 --- a/uno/lib/python/setuptools/_distutils/command/sdist.py +++ b/uno/lib/python/setuptools/_distutils/command/sdist.py @@ -24,10 +24,10 @@ def show_formats(): from ..archive_util import ARCHIVE_FORMATS from ..fancy_getopt import FancyGetopt - formats = [] - for format in ARCHIVE_FORMATS.keys(): - formats.append(("formats=" + format, None, ARCHIVE_FORMATS[format][2])) - formats.sort() + formats = sorted( + ("formats=" + format, None, ARCHIVE_FORMATS[format][2]) + for format in ARCHIVE_FORMATS.keys() + ) FancyGetopt(formats).print_help("List of available source distribution formats:") diff --git a/uno/lib/python/setuptools/_distutils/compat/py38.py b/uno/lib/python/setuptools/_distutils/compat/py38.py index 2d442111..03ec73ef 100644 --- a/uno/lib/python/setuptools/_distutils/compat/py38.py +++ b/uno/lib/python/setuptools/_distutils/compat/py38.py @@ -14,6 +14,7 @@ def removeprefix(self, prefix): return self[len(prefix) :] else: return self[:] + else: def removesuffix(self, suffix): diff --git a/uno/lib/python/setuptools/_distutils/cygwinccompiler.py b/uno/lib/python/setuptools/_distutils/cygwinccompiler.py index 7b812fd0..ce412e83 100644 --- a/uno/lib/python/setuptools/_distutils/cygwinccompiler.py +++ b/uno/lib/python/setuptools/_distutils/cygwinccompiler.py @@ -9,13 +9,11 @@ import copy import os import pathlib -import re import shlex import sys import warnings from subprocess import check_output -from ._collections import RangeMap from .errors import ( CCompilerError, CompileError, @@ -26,42 +24,10 @@ from .unixccompiler import UnixCCompiler from .version import LooseVersion, suppress_known_deprecation -_msvcr_lookup = RangeMap.left( - { - # MSVC 7.0 - 1300: ['msvcr70'], - # MSVC 7.1 - 1310: ['msvcr71'], - # VS2005 / MSVC 8.0 - 1400: ['msvcr80'], - # VS2008 / MSVC 9.0 - 1500: ['msvcr90'], - # VS2010 / MSVC 10.0 - 1600: ['msvcr100'], - # VS2012 / MSVC 11.0 - 1700: ['msvcr110'], - # VS2013 / MSVC 12.0 - 1800: ['msvcr120'], - # VS2015 / MSVC 14.0 - 1900: ['vcruntime140'], - 2000: RangeMap.undefined_value, - }, -) - def get_msvcr(): - """Include the appropriate MSVC runtime library if Python was built - with MSVC 7.0 or later. - """ - match = re.search(r'MSC v\.(\d{4})', sys.version) - try: - msc_ver = int(match.group(1)) - except AttributeError: - return [] - try: - return _msvcr_lookup[msc_ver] - except KeyError: - raise ValueError(f"Unknown MS Compiler version {msc_ver} ") + """No longer needed, but kept for backward compatibility.""" + return [] _runtime_library_dirs_msg = ( @@ -99,18 +65,20 @@ def __init__(self, verbose=False, dry_run=False, force=False): self.cxx = os.environ.get('CXX', 'g++') self.linker_dll = self.cc + self.linker_dll_cxx = self.cxx shared_option = "-shared" self.set_executables( compiler=f'{self.cc} -mcygwin -O -Wall', compiler_so=f'{self.cc} -mcygwin -mdll -O -Wall', compiler_cxx=f'{self.cxx} -mcygwin -O -Wall', + compiler_so_cxx=f'{self.cxx} -mcygwin -mdll -O -Wall', linker_exe=f'{self.cc} -mcygwin', - linker_so=(f'{self.linker_dll} -mcygwin {shared_option}'), + linker_so=f'{self.linker_dll} -mcygwin {shared_option}', + linker_exe_cxx=f'{self.cxx} -mcygwin', + linker_so_cxx=f'{self.linker_dll_cxx} -mcygwin {shared_option}', ) - # Include the appropriate MSVC runtime library if Python was built - # with MSVC 7.0 or later. self.dll_libraries = get_msvcr() @property @@ -138,9 +106,17 @@ def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): raise CompileError(msg) else: # for other files use the C-compiler try: - self.spawn( - self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs - ) + if self.detect_language(src) == 'c++': + self.spawn( + self.compiler_so_cxx + + cc_args + + [src, '-o', obj] + + extra_postargs + ) + else: + self.spawn( + self.compiler_so + cc_args + [src, '-o', obj] + extra_postargs + ) except DistutilsExecError as msg: raise CompileError(msg) @@ -276,9 +252,12 @@ def __init__(self, verbose=False, dry_run=False, force=False): self.set_executables( compiler=f'{self.cc} -O -Wall', compiler_so=f'{self.cc} -shared -O -Wall', + compiler_so_cxx=f'{self.cxx} -shared -O -Wall', compiler_cxx=f'{self.cxx} -O -Wall', linker_exe=f'{self.cc}', linker_so=f'{self.linker_dll} {shared_option}', + linker_exe_cxx=f'{self.cxx}', + linker_so_cxx=f'{self.linker_dll_cxx} {shared_option}', ) def runtime_library_dir_option(self, dir): diff --git a/uno/lib/python/setuptools/_distutils/dist.py b/uno/lib/python/setuptools/_distutils/dist.py index d7d4ca8f..115302b3 100644 --- a/uno/lib/python/setuptools/_distutils/dist.py +++ b/uno/lib/python/setuptools/_distutils/dist.py @@ -658,7 +658,7 @@ def _show_help( ) print() - for command in self.commands: + for command in commands: if isinstance(command, type) and issubclass(command, Command): klass = command else: @@ -745,10 +745,7 @@ def print_commands(self): for cmd in std_commands: is_std.add(cmd) - extra_commands = [] - for cmd in self.cmdclass.keys(): - if cmd not in is_std: - extra_commands.append(cmd) + extra_commands = [cmd for cmd in self.cmdclass.keys() if cmd not in is_std] max_length = 0 for cmd in std_commands + extra_commands: @@ -776,10 +773,7 @@ def get_command_list(self): for cmd in std_commands: is_std.add(cmd) - extra_commands = [] - for cmd in self.cmdclass.keys(): - if cmd not in is_std: - extra_commands.append(cmd) + extra_commands = [cmd for cmd in self.cmdclass.keys() if cmd not in is_std] rv = [] for cmd in std_commands + extra_commands: @@ -1301,7 +1295,4 @@ def fix_help_options(options): """Convert a 4-tuple 'help_options' list as found in various command classes to the 3-tuple form required by FancyGetopt. """ - new_options = [] - for help_tuple in options: - new_options.append(help_tuple[0:3]) - return new_options + return [opt[0:3] for opt in options] diff --git a/uno/lib/python/setuptools/_distutils/extension.py b/uno/lib/python/setuptools/_distutils/extension.py index 04e871bc..b302082f 100644 --- a/uno/lib/python/setuptools/_distutils/extension.py +++ b/uno/lib/python/setuptools/_distutils/extension.py @@ -26,7 +26,7 @@ class Extension: name : string the full name of the extension, including any packages -- ie. *not* a filename or pathname, but Python dotted name - sources : [string] + sources : [string | os.PathLike] list of source filenames, relative to the distribution root (where the setup script lives), in Unix form (slash-separated) for portability. Source files may be C, C++, SWIG (.i), @@ -106,11 +106,16 @@ def __init__( ): if not isinstance(name, str): raise AssertionError("'name' must be a string") - if not (isinstance(sources, list) and all(isinstance(v, str) for v in sources)): - raise AssertionError("'sources' must be a list of strings") + if not ( + isinstance(sources, list) + and all(isinstance(v, (str, os.PathLike)) for v in sources) + ): + raise AssertionError( + "'sources' must be a list of strings or PathLike objects." + ) self.name = name - self.sources = sources + self.sources = list(map(os.fspath, sources)) self.include_dirs = include_dirs or [] self.define_macros = define_macros or [] self.undef_macros = undef_macros or [] diff --git a/uno/lib/python/setuptools/_distutils/msvc9compiler.py b/uno/lib/python/setuptools/_distutils/msvc9compiler.py index f860a8d3..4c708487 100644 --- a/uno/lib/python/setuptools/_distutils/msvc9compiler.py +++ b/uno/lib/python/setuptools/_distutils/msvc9compiler.py @@ -640,9 +640,7 @@ def link( # noqa: C901 else: ldflags = self.ldflags_shared - export_opts = [] - for sym in export_symbols or []: - export_opts.append("/EXPORT:" + sym) + export_opts = [f"/EXPORT:{sym}" for sym in export_symbols or []] ld_args = ( ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename] diff --git a/uno/lib/python/setuptools/_distutils/msvccompiler.py b/uno/lib/python/setuptools/_distutils/msvccompiler.py index 2bf94e60..2a5e61d7 100644 --- a/uno/lib/python/setuptools/_distutils/msvccompiler.py +++ b/uno/lib/python/setuptools/_distutils/msvccompiler.py @@ -534,9 +534,7 @@ def link( # noqa: C901 else: ldflags = self.ldflags_shared - export_opts = [] - for sym in export_symbols or []: - export_opts.append("/EXPORT:" + sym) + export_opts = [f"/EXPORT:{sym}" for sym in export_symbols or []] ld_args = ( ldflags + lib_opts + export_opts + objects + ['/OUT:' + output_filename] diff --git a/uno/lib/python/setuptools/_distutils/spawn.py b/uno/lib/python/setuptools/_distutils/spawn.py index 50d30a27..107b0113 100644 --- a/uno/lib/python/setuptools/_distutils/spawn.py +++ b/uno/lib/python/setuptools/_distutils/spawn.py @@ -12,7 +12,6 @@ import subprocess import sys import warnings - from typing import Mapping from ._log import log diff --git a/uno/lib/python/setuptools/_distutils/sysconfig.py b/uno/lib/python/setuptools/_distutils/sysconfig.py index 7ebe6768..fbdd5d73 100644 --- a/uno/lib/python/setuptools/_distutils/sysconfig.py +++ b/uno/lib/python/setuptools/_distutils/sysconfig.py @@ -287,7 +287,7 @@ def _customize_macos(): ) -def customize_compiler(compiler): # noqa: C901 +def customize_compiler(compiler): """Do any platform-specific customization of a CCompiler instance. Mainly needed on Unix, so we can plug in the information that @@ -304,6 +304,7 @@ def customize_compiler(compiler): # noqa: C901 cflags, ccshared, ldshared, + ldcxxshared, shlib_suffix, ar, ar_flags, @@ -313,11 +314,14 @@ def customize_compiler(compiler): # noqa: C901 'CFLAGS', 'CCSHARED', 'LDSHARED', + 'LDCXXSHARED', 'SHLIB_SUFFIX', 'AR', 'ARFLAGS', ) + cxxflags = cflags + if 'CC' in os.environ: newcc = os.environ['CC'] if 'LDSHARED' not in os.environ and ldshared.startswith(cc): @@ -325,38 +329,42 @@ def customize_compiler(compiler): # noqa: C901 # command for LDSHARED as well ldshared = newcc + ldshared[len(cc) :] cc = newcc - if 'CXX' in os.environ: - cxx = os.environ['CXX'] - if 'LDSHARED' in os.environ: - ldshared = os.environ['LDSHARED'] - if 'CPP' in os.environ: - cpp = os.environ['CPP'] - else: - cpp = cc + " -E" # not always - if 'LDFLAGS' in os.environ: - ldshared = ldshared + ' ' + os.environ['LDFLAGS'] - if 'CFLAGS' in os.environ: - cflags = cflags + ' ' + os.environ['CFLAGS'] - ldshared = ldshared + ' ' + os.environ['CFLAGS'] - if 'CPPFLAGS' in os.environ: - cpp = cpp + ' ' + os.environ['CPPFLAGS'] - cflags = cflags + ' ' + os.environ['CPPFLAGS'] - ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] - if 'AR' in os.environ: - ar = os.environ['AR'] - if 'ARFLAGS' in os.environ: - archiver = ar + ' ' + os.environ['ARFLAGS'] - else: - archiver = ar + ' ' + ar_flags + cxx = os.environ.get('CXX', cxx) + ldshared = os.environ.get('LDSHARED', ldshared) + ldcxxshared = os.environ.get('LDCXXSHARED', ldcxxshared) + cpp = os.environ.get( + 'CPP', + cc + " -E", # not always + ) + ldshared = _add_flags(ldshared, 'LD') + ldcxxshared = _add_flags(ldcxxshared, 'LD') + cflags = _add_flags(cflags, 'C') + ldshared = _add_flags(ldshared, 'C') + cxxflags = os.environ.get('CXXFLAGS', cxxflags) + ldcxxshared = _add_flags(ldcxxshared, 'CXX') + cpp = _add_flags(cpp, 'CPP') + cflags = _add_flags(cflags, 'CPP') + cxxflags = _add_flags(cxxflags, 'CPP') + ldshared = _add_flags(ldshared, 'CPP') + ldcxxshared = _add_flags(ldcxxshared, 'CPP') + + ar = os.environ.get('AR', ar) + + archiver = ar + ' ' + os.environ.get('ARFLAGS', ar_flags) cc_cmd = cc + ' ' + cflags + cxx_cmd = cxx + ' ' + cxxflags + compiler.set_executables( preprocessor=cpp, compiler=cc_cmd, compiler_so=cc_cmd + ' ' + ccshared, - compiler_cxx=cxx, + compiler_cxx=cxx_cmd, + compiler_so_cxx=cxx_cmd + ' ' + ccshared, linker_so=ldshared, + linker_so_cxx=ldcxxshared, linker_exe=cc, + linker_exe_cxx=cxx, archiver=archiver, ) @@ -561,3 +569,14 @@ def get_config_var(name): warnings.warn('SO is deprecated, use EXT_SUFFIX', DeprecationWarning, 2) return get_config_vars().get(name) + + +@pass_none +def _add_flags(value: str, type: str) -> str: + """ + Add any flags from the environment for the given type. + + type is the prefix to FLAGS in the environment key (e.g. "C" for "CFLAGS"). + """ + flags = os.environ.get(f'{type}FLAGS') + return f'{value} {flags}' if flags else value diff --git a/uno/lib/python/setuptools/_distutils/tests/test_archive_util.py b/uno/lib/python/setuptools/_distutils/tests/test_archive_util.py index abbcd36c..389eba16 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_archive_util.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_archive_util.py @@ -18,10 +18,10 @@ from distutils.spawn import spawn from distutils.tests import support from os.path import splitdrive -from test.support import patch import path import pytest +from test.support import patch from .compat.py38 import check_warnings from .unix_compat import UID_0_SUPPORT, grp, pwd, require_uid_0, require_unix_id diff --git a/uno/lib/python/setuptools/_distutils/tests/test_build.py b/uno/lib/python/setuptools/_distutils/tests/test_build.py index 8fb1bc1b..d379aca0 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_build.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_build.py @@ -4,8 +4,7 @@ import sys from distutils.command.build import build from distutils.tests import support -from sysconfig import get_config_var -from sysconfig import get_platform +from sysconfig import get_config_var, get_platform class TestBuild(support.TempdirManager): diff --git a/uno/lib/python/setuptools/_distutils/tests/test_build_ext.py b/uno/lib/python/setuptools/_distutils/tests/test_build_ext.py index 6c4c4ba8..8bd3cef8 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_build_ext.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_build_ext.py @@ -25,11 +25,11 @@ fixup_build_ext, ) from io import StringIO -from test import support import jaraco.path import path import pytest +from test import support from .compat import py38 as import_helper diff --git a/uno/lib/python/setuptools/_distutils/tests/test_cygwinccompiler.py b/uno/lib/python/setuptools/_distutils/tests/test_cygwinccompiler.py index 2e1640b7..677bc0ac 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_cygwinccompiler.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_cygwinccompiler.py @@ -71,50 +71,8 @@ def test_check_config_h(self): assert check_config_h()[0] == CONFIG_H_OK def test_get_msvcr(self): - # [] - sys.version = ( - '2.6.1 (r261:67515, Dec 6 2008, 16:42:21) ' - '\n[GCC 4.0.1 (Apple Computer, Inc. build 5370)]' - ) assert get_msvcr() == [] - # MSVC 7.0 - sys.version = ( - '2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1300 32 bits (Intel)]' - ) - assert get_msvcr() == ['msvcr70'] - - # MSVC 7.1 - sys.version = ( - '2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bits (Intel)]' - ) - assert get_msvcr() == ['msvcr71'] - - # VS2005 / MSVC 8.0 - sys.version = ( - '2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1400 32 bits (Intel)]' - ) - assert get_msvcr() == ['msvcr80'] - - # VS2008 / MSVC 9.0 - sys.version = ( - '2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1500 32 bits (Intel)]' - ) - assert get_msvcr() == ['msvcr90'] - - sys.version = ( - '3.10.0 (tags/v3.10.0:b494f59, Oct 4 2021, 18:46:30) ' - '[MSC v.1929 32 bit (Intel)]' - ) - assert get_msvcr() == ['vcruntime140'] - - # unknown - sys.version = ( - '2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.2000 32 bits (Intel)]' - ) - with pytest.raises(ValueError): - get_msvcr() - @pytest.mark.skipif('sys.platform != "cygwin"') def test_dll_libraries_not_none(self): from distutils.cygwinccompiler import CygwinCCompiler diff --git a/uno/lib/python/setuptools/_distutils/tests/test_dist.py b/uno/lib/python/setuptools/_distutils/tests/test_dist.py index 5bd206fe..4d78a198 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_dist.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_dist.py @@ -88,7 +88,7 @@ def test_command_packages_cmdline(self, clear_argv): 'distutils' not in Distribution.parse_config_files.__module__, reason='Cannot test when virtualenv has monkey-patched Distribution', ) - def test_venv_install_options(self, tmp_path): + def test_venv_install_options(self, tmp_path, clear_argv): sys.argv.append("install") file = str(tmp_path / 'file') diff --git a/uno/lib/python/setuptools/_distutils/tests/test_extension.py b/uno/lib/python/setuptools/_distutils/tests/test_extension.py index 527a1355..41872e04 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_extension.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_extension.py @@ -1,6 +1,7 @@ """Tests for distutils.extension.""" import os +import pathlib import warnings from distutils.extension import Extension, read_setup_file @@ -68,13 +69,15 @@ def test_extension_init(self): assert ext.name == 'name' # the second argument, which is the list of files, must - # be a list of strings + # be a list of strings or PathLike objects with pytest.raises(AssertionError): Extension('name', 'file') with pytest.raises(AssertionError): Extension('name', ['file', 1]) ext = Extension('name', ['file1', 'file2']) assert ext.sources == ['file1', 'file2'] + ext = Extension('name', [pathlib.Path('file1'), pathlib.Path('file2')]) + assert ext.sources == ['file1', 'file2'] # others arguments have defaults for attr in ( diff --git a/uno/lib/python/setuptools/_distutils/tests/test_install_data.py b/uno/lib/python/setuptools/_distutils/tests/test_install_data.py index f34070b1..c800f86c 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_install_data.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_install_data.py @@ -1,6 +1,7 @@ """Tests for distutils.command.install_data.""" import os +import pathlib from distutils.command.install_data import install_data from distutils.tests import support @@ -18,22 +19,27 @@ def test_simple_run(self): # data_files can contain # - simple files + # - a Path object # - a tuple with a path, and a list of file one = os.path.join(pkg_dir, 'one') self.write_file(one, 'xxx') inst2 = os.path.join(pkg_dir, 'inst2') two = os.path.join(pkg_dir, 'two') self.write_file(two, 'xxx') + three = pathlib.Path(pkg_dir) / 'three' + self.write_file(three, 'xxx') - cmd.data_files = [one, (inst2, [two])] - assert cmd.get_inputs() == [one, (inst2, [two])] + cmd.data_files = [one, (inst2, [two]), three] + assert cmd.get_inputs() == [one, (inst2, [two]), three] # let's run the command cmd.ensure_finalized() cmd.run() # let's check the result - assert len(cmd.get_outputs()) == 2 + assert len(cmd.get_outputs()) == 3 + rthree = os.path.split(one)[-1] + assert os.path.exists(os.path.join(inst, rthree)) rtwo = os.path.split(two)[-1] assert os.path.exists(os.path.join(inst2, rtwo)) rone = os.path.split(one)[-1] @@ -46,21 +52,23 @@ def test_simple_run(self): cmd.run() # let's check the result - assert len(cmd.get_outputs()) == 2 + assert len(cmd.get_outputs()) == 3 + assert os.path.exists(os.path.join(inst, rthree)) assert os.path.exists(os.path.join(inst2, rtwo)) assert os.path.exists(os.path.join(inst, rone)) cmd.outfiles = [] # now using root and empty dir cmd.root = os.path.join(pkg_dir, 'root') - inst4 = os.path.join(pkg_dir, 'inst4') - three = os.path.join(cmd.install_dir, 'three') - self.write_file(three, 'xx') - cmd.data_files = [one, (inst2, [two]), ('inst3', [three]), (inst4, [])] + inst5 = os.path.join(pkg_dir, 'inst5') + four = os.path.join(cmd.install_dir, 'four') + self.write_file(four, 'xx') + cmd.data_files = [one, (inst2, [two]), three, ('inst5', [four]), (inst5, [])] cmd.ensure_finalized() cmd.run() # let's check the result - assert len(cmd.get_outputs()) == 4 + assert len(cmd.get_outputs()) == 5 + assert os.path.exists(os.path.join(inst, rthree)) assert os.path.exists(os.path.join(inst2, rtwo)) assert os.path.exists(os.path.join(inst, rone)) diff --git a/uno/lib/python/setuptools/_distutils/tests/test_mingwccompiler.py b/uno/lib/python/setuptools/_distutils/tests/test_mingwccompiler.py index fd201cd7..3e3ad505 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_mingwccompiler.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_mingwccompiler.py @@ -1,8 +1,8 @@ -import pytest - -from distutils.util import split_quoted, is_mingw -from distutils.errors import DistutilsPlatformError, CCompilerError from distutils import sysconfig +from distutils.errors import CCompilerError, DistutilsPlatformError +from distutils.util import is_mingw, split_quoted + +import pytest class TestMingw32CCompiler: @@ -45,6 +45,7 @@ def test_cygwincc_error(self, monkeypatch): with pytest.raises(CCompilerError): distutils.cygwinccompiler.Mingw32CCompiler() + @pytest.mark.skipif('sys.platform == "cygwin"') def test_customize_compiler_with_msvc_python(self): from distutils.cygwinccompiler import Mingw32CCompiler diff --git a/uno/lib/python/setuptools/_distutils/tests/test_modified.py b/uno/lib/python/setuptools/_distutils/tests/test_modified.py index 2bd82346..e35cec2d 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_modified.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_modified.py @@ -117,3 +117,10 @@ def test_newer_pairwise_group(groups_target): newer = newer_pairwise_group([groups_target.newer], [groups_target.target]) assert older == ([], []) assert newer == ([groups_target.newer], [groups_target.target]) + + +def test_newer_group_no_sources_no_target(tmp_path): + """ + Consider no sources and no target "newer". + """ + assert newer_group([], str(tmp_path / 'does-not-exist')) diff --git a/uno/lib/python/setuptools/_distutils/tests/test_spawn.py b/uno/lib/python/setuptools/_distutils/tests/test_spawn.py index 2576bdd5..fd7b669c 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_spawn.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_spawn.py @@ -7,10 +7,10 @@ from distutils.errors import DistutilsExecError from distutils.spawn import find_executable, spawn from distutils.tests import support -from test.support import unix_shell import path import pytest +from test.support import unix_shell from .compat import py38 as os_helper diff --git a/uno/lib/python/setuptools/_distutils/tests/test_sysconfig.py b/uno/lib/python/setuptools/_distutils/tests/test_sysconfig.py index 889a398c..49274a36 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_sysconfig.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_sysconfig.py @@ -9,12 +9,12 @@ from distutils import sysconfig from distutils.ccompiler import new_compiler # noqa: F401 from distutils.unixccompiler import UnixCCompiler -from test.support import swap_item import jaraco.envs import path import pytest from jaraco.text import trim +from test.support import swap_item def _gen_makefile(root, contents): @@ -134,7 +134,10 @@ def test_customize_compiler(self): assert comp.exes['compiler_so'] == ( 'env_cc --sc-cflags --env-cflags --env-cppflags --sc-ccshared' ) - assert comp.exes['compiler_cxx'] == 'env_cxx --env-cxx-flags' + assert ( + comp.exes['compiler_cxx'] + == 'env_cxx --env-cxx-flags --sc-cflags --env-cppflags' + ) assert comp.exes['linker_exe'] == 'env_cc' assert comp.exes['linker_so'] == ( 'env_ldshared --env-ldflags --env-cflags --env-cppflags' @@ -162,7 +165,7 @@ def test_customize_compiler(self): assert comp.exes['preprocessor'] == 'sc_cc -E' assert comp.exes['compiler'] == 'sc_cc --sc-cflags' assert comp.exes['compiler_so'] == 'sc_cc --sc-cflags --sc-ccshared' - assert comp.exes['compiler_cxx'] == 'sc_cxx' + assert comp.exes['compiler_cxx'] == 'sc_cxx --sc-cflags' assert comp.exes['linker_exe'] == 'sc_cc' assert comp.exes['linker_so'] == 'sc_ldshared' assert comp.shared_lib_extension == 'sc_shutil_suffix' diff --git a/uno/lib/python/setuptools/_distutils/tests/test_unixccompiler.py b/uno/lib/python/setuptools/_distutils/tests/test_unixccompiler.py index d2c88e91..50b66544 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_unixccompiler.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_unixccompiler.py @@ -257,9 +257,13 @@ def test_cc_overrides_ldshared_for_cxx_correctly(self): def gcv(v): if v == 'LDSHARED': return 'gcc-4.2 -bundle -undefined dynamic_lookup ' + elif v == 'LDCXXSHARED': + return 'g++-4.2 -bundle -undefined dynamic_lookup ' elif v == 'CXX': return 'g++-4.2' - return 'gcc-4.2' + elif v == 'CC': + return 'gcc-4.2' + return '' def gcvs(*args, _orig=sysconfig.get_config_vars): if args: @@ -315,3 +319,33 @@ def test_has_function(self): self.cc.output_dir = 'scratch' os.chdir(self.mkdtemp()) self.cc.has_function('abort') + + def test_find_library_file(self, monkeypatch): + compiler = UnixCCompiler() + compiler._library_root = lambda dir: dir + monkeypatch.setattr(os.path, 'exists', lambda d: 'existing' in d) + + libname = 'libabc.dylib' if sys.platform != 'cygwin' else 'cygabc.dll' + dirs = ('/foo/bar/missing', '/foo/bar/existing') + assert ( + compiler.find_library_file(dirs, 'abc').replace('\\', '/') + == f'/foo/bar/existing/{libname}' + ) + assert ( + compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/') + == f'/foo/bar/existing/{libname}' + ) + + monkeypatch.setattr( + os.path, + 'exists', + lambda d: 'existing' in d and '.a' in d and '.dll.a' not in d, + ) + assert ( + compiler.find_library_file(dirs, 'abc').replace('\\', '/') + == '/foo/bar/existing/libabc.a' + ) + assert ( + compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/') + == '/foo/bar/existing/libabc.a' + ) diff --git a/uno/lib/python/setuptools/_distutils/tests/test_util.py b/uno/lib/python/setuptools/_distutils/tests/test_util.py index 0de4e1a5..00c9743e 100644 --- a/uno/lib/python/setuptools/_distutils/tests/test_util.py +++ b/uno/lib/python/setuptools/_distutils/tests/test_util.py @@ -5,6 +5,7 @@ import email.policy import io import os +import pathlib import sys import sysconfig as stdlib_sysconfig import unittest.mock as mock @@ -63,30 +64,9 @@ def test_get_platform(self): assert get_platform() == 'win-arm64' def test_convert_path(self): - # linux/mac - os.sep = '/' - - def _join(path): - return '/'.join(path) - - os.path.join = _join - - assert convert_path('/home/to/my/stuff') == '/home/to/my/stuff' - - # win - os.sep = '\\' - - def _join(*path): - return '\\'.join(path) - - os.path.join = _join - - with pytest.raises(ValueError): - convert_path('/home/to/my/stuff') - with pytest.raises(ValueError): - convert_path('home/to/my/stuff/') - - assert convert_path('home/to/my/stuff') == 'home\\to\\my\\stuff' + expected = os.sep.join(('', 'home', 'to', 'my', 'stuff')) + assert convert_path('/home/to/my/stuff') == expected + assert convert_path(pathlib.Path('/home/to/my/stuff')) == expected assert convert_path('.') == os.curdir def test_change_root(self): diff --git a/uno/lib/python/setuptools/_distutils/unixccompiler.py b/uno/lib/python/setuptools/_distutils/unixccompiler.py index 7e68596b..6c1116ae 100644 --- a/uno/lib/python/setuptools/_distutils/unixccompiler.py +++ b/uno/lib/python/setuptools/_distutils/unixccompiler.py @@ -118,9 +118,12 @@ class UnixCCompiler(CCompiler): 'preprocessor': None, 'compiler': ["cc"], 'compiler_so': ["cc"], - 'compiler_cxx': ["cc"], + 'compiler_cxx': ["c++"], + 'compiler_so_cxx': ["c++"], 'linker_so': ["cc", "-shared"], + 'linker_so_cxx': ["c++", "-shared"], 'linker_exe': ["cc"], + 'linker_exe_cxx': ["c++", "-shared"], 'archiver': ["ar", "-cr"], 'ranlib': None, } @@ -187,8 +190,14 @@ def preprocess( def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): compiler_so = compiler_fixup(self.compiler_so, cc_args + extra_postargs) + compiler_so_cxx = compiler_fixup(self.compiler_so_cxx, cc_args + extra_postargs) try: - self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) + if self.detect_language(src) == 'c++': + self.spawn( + compiler_so_cxx + cc_args + [src, '-o', obj] + extra_postargs + ) + else: + self.spawn(compiler_so + cc_args + [src, '-o', obj] + extra_postargs) except DistutilsExecError as msg: raise CompileError(msg) @@ -256,7 +265,13 @@ def link( # building an executable or linker_so (with shared options) # when building a shared library. building_exe = target_desc == CCompiler.EXECUTABLE - linker = (self.linker_exe if building_exe else self.linker_so)[:] + linker = ( + self.linker_exe + if building_exe + else ( + self.linker_so_cxx if target_lang == "c++" else self.linker_so + ) + )[:] if target_lang == "c++" and self.compiler_cxx: env, linker_ne = _split_env(linker) @@ -366,27 +381,11 @@ def _library_root(dir): return os.path.join(match.group(1), dir[1:]) if apply_root else dir def find_library_file(self, dirs, lib, debug=False): - r""" + """ Second-guess the linker with not much hard data to go on: GCC seems to prefer the shared library, so assume that *all* Unix C compilers do, ignoring even GCC's "-static" option. - - >>> compiler = UnixCCompiler() - >>> compiler._library_root = lambda dir: dir - >>> monkeypatch = getfixture('monkeypatch') - >>> monkeypatch.setattr(os.path, 'exists', lambda d: 'existing' in d) - >>> dirs = ('/foo/bar/missing', '/foo/bar/existing') - >>> compiler.find_library_file(dirs, 'abc').replace('\\', '/') - '/foo/bar/existing/libabc.dylib' - >>> compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/') - '/foo/bar/existing/libabc.dylib' - >>> monkeypatch.setattr(os.path, 'exists', - ... lambda d: 'existing' in d and '.a' in d) - >>> compiler.find_library_file(dirs, 'abc').replace('\\', '/') - '/foo/bar/existing/libabc.a' - >>> compiler.find_library_file(reversed(dirs), 'abc').replace('\\', '/') - '/foo/bar/existing/libabc.a' """ lib_names = ( self.library_filename(lib, lib_type=type) diff --git a/uno/lib/python/setuptools/_distutils/util.py b/uno/lib/python/setuptools/_distutils/util.py index 9db89b09..4cc6bd28 100644 --- a/uno/lib/python/setuptools/_distutils/util.py +++ b/uno/lib/python/setuptools/_distutils/util.py @@ -4,9 +4,12 @@ one of the other *util.py modules. """ +from __future__ import annotations + import functools import importlib.util import os +import pathlib import re import string import subprocess @@ -14,6 +17,7 @@ import sysconfig import tempfile +from ._functools import pass_none from ._log import log from ._modified import newer from .errors import DistutilsByteCompileError, DistutilsPlatformError @@ -116,33 +120,23 @@ def split_version(s): return [int(n) for n in s.split('.')] -def convert_path(pathname): - """Return 'pathname' as a name that will work on the native filesystem, - i.e. split it on '/' and put it back together again using the current - directory separator. Needed because filenames in the setup script are - always supplied in Unix style, and have to be converted to the local - convention before we can actually use them in the filesystem. Raises - ValueError on non-Unix-ish systems if 'pathname' either starts or - ends with a slash. +@pass_none +def convert_path(pathname: str | os.PathLike) -> str: + r""" + Allow for pathlib.Path inputs, coax to a native path string. + + If None is passed, will just pass it through as + Setuptools relies on this behavior. + + >>> convert_path(None) is None + True + + Removes empty paths. + + >>> convert_path('foo/./bar').replace('\\', '/') + 'foo/bar' """ - if os.sep == '/': - return pathname - if not pathname: - return pathname - if pathname[0] == '/': - raise ValueError(f"path '{pathname}' cannot be absolute") - if pathname[-1] == '/': - raise ValueError(f"path '{pathname}' cannot end with '/'") - - paths = pathname.split('/') - while '.' in paths: - paths.remove('.') - if not paths: - return os.curdir - return os.path.join(*paths) - - -# convert_path () + return os.fspath(pathlib.PurePath(pathname)) def change_root(new_root, pathname): diff --git a/uno/lib/python/setuptools/_entry_points.py b/uno/lib/python/setuptools/_entry_points.py index 5de12582..e785fc7d 100644 --- a/uno/lib/python/setuptools/_entry_points.py +++ b/uno/lib/python/setuptools/_entry_points.py @@ -1,13 +1,14 @@ import functools -import operator import itertools +import operator -from .errors import OptionError -from jaraco.text import yield_lines from jaraco.functools import pass_none +from jaraco.text import yield_lines +from more_itertools import consume + from ._importlib import metadata from ._itertools import ensure_unique -from more_itertools import consume +from .errors import OptionError def ensure_valid(ep): diff --git a/uno/lib/python/setuptools/_imp.py b/uno/lib/python/setuptools/_imp.py index 38b146fc..bddbf6a6 100644 --- a/uno/lib/python/setuptools/_imp.py +++ b/uno/lib/python/setuptools/_imp.py @@ -3,14 +3,12 @@ from the deprecated imp module. """ -import os -import importlib.util import importlib.machinery +import importlib.util +import os import tokenize - from importlib.util import module_from_spec - PY_SOURCE = 1 PY_COMPILED = 2 C_EXTENSION = 3 diff --git a/uno/lib/python/setuptools/_importlib.py b/uno/lib/python/setuptools/_importlib.py index b2d5b5b8..5317be0f 100644 --- a/uno/lib/python/setuptools/_importlib.py +++ b/uno/lib/python/setuptools/_importlib.py @@ -1,6 +1,5 @@ import sys - if sys.version_info < (3, 10): import importlib_metadata as metadata # pragma: no cover else: diff --git a/uno/lib/python/setuptools/_path.py b/uno/lib/python/setuptools/_path.py index d00db254..dd4a9db8 100644 --- a/uno/lib/python/setuptools/_path.py +++ b/uno/lib/python/setuptools/_path.py @@ -1,15 +1,20 @@ +from __future__ import annotations + import contextlib import os import sys -from typing import Union +from typing import TYPE_CHECKING, Union -from more_itertools import unique_everseen +if TYPE_CHECKING: + from typing_extensions import TypeAlias +from more_itertools import unique_everseen + if sys.version_info >= (3, 9): - StrPath = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath + StrPath: TypeAlias = Union[str, os.PathLike[str]] # Same as _typeshed.StrPath else: - StrPath = Union[str, os.PathLike] + StrPath: TypeAlias = Union[str, os.PathLike] def ensure_directory(path): diff --git a/uno/lib/python/setuptools/_reqs.py b/uno/lib/python/setuptools/_reqs.py index 1b64d9df..2d09244b 100644 --- a/uno/lib/python/setuptools/_reqs.py +++ b/uno/lib/python/setuptools/_reqs.py @@ -1,11 +1,16 @@ +from __future__ import annotations + from functools import lru_cache -from typing import Callable, Iterable, Iterator, TypeVar, Union, overload +from typing import TYPE_CHECKING, Callable, Iterable, Iterator, TypeVar, Union, overload import jaraco.text as text from packaging.requirements import Requirement +if TYPE_CHECKING: + from typing_extensions import TypeAlias + _T = TypeVar("_T") -_StrOrIter = Union[str, Iterable[str]] +_StrOrIter: TypeAlias = Union[str, Iterable[str]] parse_req: Callable[[str], Requirement] = lru_cache()(Requirement) diff --git a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/INSTALLER b/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/INSTALLER deleted file mode 100644 index a1b589e3..00000000 --- a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/INSTALLER +++ /dev/null @@ -1 +0,0 @@ -pip diff --git a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/METADATA b/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/METADATA deleted file mode 100644 index 7aea1368..00000000 --- a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/METADATA +++ /dev/null @@ -1,158 +0,0 @@ -Metadata-Version: 2.1 -Name: ordered-set -Version: 4.1.0 -Summary: An OrderedSet is a custom MutableSet that remembers its order, so that every -Author-email: Elia Robyn Lake -Requires-Python: >=3.7 -Description-Content-Type: text/markdown -Classifier: Development Status :: 5 - Production/Stable -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.7 -Classifier: Programming Language :: Python :: 3.8 -Classifier: Programming Language :: Python :: 3.9 -Classifier: Programming Language :: Python :: 3.10 -Classifier: Programming Language :: Python :: Implementation :: CPython -Classifier: Programming Language :: Python :: Implementation :: PyPy -Requires-Dist: pytest ; extra == "dev" -Requires-Dist: black ; extra == "dev" -Requires-Dist: mypy ; extra == "dev" -Project-URL: Home, https://github.com/rspeer/ordered-set -Provides-Extra: dev - -[![Pypi](https://img.shields.io/pypi/v/ordered-set.svg)](https://pypi.python.org/pypi/ordered-set) - -An OrderedSet is a mutable data structure that is a hybrid of a list and a set. -It remembers the order of its entries, and every entry has an index number that -can be looked up. - -## Installation - -`ordered_set` is available on PyPI and packaged as a wheel. You can list it -as a dependency of your project, in whatever form that takes. - -To install it into your current Python environment: - - pip install ordered-set - -To install the code for development, after checking out the repository: - - pip install flit - flit install - -## Usage examples - -An OrderedSet is created and used like a set: - - >>> from ordered_set import OrderedSet - - >>> letters = OrderedSet('abracadabra') - - >>> letters - OrderedSet(['a', 'b', 'r', 'c', 'd']) - - >>> 'r' in letters - True - -It is efficient to find the index of an entry in an OrderedSet, or find an -entry by its index. To help with this use case, the `.add()` method returns -the index of the added item, whether it was already in the set or not. - - >>> letters.index('r') - 2 - - >>> letters[2] - 'r' - - >>> letters.add('r') - 2 - - >>> letters.add('x') - 5 - -OrderedSets implement the union (`|`), intersection (`&`), and difference (`-`) -operators like sets do. - - >>> letters |= OrderedSet('shazam') - - >>> letters - OrderedSet(['a', 'b', 'r', 'c', 'd', 'x', 's', 'h', 'z', 'm']) - - >>> letters & set('aeiou') - OrderedSet(['a']) - - >>> letters -= 'abcd' - - >>> letters - OrderedSet(['r', 'x', 's', 'h', 'z', 'm']) - -The `__getitem__()` and `index()` methods have been extended to accept any -iterable except a string, returning a list, to perform NumPy-like "fancy -indexing". - - >>> letters = OrderedSet('abracadabra') - - >>> letters[[0, 2, 3]] - ['a', 'r', 'c'] - - >>> letters.index(['a', 'r', 'c']) - [0, 2, 3] - -OrderedSet implements `__getstate__` and `__setstate__` so it can be pickled, -and implements the abstract base classes `collections.MutableSet` and -`collections.Sequence`. - -OrderedSet can be used as a generic collection type, similar to the collections -in the `typing` module like List, Dict, and Set. For example, you can annotate -a variable as having the type `OrderedSet[str]` or `OrderedSet[Tuple[int, -str]]`. - - -## OrderedSet in data science applications - -An OrderedSet can be used as a bi-directional mapping between a sparse -vocabulary and dense index numbers. As of version 3.1, it accepts NumPy arrays -of index numbers as well as lists. - -This combination of features makes OrderedSet a simple implementation of many -of the things that `pandas.Index` is used for, and many of its operations are -faster than the equivalent pandas operations. - -For further compatibility with pandas.Index, `get_loc` (the pandas method for -looking up a single index) and `get_indexer` (the pandas method for fancy -indexing in reverse) are both aliases for `index` (which handles both cases -in OrderedSet). - - -## Authors - -OrderedSet was implemented by Elia Robyn Lake (maiden name: Robyn Speer). -Jon Crall contributed changes and tests to make it fit the Python set API. -Roman Inflianskas added the original type annotations. - - -## Comparisons - -The original implementation of OrderedSet was a [recipe posted to ActiveState -Recipes][recipe] by Raymond Hettiger, released under the MIT license. - -[recipe]: https://code.activestate.com/recipes/576694-orderedset/ - -Hettiger's implementation kept its content in a doubly-linked list referenced by a -dict. As a result, looking up an item by its index was an O(N) operation, while -deletion was O(1). - -This version makes different trade-offs for the sake of efficient lookups. Its -content is a standard Python list instead of a doubly-linked list. This -provides O(1) lookups by index at the expense of O(N) deletion, as well as -slightly faster iteration. - -In Python 3.6 and later, the built-in `dict` type is inherently ordered. If you -ignore the dictionary values, that also gives you a simple ordered set, with -fast O(1) insertion, deletion, iteration and membership testing. However, `dict` -does not provide the list-like random access features of OrderedSet. You -would have to convert it to a list in O(N) to look up the index of an entry or -look up an entry by its index. - diff --git a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/RECORD b/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/RECORD deleted file mode 100644 index a9875cde..00000000 --- a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/RECORD +++ /dev/null @@ -1,8 +0,0 @@ -ordered_set-4.1.0.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4 -ordered_set-4.1.0.dist-info/METADATA,sha256=FqVN_VUTJTCDQ-vtnmXrbgapDjciET-54gSNJ47sro8,5340 -ordered_set-4.1.0.dist-info/RECORD,, -ordered_set-4.1.0.dist-info/REQUESTED,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 -ordered_set-4.1.0.dist-info/WHEEL,sha256=jPMR_Dzkc4X4icQtmz81lnNY_kAsfog7ry7qoRvYLXw,81 -ordered_set/__init__.py,sha256=ytazgKsyBKi9uFtBt938yXxQtdat1VCC681s9s0CMqg,17146 -ordered_set/__pycache__/__init__.cpython-312.pyc,, -ordered_set/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0 diff --git a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/REQUESTED b/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/REQUESTED deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/WHEEL b/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/WHEEL deleted file mode 100644 index c727d148..00000000 --- a/uno/lib/python/setuptools/_vendor/ordered_set-4.1.0.dist-info/WHEEL +++ /dev/null @@ -1,4 +0,0 @@ -Wheel-Version: 1.0 -Generator: flit 3.6.0 -Root-Is-Purelib: true -Tag: py3-none-any diff --git a/uno/lib/python/setuptools/_vendor/ordered_set/__init__.py b/uno/lib/python/setuptools/_vendor/ordered_set/__init__.py deleted file mode 100644 index e86c70ed..00000000 --- a/uno/lib/python/setuptools/_vendor/ordered_set/__init__.py +++ /dev/null @@ -1,536 +0,0 @@ -""" -An OrderedSet is a custom MutableSet that remembers its order, so that every -entry has an index that can be looked up. It can also act like a Sequence. - -Based on a recipe originally posted to ActiveState Recipes by Raymond Hettiger, -and released under the MIT license. -""" -import itertools as it -from typing import ( - Any, - Dict, - Iterable, - Iterator, - List, - MutableSet, - AbstractSet, - Sequence, - Set, - TypeVar, - Union, - overload, -) - -SLICE_ALL = slice(None) -__version__ = "4.1.0" - - -T = TypeVar("T") - -# SetLike[T] is either a set of elements of type T, or a sequence, which -# we will convert to an OrderedSet by adding its elements in order. -SetLike = Union[AbstractSet[T], Sequence[T]] -OrderedSetInitializer = Union[AbstractSet[T], Sequence[T], Iterable[T]] - - -def _is_atomic(obj: Any) -> bool: - """ - Returns True for objects which are iterable but should not be iterated in - the context of indexing an OrderedSet. - - When we index by an iterable, usually that means we're being asked to look - up a list of things. - - However, in the case of the .index() method, we shouldn't handle strings - and tuples like other iterables. They're not sequences of things to look - up, they're the single, atomic thing we're trying to find. - - As an example, oset.index('hello') should give the index of 'hello' in an - OrderedSet of strings. It shouldn't give the indexes of each individual - character. - """ - return isinstance(obj, str) or isinstance(obj, tuple) - - -class OrderedSet(MutableSet[T], Sequence[T]): - """ - An OrderedSet is a custom MutableSet that remembers its order, so that - every entry has an index that can be looked up. - - Example: - >>> OrderedSet([1, 1, 2, 3, 2]) - OrderedSet([1, 2, 3]) - """ - - def __init__(self, initial: OrderedSetInitializer[T] = None): - self.items: List[T] = [] - self.map: Dict[T, int] = {} - if initial is not None: - # In terms of duck-typing, the default __ior__ is compatible with - # the types we use, but it doesn't expect all the types we - # support as values for `initial`. - self |= initial # type: ignore - - def __len__(self): - """ - Returns the number of unique elements in the ordered set - - Example: - >>> len(OrderedSet([])) - 0 - >>> len(OrderedSet([1, 2])) - 2 - """ - return len(self.items) - - @overload - def __getitem__(self, index: slice) -> "OrderedSet[T]": - ... - - @overload - def __getitem__(self, index: Sequence[int]) -> List[T]: - ... - - @overload - def __getitem__(self, index: int) -> T: - ... - - # concrete implementation - def __getitem__(self, index): - """ - Get the item at a given index. - - If `index` is a slice, you will get back that slice of items, as a - new OrderedSet. - - If `index` is a list or a similar iterable, you'll get a list of - items corresponding to those indices. This is similar to NumPy's - "fancy indexing". The result is not an OrderedSet because you may ask - for duplicate indices, and the number of elements returned should be - the number of elements asked for. - - Example: - >>> oset = OrderedSet([1, 2, 3]) - >>> oset[1] - 2 - """ - if isinstance(index, slice) and index == SLICE_ALL: - return self.copy() - elif isinstance(index, Iterable): - return [self.items[i] for i in index] - elif isinstance(index, slice) or hasattr(index, "__index__"): - result = self.items[index] - if isinstance(result, list): - return self.__class__(result) - else: - return result - else: - raise TypeError("Don't know how to index an OrderedSet by %r" % index) - - def copy(self) -> "OrderedSet[T]": - """ - Return a shallow copy of this object. - - Example: - >>> this = OrderedSet([1, 2, 3]) - >>> other = this.copy() - >>> this == other - True - >>> this is other - False - """ - return self.__class__(self) - - # Define the gritty details of how an OrderedSet is serialized as a pickle. - # We leave off type annotations, because the only code that should interact - # with these is a generalized tool such as pickle. - def __getstate__(self): - if len(self) == 0: - # In pickle, the state can't be an empty list. - # We need to return a truthy value, or else __setstate__ won't be run. - # - # This could have been done more gracefully by always putting the state - # in a tuple, but this way is backwards- and forwards- compatible with - # previous versions of OrderedSet. - return (None,) - else: - return list(self) - - def __setstate__(self, state): - if state == (None,): - self.__init__([]) - else: - self.__init__(state) - - def __contains__(self, key: Any) -> bool: - """ - Test if the item is in this ordered set. - - Example: - >>> 1 in OrderedSet([1, 3, 2]) - True - >>> 5 in OrderedSet([1, 3, 2]) - False - """ - return key in self.map - - # Technically type-incompatible with MutableSet, because we return an - # int instead of nothing. This is also one of the things that makes - # OrderedSet convenient to use. - def add(self, key: T) -> int: - """ - Add `key` as an item to this OrderedSet, then return its index. - - If `key` is already in the OrderedSet, return the index it already - had. - - Example: - >>> oset = OrderedSet() - >>> oset.append(3) - 0 - >>> print(oset) - OrderedSet([3]) - """ - if key not in self.map: - self.map[key] = len(self.items) - self.items.append(key) - return self.map[key] - - append = add - - def update(self, sequence: SetLike[T]) -> int: - """ - Update the set with the given iterable sequence, then return the index - of the last element inserted. - - Example: - >>> oset = OrderedSet([1, 2, 3]) - >>> oset.update([3, 1, 5, 1, 4]) - 4 - >>> print(oset) - OrderedSet([1, 2, 3, 5, 4]) - """ - item_index = 0 - try: - for item in sequence: - item_index = self.add(item) - except TypeError: - raise ValueError( - "Argument needs to be an iterable, got %s" % type(sequence) - ) - return item_index - - @overload - def index(self, key: Sequence[T]) -> List[int]: - ... - - @overload - def index(self, key: T) -> int: - ... - - # concrete implementation - def index(self, key): - """ - Get the index of a given entry, raising an IndexError if it's not - present. - - `key` can be an iterable of entries that is not a string, in which case - this returns a list of indices. - - Example: - >>> oset = OrderedSet([1, 2, 3]) - >>> oset.index(2) - 1 - """ - if isinstance(key, Iterable) and not _is_atomic(key): - return [self.index(subkey) for subkey in key] - return self.map[key] - - # Provide some compatibility with pd.Index - get_loc = index - get_indexer = index - - def pop(self, index=-1) -> T: - """ - Remove and return item at index (default last). - - Raises KeyError if the set is empty. - Raises IndexError if index is out of range. - - Example: - >>> oset = OrderedSet([1, 2, 3]) - >>> oset.pop() - 3 - """ - if not self.items: - raise KeyError("Set is empty") - - elem = self.items[index] - del self.items[index] - del self.map[elem] - return elem - - def discard(self, key: T) -> None: - """ - Remove an element. Do not raise an exception if absent. - - The MutableSet mixin uses this to implement the .remove() method, which - *does* raise an error when asked to remove a non-existent item. - - Example: - >>> oset = OrderedSet([1, 2, 3]) - >>> oset.discard(2) - >>> print(oset) - OrderedSet([1, 3]) - >>> oset.discard(2) - >>> print(oset) - OrderedSet([1, 3]) - """ - if key in self: - i = self.map[key] - del self.items[i] - del self.map[key] - for k, v in self.map.items(): - if v >= i: - self.map[k] = v - 1 - - def clear(self) -> None: - """ - Remove all items from this OrderedSet. - """ - del self.items[:] - self.map.clear() - - def __iter__(self) -> Iterator[T]: - """ - Example: - >>> list(iter(OrderedSet([1, 2, 3]))) - [1, 2, 3] - """ - return iter(self.items) - - def __reversed__(self) -> Iterator[T]: - """ - Example: - >>> list(reversed(OrderedSet([1, 2, 3]))) - [3, 2, 1] - """ - return reversed(self.items) - - def __repr__(self) -> str: - if not self: - return "%s()" % (self.__class__.__name__,) - return "%s(%r)" % (self.__class__.__name__, list(self)) - - def __eq__(self, other: Any) -> bool: - """ - Returns true if the containers have the same items. If `other` is a - Sequence, then order is checked, otherwise it is ignored. - - Example: - >>> oset = OrderedSet([1, 3, 2]) - >>> oset == [1, 3, 2] - True - >>> oset == [1, 2, 3] - False - >>> oset == [2, 3] - False - >>> oset == OrderedSet([3, 2, 1]) - False - """ - if isinstance(other, Sequence): - # Check that this OrderedSet contains the same elements, in the - # same order, as the other object. - return list(self) == list(other) - try: - other_as_set = set(other) - except TypeError: - # If `other` can't be converted into a set, it's not equal. - return False - else: - return set(self) == other_as_set - - def union(self, *sets: SetLike[T]) -> "OrderedSet[T]": - """ - Combines all unique items. - Each items order is defined by its first appearance. - - Example: - >>> oset = OrderedSet.union(OrderedSet([3, 1, 4, 1, 5]), [1, 3], [2, 0]) - >>> print(oset) - OrderedSet([3, 1, 4, 5, 2, 0]) - >>> oset.union([8, 9]) - OrderedSet([3, 1, 4, 5, 2, 0, 8, 9]) - >>> oset | {10} - OrderedSet([3, 1, 4, 5, 2, 0, 10]) - """ - cls: type = OrderedSet - if isinstance(self, OrderedSet): - cls = self.__class__ - containers = map(list, it.chain([self], sets)) - items = it.chain.from_iterable(containers) - return cls(items) - - def __and__(self, other: SetLike[T]) -> "OrderedSet[T]": - # the parent implementation of this is backwards - return self.intersection(other) - - def intersection(self, *sets: SetLike[T]) -> "OrderedSet[T]": - """ - Returns elements in common between all sets. Order is defined only - by the first set. - - Example: - >>> oset = OrderedSet.intersection(OrderedSet([0, 1, 2, 3]), [1, 2, 3]) - >>> print(oset) - OrderedSet([1, 2, 3]) - >>> oset.intersection([2, 4, 5], [1, 2, 3, 4]) - OrderedSet([2]) - >>> oset.intersection() - OrderedSet([1, 2, 3]) - """ - cls: type = OrderedSet - items: OrderedSetInitializer[T] = self - if isinstance(self, OrderedSet): - cls = self.__class__ - if sets: - common = set.intersection(*map(set, sets)) - items = (item for item in self if item in common) - return cls(items) - - def difference(self, *sets: SetLike[T]) -> "OrderedSet[T]": - """ - Returns all elements that are in this set but not the others. - - Example: - >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2])) - OrderedSet([1, 3]) - >>> OrderedSet([1, 2, 3]).difference(OrderedSet([2]), OrderedSet([3])) - OrderedSet([1]) - >>> OrderedSet([1, 2, 3]) - OrderedSet([2]) - OrderedSet([1, 3]) - >>> OrderedSet([1, 2, 3]).difference() - OrderedSet([1, 2, 3]) - """ - cls = self.__class__ - items: OrderedSetInitializer[T] = self - if sets: - other = set.union(*map(set, sets)) - items = (item for item in self if item not in other) - return cls(items) - - def issubset(self, other: SetLike[T]) -> bool: - """ - Report whether another set contains this set. - - Example: - >>> OrderedSet([1, 2, 3]).issubset({1, 2}) - False - >>> OrderedSet([1, 2, 3]).issubset({1, 2, 3, 4}) - True - >>> OrderedSet([1, 2, 3]).issubset({1, 4, 3, 5}) - False - """ - if len(self) > len(other): # Fast check for obvious cases - return False - return all(item in other for item in self) - - def issuperset(self, other: SetLike[T]) -> bool: - """ - Report whether this set contains another set. - - Example: - >>> OrderedSet([1, 2]).issuperset([1, 2, 3]) - False - >>> OrderedSet([1, 2, 3, 4]).issuperset({1, 2, 3}) - True - >>> OrderedSet([1, 4, 3, 5]).issuperset({1, 2, 3}) - False - """ - if len(self) < len(other): # Fast check for obvious cases - return False - return all(item in self for item in other) - - def symmetric_difference(self, other: SetLike[T]) -> "OrderedSet[T]": - """ - Return the symmetric difference of two OrderedSets as a new set. - That is, the new set will contain all elements that are in exactly - one of the sets. - - Their order will be preserved, with elements from `self` preceding - elements from `other`. - - Example: - >>> this = OrderedSet([1, 4, 3, 5, 7]) - >>> other = OrderedSet([9, 7, 1, 3, 2]) - >>> this.symmetric_difference(other) - OrderedSet([4, 5, 9, 2]) - """ - cls: type = OrderedSet - if isinstance(self, OrderedSet): - cls = self.__class__ - diff1 = cls(self).difference(other) - diff2 = cls(other).difference(self) - return diff1.union(diff2) - - def _update_items(self, items: list) -> None: - """ - Replace the 'items' list of this OrderedSet with a new one, updating - self.map accordingly. - """ - self.items = items - self.map = {item: idx for (idx, item) in enumerate(items)} - - def difference_update(self, *sets: SetLike[T]) -> None: - """ - Update this OrderedSet to remove items from one or more other sets. - - Example: - >>> this = OrderedSet([1, 2, 3]) - >>> this.difference_update(OrderedSet([2, 4])) - >>> print(this) - OrderedSet([1, 3]) - - >>> this = OrderedSet([1, 2, 3, 4, 5]) - >>> this.difference_update(OrderedSet([2, 4]), OrderedSet([1, 4, 6])) - >>> print(this) - OrderedSet([3, 5]) - """ - items_to_remove = set() # type: Set[T] - for other in sets: - items_as_set = set(other) # type: Set[T] - items_to_remove |= items_as_set - self._update_items([item for item in self.items if item not in items_to_remove]) - - def intersection_update(self, other: SetLike[T]) -> None: - """ - Update this OrderedSet to keep only items in another set, preserving - their order in this set. - - Example: - >>> this = OrderedSet([1, 4, 3, 5, 7]) - >>> other = OrderedSet([9, 7, 1, 3, 2]) - >>> this.intersection_update(other) - >>> print(this) - OrderedSet([1, 3, 7]) - """ - other = set(other) - self._update_items([item for item in self.items if item in other]) - - def symmetric_difference_update(self, other: SetLike[T]) -> None: - """ - Update this OrderedSet to remove items from another set, then - add items from the other set that were not present in this set. - - Example: - >>> this = OrderedSet([1, 4, 3, 5, 7]) - >>> other = OrderedSet([9, 7, 1, 3, 2]) - >>> this.symmetric_difference_update(other) - >>> print(this) - OrderedSet([4, 5, 9, 2]) - """ - items_to_add = [item for item in other if item not in self] - items_to_remove = set(other) - self._update_items( - [item for item in self.items if item not in items_to_remove] + items_to_add - ) diff --git a/uno/lib/python/setuptools/_vendor/ordered_set/py.typed b/uno/lib/python/setuptools/_vendor/ordered_set/py.typed deleted file mode 100644 index e69de29b..00000000 diff --git a/uno/lib/python/setuptools/archive_util.py b/uno/lib/python/setuptools/archive_util.py index 6b8460bd..e4acd75f 100644 --- a/uno/lib/python/setuptools/archive_util.py +++ b/uno/lib/python/setuptools/archive_util.py @@ -1,15 +1,16 @@ """Utilities for extracting common archive formats""" -import zipfile -import tarfile +import contextlib import os -import shutil import posixpath -import contextlib -from distutils.errors import DistutilsError +import shutil +import tarfile +import zipfile from ._path import ensure_directory +from distutils.errors import DistutilsError + __all__ = [ "unpack_archive", "unpack_zipfile", diff --git a/uno/lib/python/setuptools/build_meta.py b/uno/lib/python/setuptools/build_meta.py index c52c872f..76633068 100644 --- a/uno/lib/python/setuptools/build_meta.py +++ b/uno/lib/python/setuptools/build_meta.py @@ -28,26 +28,31 @@ from __future__ import annotations +import contextlib import io import os import shlex -import sys -import tokenize import shutil -import contextlib +import sys import tempfile +import tokenize import warnings from pathlib import Path -from typing import Dict, Iterator, List, Optional, Union, Iterable +from typing import TYPE_CHECKING, Dict, Iterable, Iterator, List, Union import setuptools -import distutils + from . import errors -from ._path import same_path, StrPath +from ._path import StrPath, same_path from ._reqs import parse_strings from .warnings import SetuptoolsDeprecationWarning + +import distutils from distutils.util import strtobool +if TYPE_CHECKING: + from typing_extensions import TypeAlias + __all__ = [ 'get_requires_for_build_sdist', @@ -142,7 +147,7 @@ def suppress_known_deprecation(): yield -_ConfigSettings = Optional[Dict[str, Union[str, List[str], None]]] +_ConfigSettings: TypeAlias = Union[Dict[str, Union[str, List[str], None]], None] """ Currently the user can run:: diff --git a/uno/lib/python/setuptools/command/__init__.py b/uno/lib/python/setuptools/command/__init__.py index 5acd7687..bf011e89 100644 --- a/uno/lib/python/setuptools/command/__init__.py +++ b/uno/lib/python/setuptools/command/__init__.py @@ -1,6 +1,7 @@ -from distutils.command.bdist import bdist import sys +from distutils.command.bdist import bdist + if 'egg' not in bdist.format_commands: try: bdist.format_commands['egg'] = ('bdist_egg', "Python .egg file") diff --git a/uno/lib/python/setuptools/command/_requirestxt.py b/uno/lib/python/setuptools/command/_requirestxt.py index ef35d183..b87476d6 100644 --- a/uno/lib/python/setuptools/command/_requirestxt.py +++ b/uno/lib/python/setuptools/command/_requirestxt.py @@ -14,10 +14,10 @@ from itertools import filterfalse from typing import Dict, Mapping, TypeVar -from .. import _reqs from jaraco.text import yield_lines from packaging.requirements import Requirement +from .. import _reqs # dict can work as an ordered set _T = TypeVar("_T") diff --git a/uno/lib/python/setuptools/command/alias.py b/uno/lib/python/setuptools/command/alias.py index e7b4d545..4eed6523 100644 --- a/uno/lib/python/setuptools/command/alias.py +++ b/uno/lib/python/setuptools/command/alias.py @@ -1,6 +1,6 @@ -from distutils.errors import DistutilsOptionError +from setuptools.command.setopt import config_file, edit_config, option_base -from setuptools.command.setopt import edit_config, option_base, config_file +from distutils.errors import DistutilsOptionError def shquote(arg): diff --git a/uno/lib/python/setuptools/command/bdist_egg.py b/uno/lib/python/setuptools/command/bdist_egg.py index 559f7d60..f3b71502 100644 --- a/uno/lib/python/setuptools/command/bdist_egg.py +++ b/uno/lib/python/setuptools/command/bdist_egg.py @@ -2,20 +2,21 @@ Build .egg distributions""" -from distutils.dir_util import remove_tree, mkpath -from distutils import log -from types import CodeType -import sys +import marshal import os import re +import sys import textwrap -import marshal +from sysconfig import get_path, get_python_version +from types import CodeType -from setuptools.extension import Library from setuptools import Command +from setuptools.extension import Library + from .._path import ensure_directory -from sysconfig import get_path, get_python_version +from distutils import log +from distutils.dir_util import mkpath, remove_tree def _get_purelib(): diff --git a/uno/lib/python/setuptools/command/bdist_rpm.py b/uno/lib/python/setuptools/command/bdist_rpm.py index 70ed6b60..e0d4caf2 100644 --- a/uno/lib/python/setuptools/command/bdist_rpm.py +++ b/uno/lib/python/setuptools/command/bdist_rpm.py @@ -1,7 +1,8 @@ -import distutils.command.bdist_rpm as orig - +from ..dist import Distribution from ..warnings import SetuptoolsDeprecationWarning +import distutils.command.bdist_rpm as orig + class bdist_rpm(orig.bdist_rpm): """ @@ -12,6 +13,8 @@ class bdist_rpm(orig.bdist_rpm): disable eggs in RPM distributions. """ + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + def run(self): SetuptoolsDeprecationWarning.emit( "Deprecated command", diff --git a/uno/lib/python/setuptools/command/bdist_wheel.py b/uno/lib/python/setuptools/command/bdist_wheel.py index 5b9bcec6..8f067866 100644 --- a/uno/lib/python/setuptools/command/bdist_wheel.py +++ b/uno/lib/python/setuptools/command/bdist_wheel.py @@ -16,20 +16,22 @@ import warnings from email.generator import BytesGenerator, Generator from email.policy import EmailPolicy -from distutils import log from glob import iglob from shutil import rmtree from typing import TYPE_CHECKING, Callable, Iterable, Literal, Sequence, cast from zipfile import ZIP_DEFLATED, ZIP_STORED -from .. import Command, __version__ +from packaging import tags, version as _packaging_version from wheel.metadata import pkginfo_to_metadata -from packaging import tags -from packaging import version as _packaging_version from wheel.wheelfile import WheelFile +from .. import Command, __version__ +from .egg_info import egg_info as egg_info_cls + +from distutils import log + if TYPE_CHECKING: - import types + from _typeshed import ExcInfo def safe_name(name: str) -> str: @@ -152,12 +154,14 @@ def safer_version(version: str) -> str: def remove_readonly( func: Callable[..., object], path: str, - excinfo: tuple[type[Exception], Exception, types.TracebackType], + excinfo: ExcInfo, ) -> None: remove_readonly_exc(func, path, excinfo[1]) -def remove_readonly_exc(func: Callable[..., object], path: str, exc: Exception) -> None: +def remove_readonly_exc( + func: Callable[..., object], path: str, exc: BaseException +) -> None: os.chmod(path, stat.S_IWRITE) func(path) @@ -232,40 +236,35 @@ class bdist_wheel(Command): def initialize_options(self) -> None: self.bdist_dir: str | None = None - self.data_dir = None + self.data_dir: str | None = None self.plat_name: str | None = None - self.plat_tag = None + self.plat_tag: str | None = None self.format = "zip" self.keep_temp = False self.dist_dir: str | None = None - self.egginfo_dir = None + self.egginfo_dir: str | None = None self.root_is_pure: bool | None = None - self.skip_build = None + self.skip_build = False self.relative = False self.owner = None self.group = None self.universal: bool = False - self.compression: str | int = "deflated" + self.compression: int | str = "deflated" self.python_tag: str = python_tag() self.build_number: str | None = None self.py_limited_api: str | Literal[False] = False self.plat_name_supplied = False - def finalize_options(self): - if self.bdist_dir is None: + def finalize_options(self) -> None: + if not self.bdist_dir: bdist_base = self.get_finalized_command("bdist").bdist_base self.bdist_dir = os.path.join(bdist_base, "wheel") - egg_info = self.distribution.get_command_obj("egg_info") + egg_info = cast(egg_info_cls, self.distribution.get_command_obj("egg_info")) egg_info.ensure_finalized() # needed for correct `wheel_dist_name` self.data_dir = self.wheel_dist_name + ".data" - self.plat_name_supplied = self.plat_name is not None - - try: - self.compression = self.supported_compressions[self.compression] - except KeyError: - raise ValueError(f"Unsupported compression: {self.compression}") from None + self.plat_name_supplied = bool(self.plat_name) need_options = ("dist_dir", "plat_name", "skip_build") @@ -275,10 +274,7 @@ def finalize_options(self): self.distribution.has_ext_modules() or self.distribution.has_c_libraries() ) - if self.py_limited_api and not re.match( - PY_LIMITED_API_PATTERN, self.py_limited_api - ): - raise ValueError(f"py-limited-api must match '{PY_LIMITED_API_PATTERN}'") + self._validate_py_limited_api() # Support legacy [wheel] section for setting universal wheel = self.distribution.get_option_dict("wheel") @@ -292,22 +288,37 @@ def finalize_options(self): if self.build_number is not None and not self.build_number[:1].isdigit(): raise ValueError("Build tag (build-number) must start with a digit.") + def _validate_py_limited_api(self) -> None: + if not self.py_limited_api: + return + + if not re.match(PY_LIMITED_API_PATTERN, self.py_limited_api): + raise ValueError(f"py-limited-api must match '{PY_LIMITED_API_PATTERN}'") + + if sysconfig.get_config_var("Py_GIL_DISABLED"): + raise ValueError( + f"`py_limited_api={self.py_limited_api!r}` not supported. " + "`Py_LIMITED_API` is currently incompatible with " + f"`Py_GIL_DISABLED` ({sys.abiflags=!r}). " + "See https://github.com/python/cpython/issues/111506." + ) + @property - def wheel_dist_name(self): + def wheel_dist_name(self) -> str: """Return distribution full name with - replaced with _""" - components = ( + components = [ safer_name(self.distribution.get_name()), safer_version(self.distribution.get_version()), - ) + ] if self.build_number: - components += (self.build_number,) + components.append(self.build_number) return "-".join(components) def get_tag(self) -> tuple[str, str, str]: # bdist sets self.plat_name if unset, we should only use it for purepy # wheels if the user supplied it. - if self.plat_name_supplied: - plat_name = cast(str, self.plat_name) + if self.plat_name_supplied and self.plat_name: + plat_name = self.plat_name elif self.root_is_pure: plat_name = "any" else: @@ -431,7 +442,7 @@ def run(self): os.makedirs(self.dist_dir) wheel_path = os.path.join(self.dist_dir, archive_basename + ".whl") - with WheelFile(wheel_path, "w", self.compression) as wf: + with WheelFile(wheel_path, "w", self._zip_compression()) as wf: wf.write_files(archive_root) # Add to 'Distribution.dist_files' so that the "upload" command works @@ -595,3 +606,16 @@ def adios(p: str) -> None: shutil.copy(license_path, os.path.join(distinfo_path, filename)) adios(egginfo_path) + + def _zip_compression(self) -> int: + if ( + isinstance(self.compression, int) + and self.compression in self.supported_compressions.values() + ): + return self.compression + + compression = self.supported_compressions.get(str(self.compression)) + if compression is not None: + return compression + + raise ValueError(f"Unsupported compression: {self.compression!r}") diff --git a/uno/lib/python/setuptools/command/build.py b/uno/lib/python/setuptools/command/build.py index bc765a17..0c5e5448 100644 --- a/uno/lib/python/setuptools/command/build.py +++ b/uno/lib/python/setuptools/command/build.py @@ -1,12 +1,17 @@ from __future__ import annotations from typing import Protocol + +from ..dist import Distribution + from distutils.command.build import build as _build _ORIGINAL_SUBCOMMANDS = {"build_py", "build_clib", "build_ext", "build_scripts"} class build(_build): + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + # copy to avoid sharing the object with parent class sub_commands = _build.sub_commands[:] diff --git a/uno/lib/python/setuptools/command/build_clib.py b/uno/lib/python/setuptools/command/build_clib.py index acd4d1d3..9db57ac8 100644 --- a/uno/lib/python/setuptools/command/build_clib.py +++ b/uno/lib/python/setuptools/command/build_clib.py @@ -1,6 +1,8 @@ +from ..dist import Distribution + import distutils.command.build_clib as orig -from distutils.errors import DistutilsSetupError from distutils import log +from distutils.errors import DistutilsSetupError try: from distutils._modified import newer_pairwise_group @@ -25,6 +27,8 @@ class build_clib(orig.build_clib): the compiler. """ + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + def build_libraries(self, libraries): for lib_name, build_info in libraries: sources = build_info.get('sources') diff --git a/uno/lib/python/setuptools/command/build_ext.py b/uno/lib/python/setuptools/command/build_ext.py index 508704f3..51c1771a 100644 --- a/uno/lib/python/setuptools/command/build_ext.py +++ b/uno/lib/python/setuptools/command/build_ext.py @@ -1,30 +1,32 @@ from __future__ import annotations +import itertools import os import sys -import itertools from importlib.machinery import EXTENSION_SUFFIXES from importlib.util import cache_from_source as _compiled_file_name -from typing import Iterator from pathlib import Path +from typing import Iterator -from distutils.command.build_ext import build_ext as _du_build_ext -from distutils.ccompiler import new_compiler -from distutils.sysconfig import customize_compiler, get_config_var -from distutils import log - +from setuptools.dist import Distribution from setuptools.errors import BaseError from setuptools.extension import Extension, Library +from distutils import log +from distutils.ccompiler import new_compiler +from distutils.sysconfig import customize_compiler, get_config_var + try: # Attempt to use Cython for building extensions, if available - from Cython.Distutils.build_ext import build_ext as _build_ext # type: ignore[import-not-found] # Cython not installed on CI tests + from Cython.Distutils.build_ext import ( # type: ignore[import-not-found] # Cython not installed on CI tests + build_ext as _build_ext, + ) # Additionally, assert that the compiler module will load # also. Ref #1229. __import__('Cython.Compiler.Main') except ImportError: - _build_ext = _du_build_ext + from distutils.command.build_ext import build_ext as _build_ext # make sure _config_vars is initialized get_config_var("LDSHARED") @@ -84,6 +86,7 @@ def get_abi3_suffix(): class build_ext(_build_ext): + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution editable_mode: bool = False inplace: bool = False diff --git a/uno/lib/python/setuptools/command/build_py.py b/uno/lib/python/setuptools/command/build_py.py index 15a4f63f..e6d9656f 100644 --- a/uno/lib/python/setuptools/command/build_py.py +++ b/uno/lib/python/setuptools/command/build_py.py @@ -1,21 +1,23 @@ from __future__ import annotations -from functools import partial -from glob import glob -from distutils.util import convert_path -import distutils.command.build_py as orig -import os import fnmatch -import textwrap -import distutils.errors import itertools +import os import stat +import textwrap +from functools import partial +from glob import glob from pathlib import Path from typing import Iterable, Iterator from more_itertools import unique_everseen + +from ..dist import Distribution from ..warnings import SetuptoolsDeprecationWarning +import distutils.command.build_py as orig +import distutils.errors +from distutils.util import convert_path _IMPLICIT_DATA_FILES = ('*.pyi', 'py.typed') @@ -34,6 +36,7 @@ class build_py(orig.build_py): 'py_modules' and 'packages' in the same setup operation. """ + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution editable_mode: bool = False existing_egg_info_dir: str | None = None #: Private API, internal use only. diff --git a/uno/lib/python/setuptools/command/develop.py b/uno/lib/python/setuptools/command/develop.py index 55f24f39..1938434b 100644 --- a/uno/lib/python/setuptools/command/develop.py +++ b/uno/lib/python/setuptools/command/develop.py @@ -1,17 +1,16 @@ -from distutils.util import convert_path -from distutils import log -from distutils.errors import DistutilsOptionError -import os import glob +import os -from setuptools.command.easy_install import easy_install -from setuptools import _normalization -from setuptools import _path -from setuptools import namespaces import setuptools +from setuptools import _normalization, _path, namespaces +from setuptools.command.easy_install import easy_install from ..unicode_utils import _read_utf8_with_fallback +from distutils import log +from distutils.errors import DistutilsOptionError +from distutils.util import convert_path + class develop(namespaces.DevelopInstaller, easy_install): """Set up package for development""" diff --git a/uno/lib/python/setuptools/command/dist_info.py b/uno/lib/python/setuptools/command/dist_info.py index 2adc1c46..1db3fbf6 100644 --- a/uno/lib/python/setuptools/command/dist_info.py +++ b/uno/lib/python/setuptools/command/dist_info.py @@ -6,14 +6,15 @@ import os import shutil from contextlib import contextmanager -from distutils import log -from distutils.core import Command from pathlib import Path from typing import cast from .. import _normalization from .egg_info import egg_info as egg_info_cls +from distutils import log +from distutils.core import Command + class dist_info(Command): """ diff --git a/uno/lib/python/setuptools/command/easy_install.py b/uno/lib/python/setuptools/command/easy_install.py index 36114d40..54d1e484 100644 --- a/uno/lib/python/setuptools/command/easy_install.py +++ b/uno/lib/python/setuptools/command/easy_install.py @@ -12,72 +12,72 @@ from __future__ import annotations -from glob import glob -from distutils.util import get_platform -from distutils.util import convert_path, subst_vars -from distutils.errors import ( - DistutilsArgError, - DistutilsOptionError, - DistutilsError, - DistutilsPlatformError, -) -from distutils import log, dir_util -from distutils.command.build_scripts import first_line_re -from distutils.command import install -import sys +import configparser +import contextlib +import io import os -import zipimport -import shutil -import tempfile -import zipfile -import re -import stat import random -import textwrap -import warnings +import re +import shlex +import shutil import site +import stat import struct -import contextlib import subprocess -import shlex -import io -import configparser +import sys import sysconfig - +import tempfile +import textwrap +import warnings +import zipfile +import zipimport +from collections.abc import Iterable +from glob import glob from sysconfig import get_path +from typing import TYPE_CHECKING -from setuptools import Command -from setuptools.sandbox import run_setup -from setuptools.command import setopt -from setuptools.archive_util import unpack_archive -from setuptools.package_index import ( - PackageIndex, - parse_requirement_arg, - URL_SCHEME, -) -from setuptools.command import bdist_egg, egg_info -from setuptools.warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning -from setuptools.wheel import Wheel +from jaraco.text import yield_lines + +import pkg_resources from pkg_resources import ( - normalize_path, - resource_string, - get_distribution, - find_distributions, - Environment, - Requirement, + DEVELOP_DIST, Distribution, - PathMetadata, - EggMetadata, - WorkingSet, DistributionNotFound, + EggMetadata, + Environment, + PathMetadata, + Requirement, VersionConflict, - DEVELOP_DIST, + WorkingSet, + find_distributions, + get_distribution, + normalize_path, + resource_string, ) -import pkg_resources -from ..compat import py39, py311 +from setuptools import Command +from setuptools.archive_util import unpack_archive +from setuptools.command import bdist_egg, egg_info, setopt +from setuptools.package_index import URL_SCHEME, PackageIndex, parse_requirement_arg +from setuptools.sandbox import run_setup +from setuptools.warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning +from setuptools.wheel import Wheel + from .._path import ensure_directory -from jaraco.text import yield_lines +from ..compat import py39, py311 + +from distutils import dir_util, log +from distutils.command import install +from distutils.command.build_scripts import first_line_re +from distutils.errors import ( + DistutilsArgError, + DistutilsError, + DistutilsOptionError, + DistutilsPlatformError, +) +from distutils.util import convert_path, get_platform, subst_vars +if TYPE_CHECKING: + from typing_extensions import Self # Turn on PEP440Warnings warnings.filterwarnings("default", category=pkg_resources.PEP440Warning) @@ -2055,19 +2055,21 @@ def _sys_executable(cls): return os.environ.get('__PYVENV_LAUNCHER__', _default) @classmethod - def from_param(cls, param): + def from_param(cls, param: Self | str | Iterable[str] | None) -> Self: """ Construct a CommandSpec from a parameter to build_scripts, which may be None. """ if isinstance(param, cls): return param - if isinstance(param, list): + if isinstance(param, str): + return cls.from_string(param) + if isinstance(param, Iterable): return cls(param) if param is None: return cls.from_environment() - # otherwise, assume it's a string. - return cls.from_string(param) + # AttributeError to keep backwards compatibility, this should really be a TypeError though + raise AttributeError(f"Argument has an unsupported type {type(param)}") @classmethod def from_environment(cls): diff --git a/uno/lib/python/setuptools/command/editable_wheel.py b/uno/lib/python/setuptools/command/editable_wheel.py index 49fd609b..46852c1a 100644 --- a/uno/lib/python/setuptools/command/editable_wheel.py +++ b/uno/lib/python/setuptools/command/editable_wheel.py @@ -12,8 +12,8 @@ from __future__ import annotations -import logging import io +import logging import os import shutil import traceback @@ -23,32 +23,14 @@ from itertools import chain, starmap from pathlib import Path from tempfile import TemporaryDirectory -from typing import ( - TYPE_CHECKING, - Iterable, - Iterator, - Mapping, - Protocol, - TypeVar, - cast, -) - -from .. import ( - Command, - _normalization, - _path, - errors, - namespaces, -) +from typing import TYPE_CHECKING, Iterable, Iterator, Mapping, Protocol, TypeVar, cast + +from .. import Command, _normalization, _path, errors, namespaces from .._path import StrPath from ..compat import py39 from ..discovery import find_package_path from ..dist import Distribution -from ..warnings import ( - InformationOnly, - SetuptoolsDeprecationWarning, - SetuptoolsWarning, -) +from ..warnings import InformationOnly, SetuptoolsDeprecationWarning, SetuptoolsWarning from .build import build as build_cls from .build_py import build_py as build_py_cls from .dist_info import dist_info as dist_info_cls @@ -153,6 +135,7 @@ def run(self): self._create_wheel_file(bdist_wheel) except Exception: traceback.print_exc() + # TODO: Fix false-positive [attr-defined] in typeshed project = self.distribution.name or self.distribution.get_name() _DebuggingTips.emit(project=project) raise @@ -466,8 +449,9 @@ def _create_file(self, relative_output: str, src_file: str, link=None): def _create_links(self, outputs, output_mapping): self.auxiliary_dir.mkdir(parents=True, exist_ok=True) link_type = "sym" if _can_symlink_files(self.auxiliary_dir) else "hard" - mappings = {self._normalize_output(k): v for k, v in output_mapping.items()} - mappings.pop(None, None) # remove files that are not relative to build_lib + normalised = ((self._normalize_output(k), v) for k, v in output_mapping.items()) + # remove files that are not relative to build_lib + mappings = {k: v for k, v in normalised if k is not None} for output in outputs: relative = self._normalize_output(output) diff --git a/uno/lib/python/setuptools/command/egg_info.py b/uno/lib/python/setuptools/command/egg_info.py index 30b62f5f..09255a32 100644 --- a/uno/lib/python/setuptools/command/egg_info.py +++ b/uno/lib/python/setuptools/command/egg_info.py @@ -2,34 +2,35 @@ Create a distribution's .egg-info directory and contents""" -from distutils.filelist import FileList as _FileList -from distutils.errors import DistutilsInternalError -from distutils.util import convert_path -from distutils import log -import distutils.errors -import distutils.filelist +import collections import functools import os import re import sys import time -import collections -from .._importlib import metadata -from .. import _entry_points, _normalization -from . import _requirestxt +import packaging +import packaging.requirements +import packaging.version +import setuptools.unicode_utils as unicode_utils from setuptools import Command -from setuptools.command.sdist import sdist -from setuptools.command.sdist import walk_revctrl -from setuptools.command.setopt import edit_config from setuptools.command import bdist_egg -import setuptools.unicode_utils as unicode_utils +from setuptools.command.sdist import sdist, walk_revctrl +from setuptools.command.setopt import edit_config from setuptools.glob import glob -import packaging +from .. import _entry_points, _normalization +from .._importlib import metadata from ..warnings import SetuptoolsDeprecationWarning +from . import _requirestxt +import distutils.errors +import distutils.filelist +from distutils import log +from distutils.errors import DistutilsInternalError +from distutils.filelist import FileList as _FileList +from distutils.util import convert_path PY_MAJOR = '{}.{}'.format(*sys.version_info) diff --git a/uno/lib/python/setuptools/command/install.py b/uno/lib/python/setuptools/command/install.py index f1ea2adf..e2ec1abd 100644 --- a/uno/lib/python/setuptools/command/install.py +++ b/uno/lib/python/setuptools/command/install.py @@ -1,17 +1,20 @@ from __future__ import annotations -from collections.abc import Callable -from distutils.errors import DistutilsArgError -import inspect import glob +import inspect import platform -import distutils.command.install as orig +from collections.abc import Callable from typing import Any, ClassVar, cast import setuptools + +from ..dist import Distribution from ..warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning from .bdist_egg import bdist_egg as bdist_egg_cls +import distutils.command.install as orig +from distutils.errors import DistutilsArgError + # Prior to numpy 1.9, NumPy relies on the '_install' name, so provide it for # now. See https://github.com/pypa/setuptools/issues/199/ _install = orig.install @@ -20,6 +23,8 @@ class install(orig.install): """Use easy_install to install the package, w/dependencies""" + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + user_options = orig.install.user_options + [ ('old-and-unmanageable', None, "Try not to use this!"), ( diff --git a/uno/lib/python/setuptools/command/install_egg_info.py b/uno/lib/python/setuptools/command/install_egg_info.py index a1d2e818..be47254f 100644 --- a/uno/lib/python/setuptools/command/install_egg_info.py +++ b/uno/lib/python/setuptools/command/install_egg_info.py @@ -1,11 +1,12 @@ -from distutils import log, dir_util import os -from setuptools import Command -from setuptools import namespaces +from setuptools import Command, namespaces from setuptools.archive_util import unpack_archive + from .._path import ensure_directory +from distutils import dir_util, log + class install_egg_info(namespaces.Installer, Command): """Install an .egg-info directory for the package""" diff --git a/uno/lib/python/setuptools/command/install_lib.py b/uno/lib/python/setuptools/command/install_lib.py index 3c77c6eb..292f07ab 100644 --- a/uno/lib/python/setuptools/command/install_lib.py +++ b/uno/lib/python/setuptools/command/install_lib.py @@ -1,14 +1,20 @@ from __future__ import annotations + import os import sys from itertools import product, starmap -import distutils.command.install_lib as orig + from .._path import StrPath +from ..dist import Distribution + +import distutils.command.install_lib as orig class install_lib(orig.install_lib): """Don't add compiled flags to filenames of non-Python files""" + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + def run(self): self.build() outfiles = self.install() @@ -103,6 +109,7 @@ def copy_tree( # Exclude namespace package __init__.py* files from the output from setuptools.archive_util import unpack_directory + from distutils import log outfiles: list[str] = [] diff --git a/uno/lib/python/setuptools/command/install_scripts.py b/uno/lib/python/setuptools/command/install_scripts.py index f44281b4..7b90611d 100644 --- a/uno/lib/python/setuptools/command/install_scripts.py +++ b/uno/lib/python/setuptools/command/install_scripts.py @@ -1,16 +1,20 @@ from __future__ import annotations -from distutils import log -import distutils.command.install_scripts as orig import os import sys from .._path import ensure_directory +from ..dist import Distribution + +import distutils.command.install_scripts as orig +from distutils import log class install_scripts(orig.install_scripts): """Do normal script install, plus any egg_info wrapper scripts""" + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + def initialize_options(self): orig.install_scripts.initialize_options(self) self.no_ep = False @@ -29,6 +33,7 @@ def run(self) -> None: def _install_ep_scripts(self): # Delay import side-effects from pkg_resources import Distribution, PathMetadata + from . import easy_install as ei ei_cmd = self.get_finalized_command("egg_info") diff --git a/uno/lib/python/setuptools/command/register.py b/uno/lib/python/setuptools/command/register.py index beee9782..93ef04aa 100644 --- a/uno/lib/python/setuptools/command/register.py +++ b/uno/lib/python/setuptools/command/register.py @@ -1,12 +1,16 @@ -from distutils import log -import distutils.command.register as orig - from setuptools.errors import RemovedCommandError +from ..dist import Distribution + +import distutils.command.register as orig +from distutils import log + class register(orig.register): """Formerly used to register packages on PyPI.""" + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + def run(self): msg = ( "The register command has been removed, use twine to upload " diff --git a/uno/lib/python/setuptools/command/rotate.py b/uno/lib/python/setuptools/command/rotate.py index 064d7959..dcdfafbc 100644 --- a/uno/lib/python/setuptools/command/rotate.py +++ b/uno/lib/python/setuptools/command/rotate.py @@ -1,13 +1,14 @@ from __future__ import annotations -from distutils.util import convert_path -from distutils import log -from distutils.errors import DistutilsOptionError import os import shutil from setuptools import Command +from distutils import log +from distutils.errors import DistutilsOptionError +from distutils.util import convert_path + class rotate(Command): """Delete older distributions""" diff --git a/uno/lib/python/setuptools/command/sdist.py b/uno/lib/python/setuptools/command/sdist.py index a834ba4a..23393c07 100644 --- a/uno/lib/python/setuptools/command/sdist.py +++ b/uno/lib/python/setuptools/command/sdist.py @@ -1,12 +1,14 @@ -from distutils import log -import distutils.command.sdist as orig -import os import contextlib +import os from itertools import chain from .._importlib import metadata +from ..dist import Distribution from .build import _ORIGINAL_SUBCOMMANDS +import distutils.command.sdist as orig +from distutils import log + _default_revctrl = list @@ -43,6 +45,7 @@ class sdist(orig.sdist): ), ] + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution negative_opt = {} README_EXTENSIONS = ['', '.rst', '.txt', '.md'] diff --git a/uno/lib/python/setuptools/command/setopt.py b/uno/lib/python/setuptools/command/setopt.py index b78d845e..e351af22 100644 --- a/uno/lib/python/setuptools/command/setopt.py +++ b/uno/lib/python/setuptools/command/setopt.py @@ -1,13 +1,14 @@ -from distutils.util import convert_path -from distutils import log -from distutils.errors import DistutilsOptionError -import distutils -import os import configparser +import os from .. import Command from ..unicode_utils import _cfg_read_utf8_with_fallback +import distutils +from distutils import log +from distutils.errors import DistutilsOptionError +from distutils.util import convert_path + __all__ = ['config_file', 'edit_config', 'option_base', 'setopt'] diff --git a/uno/lib/python/setuptools/command/upload.py b/uno/lib/python/setuptools/command/upload.py index 1cca47ce..649b41fa 100644 --- a/uno/lib/python/setuptools/command/upload.py +++ b/uno/lib/python/setuptools/command/upload.py @@ -1,12 +1,15 @@ +from setuptools.dist import Distribution +from setuptools.errors import RemovedCommandError + from distutils import log from distutils.command import upload as orig -from setuptools.errors import RemovedCommandError - class upload(orig.upload): """Formerly used to upload packages to PyPI.""" + distribution: Distribution # override distutils.dist.Distribution with setuptools.dist.Distribution + def run(self): msg = ( "The upload command has been removed, use twine to upload " diff --git a/uno/lib/python/setuptools/command/upload_docs.py b/uno/lib/python/setuptools/command/upload_docs.py index 32c9abd7..3c2946cf 100644 --- a/uno/lib/python/setuptools/command/upload_docs.py +++ b/uno/lib/python/setuptools/command/upload_docs.py @@ -4,23 +4,23 @@ sites other than PyPi such as devpi). """ -from base64 import standard_b64encode -from distutils import log -from distutils.errors import DistutilsOptionError -import os -import zipfile -import tempfile -import shutil -import itertools import functools import http.client +import itertools +import os +import shutil +import tempfile import urllib.parse +import zipfile +from base64 import standard_b64encode from .._importlib import metadata from ..warnings import SetuptoolsDeprecationWarning - from .upload import upload +from distutils import log +from distutils.errors import DistutilsOptionError + def _encode(s): return s.encode('utf-8', 'surrogateescape') diff --git a/uno/lib/python/setuptools/compat/py310.py b/uno/lib/python/setuptools/compat/py310.py index cc875c00..b3912f8e 100644 --- a/uno/lib/python/setuptools/compat/py310.py +++ b/uno/lib/python/setuptools/compat/py310.py @@ -1,6 +1,5 @@ import sys - __all__ = ['tomllib'] diff --git a/uno/lib/python/setuptools/compat/py311.py b/uno/lib/python/setuptools/compat/py311.py index 5069c441..52b58af3 100644 --- a/uno/lib/python/setuptools/compat/py311.py +++ b/uno/lib/python/setuptools/compat/py311.py @@ -2,13 +2,14 @@ import shutil import sys -from typing import Any, Callable, TYPE_CHECKING +from typing import TYPE_CHECKING, Any, Callable if TYPE_CHECKING: - from _typeshed import StrOrBytesPath, ExcInfo + from _typeshed import ExcInfo, StrOrBytesPath + from typing_extensions import TypeAlias # Same as shutil._OnExcCallback from typeshed -_OnExcCallback = Callable[[Callable[..., Any], str, BaseException], object] +_OnExcCallback: TypeAlias = Callable[[Callable[..., Any], str, BaseException], object] def shutil_rmtree( diff --git a/uno/lib/python/setuptools/config/NOTICE b/uno/lib/python/setuptools/config/NOTICE new file mode 100644 index 00000000..01864511 --- /dev/null +++ b/uno/lib/python/setuptools/config/NOTICE @@ -0,0 +1,10 @@ +The following files include code from opensource projects +(either as direct copies or modified versions): + +- `setuptools.schema.json`, `distutils.schema.json`: + - project: `validate-pyproject` - licensed under MPL-2.0 + (https://github.com/abravalheri/validate-pyproject): + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this file, + You can obtain one at https://mozilla.org/MPL/2.0/. diff --git a/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py b/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py index 6cc59d2b..7b9c0b1a 100644 --- a/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py +++ b/uno/lib/python/setuptools/config/_apply_pyprojecttoml.py @@ -17,27 +17,24 @@ from inspect import cleandoc from itertools import chain from types import MappingProxyType -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Dict, - Mapping, - Union, -) +from typing import TYPE_CHECKING, Any, Callable, Dict, Mapping, Union + from .._path import StrPath from ..errors import RemovedConfigError from ..warnings import SetuptoolsWarning if TYPE_CHECKING: - from distutils.dist import _OptionsList + from typing_extensions import TypeAlias + from setuptools._importlib import metadata from setuptools.dist import Distribution + from distutils.dist import _OptionsList + EMPTY: Mapping = MappingProxyType({}) # Immutable dict-like -_ProjectReadmeValue = Union[str, Dict[str, str]] -_CorrespFn = Callable[["Distribution", Any, StrPath], None] -_Correspondence = Union[str, _CorrespFn] +_ProjectReadmeValue: TypeAlias = Union[str, Dict[str, str]] +_CorrespFn: TypeAlias = Callable[["Distribution", Any, StrPath], None] +_Correspondence: TypeAlias = Union[str, _CorrespFn] _logger = logging.getLogger(__name__) @@ -261,9 +258,10 @@ def _copy_command_options(pyproject: dict, dist: Distribution, filename: StrPath def _valid_command_options(cmdclass: Mapping = EMPTY) -> dict[str, set[str]]: - from .._importlib import metadata from setuptools.dist import Distribution + from .._importlib import metadata + valid_options = {"global": _normalise_cmd_options(Distribution.global_options)} unloaded_entry_points = metadata.entry_points(group='distutils.commands') @@ -278,6 +276,11 @@ def _valid_command_options(cmdclass: Mapping = EMPTY) -> dict[str, set[str]]: def _load_ep(ep: metadata.EntryPoint) -> tuple[str, type] | None: + if ep.value.startswith("wheel.bdist_wheel"): + # Ignore deprecated entrypoint from wheel and avoid warning pypa/wheel#631 + # TODO: remove check when `bdist_wheel` has been fully removed from pypa/wheel + return None + # Ignore all the errors try: return (ep.name, ep.load()) diff --git a/uno/lib/python/setuptools/config/_validate_pyproject/NOTICE b/uno/lib/python/setuptools/config/_validate_pyproject/NOTICE new file mode 100644 index 00000000..74e8821f --- /dev/null +++ b/uno/lib/python/setuptools/config/_validate_pyproject/NOTICE @@ -0,0 +1,438 @@ +The code contained in this directory was automatically generated using the +following command: + + python -m validate_pyproject.pre_compile --output-dir=setuptools/config/_validate_pyproject --enable-plugins setuptools distutils --very-verbose -t distutils=setuptools/config/distutils.schema.json -t setuptools=setuptools/config/setuptools.schema.json + +Please avoid changing it manually. + + +You can report issues or suggest changes directly to `validate-pyproject` +(or to the relevant plugin repository) + +- https://github.com/abravalheri/validate-pyproject/issues + + +*** + +The following files include code from opensource projects +(either as direct copies or modified versions): + +- `fastjsonschema_exceptions.py`: + - project: `fastjsonschema` - licensed under BSD-3-Clause + (https://github.com/horejsek/python-fastjsonschema) +- `extra_validations.py` and `format.py`, `error_reporting.py`: + - project: `validate-pyproject` - licensed under MPL-2.0 + (https://github.com/abravalheri/validate-pyproject) + + +Additionally the following files are automatically generated by tools provided +by the same projects: + +- `__init__.py` +- `fastjsonschema_validations.py` + +The relevant copyright notes and licenses are included below. + + +*** + +`fastjsonschema` +================ + +Copyright (c) 2018, Michal Horejsek +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + + Neither the name of the {organization} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + + +*** + +`validate-pyproject` +==================== + +Mozilla Public License, version 2.0 + +1. Definitions + +1.1. "Contributor" + + means each individual or legal entity that creates, contributes to the + creation of, or owns Covered Software. + +1.2. "Contributor Version" + + means the combination of the Contributions of others (if any) used by a + Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + + means Source Code Form to which the initial Contributor has attached the + notice in Exhibit A, the Executable Form of such Source Code Form, and + Modifications of such Source Code Form, in each case including portions + thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + a. that the initial Contributor has attached the notice described in + Exhibit B to the Covered Software; or + + b. that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the terms of + a Secondary License. + +1.6. "Executable Form" + + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + + means a work that combines Covered Software with other material, in a + separate file or files, that is not Covered Software. + +1.8. "License" + + means this document. + +1.9. "Licensable" + + means having the right to grant, to the maximum extent possible, whether + at the time of the initial grant or subsequently, any and all of the + rights conveyed by this License. + +1.10. "Modifications" + + means any of the following: + + a. any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered Software; or + + b. any new file in Source Code Form that contains any Covered Software. + +1.11. "Patent Claims" of a Contributor + + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the License, + by the making, using, selling, offering for sale, having made, import, + or transfer of either its Contributions or its Contributor Version. + +1.12. "Secondary License" + + means either the GNU General Public License, Version 2.0, the GNU Lesser + General Public License, Version 2.1, the GNU Affero General Public + License, Version 3.0, or any later versions of those licenses. + +1.13. "Source Code Form" + + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that controls, is + controlled by, or is under common control with You. For purposes of this + definition, "control" means (a) the power, direct or indirect, to cause + the direction or management of such entity, whether by contract or + otherwise, or (b) ownership of more than fifty percent (50%) of the + outstanding shares or beneficial ownership of such entity. + + +2. License Grants and Conditions + +2.1. Grants + + Each Contributor hereby grants You a world-wide, royalty-free, + non-exclusive license: + + a. under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + + b. under Patent Claims of such Contributor to make, use, sell, offer for + sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + + The licenses granted in Section 2.1 with respect to any Contribution + become effective for each Contribution on the date the Contributor first + distributes such Contribution. + +2.3. Limitations on Grant Scope + + The licenses granted in this Section 2 are the only rights granted under + this License. No additional rights or licenses will be implied from the + distribution or licensing of Covered Software under this License. + Notwithstanding Section 2.1(b) above, no patent license is granted by a + Contributor: + + a. for any code that a Contributor has removed from Covered Software; or + + b. for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + + c. under Patent Claims infringed by Covered Software in the absence of + its Contributions. + + This License does not grant any rights in the trademarks, service marks, + or logos of any Contributor (except as may be necessary to comply with + the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + + No Contributor makes additional grants as a result of Your choice to + distribute the Covered Software under a subsequent version of this + License (see Section 10.2) or under the terms of a Secondary License (if + permitted under the terms of Section 3.3). + +2.5. Representation + + Each Contributor represents that the Contributor believes its + Contributions are its original creation(s) or it has sufficient rights to + grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + + This License is not intended to limit any rights You have under + applicable copyright doctrines of fair use, fair dealing, or other + equivalents. + +2.7. Conditions + + Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in + Section 2.1. + + +3. Responsibilities + +3.1. Distribution of Source Form + + All distribution of Covered Software in Source Code Form, including any + Modifications that You create or to which You contribute, must be under + the terms of this License. You must inform recipients that the Source + Code Form of the Covered Software is governed by the terms of this + License, and how they can obtain a copy of this License. You may not + attempt to alter or restrict the recipients' rights in the Source Code + Form. + +3.2. Distribution of Executable Form + + If You distribute Covered Software in Executable Form then: + + a. such Covered Software must also be made available in Source Code Form, + as described in Section 3.1, and You must inform recipients of the + Executable Form how they can obtain a copy of such Source Code Form by + reasonable means in a timely manner, at a charge no more than the cost + of distribution to the recipient; and + + b. You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter the + recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + + You may create and distribute a Larger Work under terms of Your choice, + provided that You also comply with the requirements of this License for + the Covered Software. If the Larger Work is a combination of Covered + Software with a work governed by one or more Secondary Licenses, and the + Covered Software is not Incompatible With Secondary Licenses, this + License permits You to additionally distribute such Covered Software + under the terms of such Secondary License(s), so that the recipient of + the Larger Work may, at their option, further distribute the Covered + Software under the terms of either this License or such Secondary + License(s). + +3.4. Notices + + You may not remove or alter the substance of any license notices + (including copyright notices, patent notices, disclaimers of warranty, or + limitations of liability) contained within the Source Code Form of the + Covered Software, except that You may alter any license notices to the + extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + + You may choose to offer, and to charge a fee for, warranty, support, + indemnity or liability obligations to one or more recipients of Covered + Software. However, You may do so only on Your own behalf, and not on + behalf of any Contributor. You must make it absolutely clear that any + such warranty, support, indemnity, or liability obligation is offered by + You alone, and You hereby agree to indemnify every Contributor for any + liability incurred by such Contributor as a result of warranty, support, + indemnity or liability terms You offer. You may include additional + disclaimers of warranty and limitations of liability specific to any + jurisdiction. + +4. Inability to Comply Due to Statute or Regulation + + If it is impossible for You to comply with any of the terms of this License + with respect to some or all of the Covered Software due to statute, + judicial order, or regulation then You must: (a) comply with the terms of + this License to the maximum extent possible; and (b) describe the + limitations and the code they affect. Such description must be placed in a + text file included with all distributions of the Covered Software under + this License. Except to the extent prohibited by statute or regulation, + such description must be sufficiently detailed for a recipient of ordinary + skill to be able to understand it. + +5. Termination + +5.1. The rights granted under this License will terminate automatically if You + fail to comply with any of its terms. However, if You become compliant, + then the rights granted under this License from a particular Contributor + are reinstated (a) provisionally, unless and until such Contributor + explicitly and finally terminates Your grants, and (b) on an ongoing + basis, if such Contributor fails to notify You of the non-compliance by + some reasonable means prior to 60 days after You have come back into + compliance. Moreover, Your grants from a particular Contributor are + reinstated on an ongoing basis if such Contributor notifies You of the + non-compliance by some reasonable means, this is the first time You have + received notice of non-compliance with this License from such + Contributor, and You become compliant prior to 30 days after Your receipt + of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent + infringement claim (excluding declaratory judgment actions, + counter-claims, and cross-claims) alleging that a Contributor Version + directly or indirectly infringes any patent, then the rights granted to + You by any and all Contributors for the Covered Software under Section + 2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user + license agreements (excluding distributors and resellers) which have been + validly granted by You or Your distributors under this License prior to + termination shall survive termination. + +6. Disclaimer of Warranty + + Covered Software is provided under this License on an "as is" basis, + without warranty of any kind, either expressed, implied, or statutory, + including, without limitation, warranties that the Covered Software is free + of defects, merchantable, fit for a particular purpose or non-infringing. + The entire risk as to the quality and performance of the Covered Software + is with You. Should any Covered Software prove defective in any respect, + You (not any Contributor) assume the cost of any necessary servicing, + repair, or correction. This disclaimer of warranty constitutes an essential + part of this License. No use of any Covered Software is authorized under + this License except under this disclaimer. + +7. Limitation of Liability + + Under no circumstances and under no legal theory, whether tort (including + negligence), contract, or otherwise, shall any Contributor, or anyone who + distributes Covered Software as permitted above, be liable to You for any + direct, indirect, special, incidental, or consequential damages of any + character including, without limitation, damages for lost profits, loss of + goodwill, work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses, even if such party shall have been + informed of the possibility of such damages. This limitation of liability + shall not apply to liability for death or personal injury resulting from + such party's negligence to the extent applicable law prohibits such + limitation. Some jurisdictions do not allow the exclusion or limitation of + incidental or consequential damages, so this exclusion and limitation may + not apply to You. + +8. Litigation + + Any litigation relating to this License may be brought only in the courts + of a jurisdiction where the defendant maintains its principal place of + business and such litigation shall be governed by laws of that + jurisdiction, without reference to its conflict-of-law provisions. Nothing + in this Section shall prevent a party's ability to bring cross-claims or + counter-claims. + +9. Miscellaneous + + This License represents the complete agreement concerning the subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. Any law or regulation which provides that + the language of a contract shall be construed against the drafter shall not + be used to construe this License against a Contributor. + + +10. Versions of the License + +10.1. New Versions + + Mozilla Foundation is the license steward. Except as provided in Section + 10.3, no one other than the license steward has the right to modify or + publish new versions of this License. Each version will be given a + distinguishing version number. + +10.2. Effect of New Versions + + You may distribute the Covered Software under the terms of the version + of the License under which You originally received the Covered Software, + or under the terms of any subsequent version published by the license + steward. + +10.3. Modified Versions + + If you create software not governed by this License, and you want to + create a new license for such software, you may create and use a + modified version of this License if you rename the license and remove + any references to the name of the license steward (except to note that + such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary + Licenses If You choose to distribute Source Code Form that is + Incompatible With Secondary Licenses under the terms of this version of + the License, the notice described in Exhibit B of this License must be + attached. + +Exhibit A - Source Code Form License Notice + + This Source Code Form is subject to the + terms of the Mozilla Public License, v. + 2.0. If a copy of the MPL was not + distributed with this file, You can + obtain one at + https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular file, +then You may include the notice in a location (such as a LICENSE file in a +relevant directory) where a recipient would be likely to look for such a +notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice + + This Source Code Form is "Incompatible + With Secondary Licenses", as defined by + the Mozilla Public License, v. 2.0. diff --git a/uno/lib/python/setuptools/config/_validate_pyproject/error_reporting.py b/uno/lib/python/setuptools/config/_validate_pyproject/error_reporting.py index a6753604..3591231c 100644 --- a/uno/lib/python/setuptools/config/_validate_pyproject/error_reporting.py +++ b/uno/lib/python/setuptools/config/_validate_pyproject/error_reporting.py @@ -6,7 +6,7 @@ import typing from contextlib import contextmanager from textwrap import indent, wrap -from typing import Any, Dict, Generator, Iterator, List, Optional, Sequence, Union, cast +from typing import Any, Dict, Generator, Iterator, List, Optional, Sequence, Union from .fastjsonschema_exceptions import JsonSchemaValueException @@ -316,9 +316,7 @@ def _label(self, path: Sequence[str]) -> str: def _value(self, value: Any, path: Sequence[str]) -> str: if path[-1] == "type" and not self._is_property(path): type_ = self._jargon(value) - return ( - f"[{', '.join(type_)}]" if isinstance(value, list) else cast(str, type_) - ) + return f"[{', '.join(type_)}]" if isinstance(type_, list) else type_ return repr(value) def _inline_attrs(self, schema: dict, path: Sequence[str]) -> Iterator[str]: diff --git a/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py b/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py index 1c58a55e..7e403af4 100644 --- a/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py +++ b/uno/lib/python/setuptools/config/_validate_pyproject/fastjsonschema_validations.py @@ -10,7 +10,7 @@ # *** PLEASE DO NOT MODIFY DIRECTLY: Automatically generated code *** -VERSION = "2.19.1" +VERSION = "2.20.0" from decimal import Decimal import re from .fastjsonschema_exceptions import JsonSchemaValueException @@ -31,7 +31,7 @@ def validate(data, custom_formats={}, name_prefix=None): def validate_https___packaging_python_org_en_latest_specifications_declaring_build_dependencies(data, custom_formats={}, name_prefix=None): if not isinstance(data, (dict)): - raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/declaring-build-dependencies/', 'title': 'Data structure for ``pyproject.toml`` files', '$$description': ['File format containing build-time configurations for the Python ecosystem. ', ':pep:`517` initially defined a build-system independent format for source trees', 'which was complemented by :pep:`518` to provide a way of specifying dependencies ', 'for building Python projects.', 'Please notice the ``project`` table (as initially defined in :pep:`621`) is not included', 'in this schema and should be considered separately.'], 'type': 'object', 'additionalProperties': False, 'properties': {'build-system': {'type': 'object', 'description': 'Table used to store build-related data', 'additionalProperties': False, 'properties': {'requires': {'type': 'array', '$$description': ['List of dependencies in the :pep:`508` format required to execute the build', 'system. Please notice that the resulting dependency graph', '**MUST NOT contain cycles**'], 'items': {'type': 'string'}}, 'build-backend': {'type': 'string', 'description': 'Python object that will be used to perform the build according to :pep:`517`', 'format': 'pep517-backend-reference'}, 'backend-path': {'type': 'array', '$$description': ['List of directories to be prepended to ``sys.path`` when loading the', 'back-end, and running its hooks'], 'items': {'type': 'string', '$comment': 'Should be a path (TODO: enforce it with format?)'}}}, 'required': ['requires']}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}, 'tool': {'type': 'object', 'properties': {'distutils': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html', 'title': '``tool.distutils`` table', '$$description': ['**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``', 'subtables to configure arguments for ``distutils`` commands.', 'Originally, ``distutils`` allowed developers to configure arguments for', '``setup.py`` commands via `distutils configuration files', '`_.', 'See also `the old Python docs _`.'], 'type': 'object', 'properties': {'global': {'type': 'object', 'description': 'Global options applied to all ``distutils`` commands'}}, 'patternProperties': {'.+': {'type': 'object'}}, '$comment': 'TODO: Is there a practical way of making this schema more specific?'}, 'setuptools': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$ref': '#/definitions/package-name'}}, {'$ref': '#/definitions/find-directive'}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$ref': '#/definitions/package-name'}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'$ref': '#/definitions/attr-directive'}, {'$ref': '#/definitions/file-directive'}]}, 'classifiers': {'$ref': '#/definitions/file-directive'}, 'description': {'$ref': '#/definitions/file-directive'}, 'entry-points': {'$ref': '#/definitions/file-directive'}, 'dependencies': {'$ref': '#/definitions/file-directive-for-dependencies'}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'$ref': '#/definitions/file-directive-for-dependencies'}}}, 'readme': {'type': 'object', 'anyOf': [{'$ref': '#/definitions/file-directive'}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'$ref': '#/definitions/file-directive/properties/file'}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}}}}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/declaring-build-dependencies/', 'title': 'Data structure for ``pyproject.toml`` files', '$$description': ['File format containing build-time configurations for the Python ecosystem. ', ':pep:`517` initially defined a build-system independent format for source trees', 'which was complemented by :pep:`518` to provide a way of specifying dependencies ', 'for building Python projects.', 'Please notice the ``project`` table (as initially defined in :pep:`621`) is not included', 'in this schema and should be considered separately.'], 'type': 'object', 'additionalProperties': False, 'properties': {'build-system': {'type': 'object', 'description': 'Table used to store build-related data', 'additionalProperties': False, 'properties': {'requires': {'type': 'array', '$$description': ['List of dependencies in the :pep:`508` format required to execute the build', 'system. Please notice that the resulting dependency graph', '**MUST NOT contain cycles**'], 'items': {'type': 'string'}}, 'build-backend': {'type': 'string', 'description': 'Python object that will be used to perform the build according to :pep:`517`', 'format': 'pep517-backend-reference'}, 'backend-path': {'type': 'array', '$$description': ['List of directories to be prepended to ``sys.path`` when loading the', 'back-end, and running its hooks'], 'items': {'type': 'string', '$comment': 'Should be a path (TODO: enforce it with format?)'}}}, 'required': ['requires']}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}, 'tool': {'type': 'object', 'properties': {'distutils': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html', 'title': '``tool.distutils`` table', '$$description': ['**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``', 'subtables to configure arguments for ``distutils`` commands.', 'Originally, ``distutils`` allowed developers to configure arguments for', '``setup.py`` commands via `distutils configuration files', '`_.', 'See also `the old Python docs _`.'], 'type': 'object', 'properties': {'global': {'type': 'object', 'description': 'Global options applied to all ``distutils`` commands'}}, 'patternProperties': {'.+': {'type': 'object'}}, '$comment': 'TODO: Is there a practical way of making this schema more specific?'}, 'setuptools': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$ref': '#/definitions/package-name'}}, {'$ref': '#/definitions/find-directive'}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$ref': '#/definitions/package-name'}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'$ref': '#/definitions/attr-directive'}, {'$ref': '#/definitions/file-directive'}]}, 'classifiers': {'$ref': '#/definitions/file-directive'}, 'description': {'$ref': '#/definitions/file-directive'}, 'entry-points': {'$ref': '#/definitions/file-directive'}, 'dependencies': {'$ref': '#/definitions/file-directive-for-dependencies'}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'$ref': '#/definitions/file-directive-for-dependencies'}}}, 'readme': {'type': 'object', 'anyOf': [{'$ref': '#/definitions/file-directive'}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'$ref': '#/definitions/file-directive/properties/file'}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}}}}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}}, rule='type') data_is_dict = isinstance(data, dict) if data_is_dict: data_keys = set(data.keys()) @@ -86,7 +86,7 @@ def validate_https___packaging_python_org_en_latest_specifications_declaring_bui data_keys.remove("tool") data__tool = data["tool"] if not isinstance(data__tool, (dict)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".tool must be object", value=data__tool, name="" + (name_prefix or "data") + ".tool", definition={'type': 'object', 'properties': {'distutils': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html', 'title': '``tool.distutils`` table', '$$description': ['**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``', 'subtables to configure arguments for ``distutils`` commands.', 'Originally, ``distutils`` allowed developers to configure arguments for', '``setup.py`` commands via `distutils configuration files', '`_.', 'See also `the old Python docs _`.'], 'type': 'object', 'properties': {'global': {'type': 'object', 'description': 'Global options applied to all ``distutils`` commands'}}, 'patternProperties': {'.+': {'type': 'object'}}, '$comment': 'TODO: Is there a practical way of making this schema more specific?'}, 'setuptools': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$ref': '#/definitions/package-name'}}, {'$ref': '#/definitions/find-directive'}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$ref': '#/definitions/package-name'}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'$ref': '#/definitions/attr-directive'}, {'$ref': '#/definitions/file-directive'}]}, 'classifiers': {'$ref': '#/definitions/file-directive'}, 'description': {'$ref': '#/definitions/file-directive'}, 'entry-points': {'$ref': '#/definitions/file-directive'}, 'dependencies': {'$ref': '#/definitions/file-directive-for-dependencies'}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'$ref': '#/definitions/file-directive-for-dependencies'}}}, 'readme': {'type': 'object', 'anyOf': [{'$ref': '#/definitions/file-directive'}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'$ref': '#/definitions/file-directive/properties/file'}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}}}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".tool must be object", value=data__tool, name="" + (name_prefix or "data") + ".tool", definition={'type': 'object', 'properties': {'distutils': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html', 'title': '``tool.distutils`` table', '$$description': ['**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``', 'subtables to configure arguments for ``distutils`` commands.', 'Originally, ``distutils`` allowed developers to configure arguments for', '``setup.py`` commands via `distutils configuration files', '`_.', 'See also `the old Python docs _`.'], 'type': 'object', 'properties': {'global': {'type': 'object', 'description': 'Global options applied to all ``distutils`` commands'}}, 'patternProperties': {'.+': {'type': 'object'}}, '$comment': 'TODO: Is there a practical way of making this schema more specific?'}, 'setuptools': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$ref': '#/definitions/package-name'}}, {'$ref': '#/definitions/find-directive'}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$ref': '#/definitions/package-name'}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'$ref': '#/definitions/attr-directive'}, {'$ref': '#/definitions/file-directive'}]}, 'classifiers': {'$ref': '#/definitions/file-directive'}, 'description': {'$ref': '#/definitions/file-directive'}, 'entry-points': {'$ref': '#/definitions/file-directive'}, 'dependencies': {'$ref': '#/definitions/file-directive-for-dependencies'}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'$ref': '#/definitions/file-directive-for-dependencies'}}}, 'readme': {'type': 'object', 'anyOf': [{'$ref': '#/definitions/file-directive'}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'$ref': '#/definitions/file-directive/properties/file'}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}}}, rule='type') data__tool_is_dict = isinstance(data__tool, dict) if data__tool_is_dict: data__tool_keys = set(data__tool.keys()) @@ -99,12 +99,12 @@ def validate_https___packaging_python_org_en_latest_specifications_declaring_bui data__tool__setuptools = data__tool["setuptools"] validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_html(data__tool__setuptools, custom_formats, (name_prefix or "data") + ".tool.setuptools") if data_keys: - raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/declaring-build-dependencies/', 'title': 'Data structure for ``pyproject.toml`` files', '$$description': ['File format containing build-time configurations for the Python ecosystem. ', ':pep:`517` initially defined a build-system independent format for source trees', 'which was complemented by :pep:`518` to provide a way of specifying dependencies ', 'for building Python projects.', 'Please notice the ``project`` table (as initially defined in :pep:`621`) is not included', 'in this schema and should be considered separately.'], 'type': 'object', 'additionalProperties': False, 'properties': {'build-system': {'type': 'object', 'description': 'Table used to store build-related data', 'additionalProperties': False, 'properties': {'requires': {'type': 'array', '$$description': ['List of dependencies in the :pep:`508` format required to execute the build', 'system. Please notice that the resulting dependency graph', '**MUST NOT contain cycles**'], 'items': {'type': 'string'}}, 'build-backend': {'type': 'string', 'description': 'Python object that will be used to perform the build according to :pep:`517`', 'format': 'pep517-backend-reference'}, 'backend-path': {'type': 'array', '$$description': ['List of directories to be prepended to ``sys.path`` when loading the', 'back-end, and running its hooks'], 'items': {'type': 'string', '$comment': 'Should be a path (TODO: enforce it with format?)'}}}, 'required': ['requires']}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}, 'tool': {'type': 'object', 'properties': {'distutils': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html', 'title': '``tool.distutils`` table', '$$description': ['**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``', 'subtables to configure arguments for ``distutils`` commands.', 'Originally, ``distutils`` allowed developers to configure arguments for', '``setup.py`` commands via `distutils configuration files', '`_.', 'See also `the old Python docs _`.'], 'type': 'object', 'properties': {'global': {'type': 'object', 'description': 'Global options applied to all ``distutils`` commands'}}, 'patternProperties': {'.+': {'type': 'object'}}, '$comment': 'TODO: Is there a practical way of making this schema more specific?'}, 'setuptools': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$ref': '#/definitions/package-name'}}, {'$ref': '#/definitions/find-directive'}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$ref': '#/definitions/package-name'}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'$ref': '#/definitions/attr-directive'}, {'$ref': '#/definitions/file-directive'}]}, 'classifiers': {'$ref': '#/definitions/file-directive'}, 'description': {'$ref': '#/definitions/file-directive'}, 'entry-points': {'$ref': '#/definitions/file-directive'}, 'dependencies': {'$ref': '#/definitions/file-directive-for-dependencies'}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'$ref': '#/definitions/file-directive-for-dependencies'}}}, 'readme': {'type': 'object', 'anyOf': [{'$ref': '#/definitions/file-directive'}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'$ref': '#/definitions/file-directive/properties/file'}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}}}}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}}, rule='additionalProperties') + raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/declaring-build-dependencies/', 'title': 'Data structure for ``pyproject.toml`` files', '$$description': ['File format containing build-time configurations for the Python ecosystem. ', ':pep:`517` initially defined a build-system independent format for source trees', 'which was complemented by :pep:`518` to provide a way of specifying dependencies ', 'for building Python projects.', 'Please notice the ``project`` table (as initially defined in :pep:`621`) is not included', 'in this schema and should be considered separately.'], 'type': 'object', 'additionalProperties': False, 'properties': {'build-system': {'type': 'object', 'description': 'Table used to store build-related data', 'additionalProperties': False, 'properties': {'requires': {'type': 'array', '$$description': ['List of dependencies in the :pep:`508` format required to execute the build', 'system. Please notice that the resulting dependency graph', '**MUST NOT contain cycles**'], 'items': {'type': 'string'}}, 'build-backend': {'type': 'string', 'description': 'Python object that will be used to perform the build according to :pep:`517`', 'format': 'pep517-backend-reference'}, 'backend-path': {'type': 'array', '$$description': ['List of directories to be prepended to ``sys.path`` when loading the', 'back-end, and running its hooks'], 'items': {'type': 'string', '$comment': 'Should be a path (TODO: enforce it with format?)'}}}, 'required': ['requires']}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}, 'tool': {'type': 'object', 'properties': {'distutils': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html', 'title': '``tool.distutils`` table', '$$description': ['**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``', 'subtables to configure arguments for ``distutils`` commands.', 'Originally, ``distutils`` allowed developers to configure arguments for', '``setup.py`` commands via `distutils configuration files', '`_.', 'See also `the old Python docs _`.'], 'type': 'object', 'properties': {'global': {'type': 'object', 'description': 'Global options applied to all ``distutils`` commands'}}, 'patternProperties': {'.+': {'type': 'object'}}, '$comment': 'TODO: Is there a practical way of making this schema more specific?'}, 'setuptools': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$ref': '#/definitions/package-name'}}, {'$ref': '#/definitions/find-directive'}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$ref': '#/definitions/package-name'}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'$ref': '#/definitions/attr-directive'}, {'$ref': '#/definitions/file-directive'}]}, 'classifiers': {'$ref': '#/definitions/file-directive'}, 'description': {'$ref': '#/definitions/file-directive'}, 'entry-points': {'$ref': '#/definitions/file-directive'}, 'dependencies': {'$ref': '#/definitions/file-directive-for-dependencies'}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'$ref': '#/definitions/file-directive-for-dependencies'}}}, 'readme': {'type': 'object', 'anyOf': [{'$ref': '#/definitions/file-directive'}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'$ref': '#/definitions/file-directive/properties/file'}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}}}}, 'project': {'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://packaging.python.org/en/latest/specifications/pyproject-toml/', 'title': 'Package metadata stored in the ``project`` table', '$$description': ['Data structure for the **project** table inside ``pyproject.toml``', '(as initially defined in :pep:`621`)'], 'type': 'object', 'properties': {'name': {'type': 'string', 'description': 'The name (primary identifier) of the project. MUST be statically defined.', 'format': 'pep508-identifier'}, 'version': {'type': 'string', 'description': 'The version of the project as supported by :pep:`440`.', 'format': 'pep440'}, 'description': {'type': 'string', '$$description': ['The `summary description of the project', '`_']}, 'readme': {'$$description': ['`Full/detailed description of the project in the form of a README', '`_', "with meaning similar to the one defined in `core metadata's Description", '`_'], 'oneOf': [{'type': 'string', '$$description': ['Relative path to a text file (UTF-8) containing the full description', 'of the project. If the file path ends in case-insensitive ``.md`` or', '``.rst`` suffixes, then the content-type is respectively', '``text/markdown`` or ``text/x-rst``']}, {'type': 'object', 'allOf': [{'anyOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to a text file containing the full description', 'of the project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', 'description': 'Full text describing the project.'}}, 'required': ['text']}]}, {'properties': {'content-type': {'type': 'string', '$$description': ['Content-type (:rfc:`1341`) of the full description', '(e.g. ``text/markdown``). The ``charset`` parameter is assumed', 'UTF-8 when not present.'], '$comment': 'TODO: add regex pattern or format?'}}, 'required': ['content-type']}]}]}, 'requires-python': {'type': 'string', 'format': 'pep508-versionspec', '$$description': ['`The Python version requirements of the project', '`_.']}, 'license': {'description': '`Project license `_.', 'oneOf': [{'properties': {'file': {'type': 'string', '$$description': ['Relative path to the file (UTF-8) which contains the license for the', 'project.']}}, 'required': ['file']}, {'properties': {'text': {'type': 'string', '$$description': ['The license of the project whose meaning is that of the', '`License field from the core metadata', '`_.']}}, 'required': ['text']}]}, 'authors': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'authors' of the project.", 'The exact meaning is open to interpretation (e.g. original or primary authors,', 'current maintainers, or owners of the package).']}, 'maintainers': {'type': 'array', 'items': {'$ref': '#/definitions/author'}, '$$description': ["The people or organizations considered to be the 'maintainers' of the project.", 'Similarly to ``authors``, the exact meaning is open to interpretation.']}, 'keywords': {'type': 'array', 'items': {'type': 'string'}, 'description': 'List of keywords to assist searching for the distribution in a larger catalog.'}, 'classifiers': {'type': 'array', 'items': {'type': 'string', 'format': 'trove-classifier', 'description': '`PyPI classifier `_.'}, '$$description': ['`Trove classifiers `_', 'which apply to the project.']}, 'urls': {'type': 'object', 'description': 'URLs associated with the project in the form ``label => value``.', 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', 'format': 'url'}}}, 'scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create command-line wrappers for the given', '`entry points `_.']}, 'gui-scripts': {'$ref': '#/definitions/entry-point-group', '$$description': ['Instruct the installer to create GUI wrappers for the given', '`entry points `_.', 'The difference between ``scripts`` and ``gui-scripts`` is only relevant in', 'Windows.']}, 'entry-points': {'$$description': ['Instruct the installer to expose the given modules/functions via', '``entry-point`` discovery mechanism (useful for plugins).', 'More information available in the `Python packaging guide', '`_.'], 'propertyNames': {'format': 'python-entrypoint-group'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'$ref': '#/definitions/entry-point-group'}}}, 'dependencies': {'type': 'array', 'description': 'Project (mandatory) dependencies.', 'items': {'$ref': '#/definitions/dependency'}}, 'optional-dependencies': {'type': 'object', 'description': 'Optional dependency for the project', 'propertyNames': {'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'array', 'items': {'$ref': '#/definitions/dependency'}}}}, 'dynamic': {'type': 'array', '$$description': ['Specifies which fields are intentionally unspecified and expected to be', 'dynamically provided by build tools'], 'items': {'enum': ['version', 'description', 'readme', 'requires-python', 'license', 'authors', 'maintainers', 'keywords', 'classifiers', 'urls', 'scripts', 'gui-scripts', 'entry-points', 'dependencies', 'optional-dependencies']}}}, 'required': ['name'], 'additionalProperties': False, 'if': {'not': {'required': ['dynamic'], 'properties': {'dynamic': {'contains': {'const': 'version'}, '$$description': ['version is listed in ``dynamic``']}}}, '$$comment': ['According to :pep:`621`:', ' If the core metadata specification lists a field as "Required", then', ' the metadata MUST specify the field statically or list it in dynamic', 'In turn, `core metadata`_ defines:', ' The required fields are: Metadata-Version, Name, Version.', ' All the other fields are optional.', 'Since ``Metadata-Version`` is defined by the build back-end, ``name`` and', '``version`` are the only mandatory information in ``pyproject.toml``.', '.. _core metadata: https://packaging.python.org/specifications/core-metadata/']}, 'then': {'required': ['version'], '$$description': ['version should be statically defined in the ``version`` field']}, 'definitions': {'author': {'$id': '#/definitions/author', 'title': 'Author or Maintainer', '$comment': 'https://peps.python.org/pep-0621/#authors-maintainers', 'type': 'object', 'additionalProperties': False, 'properties': {'name': {'type': 'string', '$$description': ['MUST be a valid email name, i.e. whatever can be put as a name, before an', 'email, in :rfc:`822`.']}, 'email': {'type': 'string', 'format': 'idn-email', 'description': 'MUST be a valid email address'}}}, 'entry-point-group': {'$id': '#/definitions/entry-point-group', 'title': 'Entry-points', 'type': 'object', '$$description': ['Entry-points are grouped together to indicate what sort of capabilities they', 'provide.', 'See the `packaging guides', '`_', 'and `setuptools docs', '`_', 'for more information.'], 'propertyNames': {'format': 'python-entrypoint-name'}, 'additionalProperties': False, 'patternProperties': {'^.+$': {'type': 'string', '$$description': ['Reference to a Python object. It is either in the form', '``importable.module``, or ``importable.module:object.attr``.'], 'format': 'python-entrypoint-reference', '$comment': 'https://packaging.python.org/specifications/entry-points/'}}}, 'dependency': {'$id': '#/definitions/dependency', 'title': 'Dependency', 'type': 'string', 'description': 'Project dependency specification according to PEP 508', 'format': 'pep508'}}}}, rule='additionalProperties') return data def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_html(data, custom_formats={}, name_prefix=None): if not isinstance(data, (dict)): - raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'classifiers': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'description': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'entry-points': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}}}, 'readme': {'type': 'object', 'anyOf': [{'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + " must be object", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'classifiers': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'description': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'entry-points': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}}}, 'readme': {'type': 'object', 'anyOf': [{'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}, rule='type') data_is_dict = isinstance(data, dict) if data_is_dict: data_keys = set(data.keys()) @@ -181,7 +181,7 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm if data__packages_one_of_count1 < 2: try: if not isinstance(data__packages, (list, tuple)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".packages must be array", value=data__packages, name="" + (name_prefix or "data") + ".packages", definition={'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".packages must be array", value=data__packages, name="" + (name_prefix or "data") + ".packages", definition={'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, rule='type') data__packages_is_list = isinstance(data__packages, (list, tuple)) if data__packages_is_list: data__packages_len = len(data__packages) @@ -195,12 +195,12 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm data__packages_one_of_count1 += 1 except JsonSchemaValueException: pass if data__packages_one_of_count1 != 1: - raise JsonSchemaValueException("" + (name_prefix or "data") + ".packages must be valid exactly by one definition" + (" (" + str(data__packages_one_of_count1) + " matches found)"), value=data__packages, name="" + (name_prefix or "data") + ".packages", definition={'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}]}, rule='oneOf') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".packages must be valid exactly by one definition" + (" (" + str(data__packages_one_of_count1) + " matches found)"), value=data__packages, name="" + (name_prefix or "data") + ".packages", definition={'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}]}, rule='oneOf') if "package-dir" in data_keys: data_keys.remove("package-dir") data__packagedir = data["package-dir"] if not isinstance(data__packagedir, (dict)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must be object", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must be object", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, rule='type') data__packagedir_is_dict = isinstance(data__packagedir, dict) if data__packagedir_is_dict: data__packagedir_keys = set(data__packagedir.keys()) @@ -211,7 +211,7 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm if not isinstance(data__packagedir_val, (str)): raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir.{data__packagedir_key}".format(**locals()) + " must be string", value=data__packagedir_val, name="" + (name_prefix or "data") + ".package-dir.{data__packagedir_key}".format(**locals()) + "", definition={'type': 'string'}, rule='type') if data__packagedir_keys: - raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must not contain "+str(data__packagedir_keys)+" properties", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, rule='additionalProperties') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must not contain "+str(data__packagedir_keys)+" properties", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, rule='additionalProperties') data__packagedir_len = len(data__packagedir) if data__packagedir_len != 0: data__packagedir_property_names = True @@ -230,11 +230,11 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm data__packagedir_key_any_of_count2 += 1 except JsonSchemaValueException: pass if not data__packagedir_key_any_of_count2: - raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir cannot be validated by any definition", value=data__packagedir_key, name="" + (name_prefix or "data") + ".package-dir", definition={'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, rule='anyOf') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir cannot be validated by any definition", value=data__packagedir_key, name="" + (name_prefix or "data") + ".package-dir", definition={'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, rule='anyOf') except JsonSchemaValueException: data__packagedir_property_names = False if not data__packagedir_property_names: - raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must be named by propertyName definition", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, rule='propertyNames') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".package-dir must be named by propertyName definition", value=data__packagedir, name="" + (name_prefix or "data") + ".package-dir", definition={'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, rule='propertyNames') if "package-data" in data_keys: data_keys.remove("package-data") data__packagedata = data["package-data"] @@ -342,30 +342,30 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm data_keys.remove("namespace-packages") data__namespacepackages = data["namespace-packages"] if not isinstance(data__namespacepackages, (list, tuple)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".namespace-packages must be array", value=data__namespacepackages, name="" + (name_prefix or "data") + ".namespace-packages", definition={'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".namespace-packages must be array", value=data__namespacepackages, name="" + (name_prefix or "data") + ".namespace-packages", definition={'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, rule='type') data__namespacepackages_is_list = isinstance(data__namespacepackages, (list, tuple)) if data__namespacepackages_is_list: data__namespacepackages_len = len(data__namespacepackages) for data__namespacepackages_x, data__namespacepackages_item in enumerate(data__namespacepackages): if not isinstance(data__namespacepackages_item, (str)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + " must be string", value=data__namespacepackages_item, name="" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name'}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + " must be string", value=data__namespacepackages_item, name="" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name-relaxed'}, rule='type') if isinstance(data__namespacepackages_item, str): - if not custom_formats["python-module-name"](data__namespacepackages_item): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + " must be python-module-name", value=data__namespacepackages_item, name="" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name'}, rule='format') + if not custom_formats["python-module-name-relaxed"](data__namespacepackages_item): + raise JsonSchemaValueException("" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + " must be python-module-name-relaxed", value=data__namespacepackages_item, name="" + (name_prefix or "data") + ".namespace-packages[{data__namespacepackages_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name-relaxed'}, rule='format') if "py-modules" in data_keys: data_keys.remove("py-modules") data__pymodules = data["py-modules"] if not isinstance(data__pymodules, (list, tuple)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".py-modules must be array", value=data__pymodules, name="" + (name_prefix or "data") + ".py-modules", definition={'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".py-modules must be array", value=data__pymodules, name="" + (name_prefix or "data") + ".py-modules", definition={'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, rule='type') data__pymodules_is_list = isinstance(data__pymodules, (list, tuple)) if data__pymodules_is_list: data__pymodules_len = len(data__pymodules) for data__pymodules_x, data__pymodules_item in enumerate(data__pymodules): if not isinstance(data__pymodules_item, (str)): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + " must be string", value=data__pymodules_item, name="" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name'}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + " must be string", value=data__pymodules_item, name="" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name-relaxed'}, rule='type') if isinstance(data__pymodules_item, str): - if not custom_formats["python-module-name"](data__pymodules_item): - raise JsonSchemaValueException("" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + " must be python-module-name", value=data__pymodules_item, name="" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name'}, rule='format') + if not custom_formats["python-module-name-relaxed"](data__pymodules_item): + raise JsonSchemaValueException("" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + " must be python-module-name-relaxed", value=data__pymodules_item, name="" + (name_prefix or "data") + ".py-modules[{data__pymodules_x}]".format(**locals()) + "", definition={'type': 'string', 'format': 'python-module-name-relaxed'}, rule='format') if "data-files" in data_keys: data_keys.remove("data-files") data__datafiles = data["data-files"] @@ -524,7 +524,7 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm if data__dynamic_keys: raise JsonSchemaValueException("" + (name_prefix or "data") + ".dynamic must not contain "+str(data__dynamic_keys)+" properties", value=data__dynamic, name="" + (name_prefix or "data") + ".dynamic", definition={'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'classifiers': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'description': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'entry-points': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}}}, 'readme': {'type': 'object', 'anyOf': [{'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'additionalProperties': False}], 'required': ['file']}}}, rule='additionalProperties') if data_keys: - raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'classifiers': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'description': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'entry-points': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}}}, 'readme': {'type': 'object', 'anyOf': [{'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}, rule='additionalProperties') + raise JsonSchemaValueException("" + (name_prefix or "data") + " must not contain "+str(data_keys)+" properties", value=data, name="" + (name_prefix or "data") + "", definition={'$schema': 'http://json-schema.org/draft-07/schema#', '$id': 'https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html', 'title': '``tool.setuptools`` table', '$$description': ['``setuptools``-specific configurations that can be set by users that require', 'customization.', 'These configurations are completely optional and probably can be skipped when', 'creating simple packages. They are equivalent to some of the `Keywords', '`_', 'used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.', 'It considers only ``setuptools`` `parameters', '`_', 'that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``', 'and ``setup_requires`` (incompatible with modern workflows/standards).'], 'type': 'object', 'additionalProperties': False, 'properties': {'platforms': {'type': 'array', 'items': {'type': 'string'}}, 'provides': {'$$description': ['Package and virtual package names contained within this package', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'obsoletes': {'$$description': ['Packages which this package renders obsolete', '**(not supported by pip)**'], 'type': 'array', 'items': {'type': 'string', 'format': 'pep508-identifier'}}, 'zip-safe': {'$$description': ['Whether the project can be safely installed and run from a zip file.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'boolean'}, 'script-files': {'$$description': ['Legacy way of defining scripts (entry-points are preferred).', 'Equivalent to the ``script`` keyword in ``setup.py``', '(it was renamed to avoid confusion with entry-point based ``project.scripts``', 'defined in :pep:`621`).', '**DISCOURAGED**: generic script wrappers are tricky and may not work properly.', 'Whenever possible, please use ``project.scripts`` instead.'], 'type': 'array', 'items': {'type': 'string'}, '$comment': 'TODO: is this field deprecated/should be removed?'}, 'eager-resources': {'$$description': ['Resources that should be extracted together, if any of them is needed,', 'or if any C extensions included in the project are imported.', '**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and', '``setup.py install`` in the context of ``eggs`` (**DEPRECATED**).'], 'type': 'array', 'items': {'type': 'string'}}, 'packages': {'$$description': ['Packages that should be included in the distribution.', 'It can be given either as a list of package identifiers', 'or as a ``dict``-like structure with a single key ``find``', 'which corresponds to a dynamic call to', '``setuptools.config.expand.find_packages`` function.', 'The ``find`` key is associated with a nested ``dict``-like structure that can', 'contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,', 'mimicking the keyword arguments of the associated function.'], 'oneOf': [{'title': 'Array of Python package identifiers', 'type': 'array', 'items': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}}, {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}]}, 'package-dir': {'$$description': [':class:`dict`-like structure mapping from package names to directories where their', 'code can be found.', 'The empty string (as key) means that all packages are contained inside', 'the given directory will be included in the distribution.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'const': ''}, {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}]}, 'patternProperties': {'^.*$': {'type': 'string'}}}, 'package-data': {'$$description': ['Mapping from package names to lists of glob patterns.', 'Usually this option is not needed when using ``include-package-data = true``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'include-package-data': {'$$description': ['Automatically include any data files inside the package directories', 'that are specified by ``MANIFEST.in``', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'boolean'}, 'exclude-package-data': {'$$description': ['Mapping from package names to lists of glob patterns that should be excluded', 'For more information on how to include data files, check ``setuptools`` `docs', '`_.'], 'type': 'object', 'additionalProperties': False, 'propertyNames': {'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'const': '*'}]}, 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'namespace-packages': {'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'https://setuptools.pypa.io/en/latest/userguide/package_discovery.html', 'description': '**DEPRECATED**: use implicit namespaces instead (:pep:`420`).'}, 'py-modules': {'description': 'Modules that setuptools will manipulate', 'type': 'array', 'items': {'type': 'string', 'format': 'python-module-name-relaxed'}, '$comment': 'TODO: clarify the relationship with ``packages``'}, 'data-files': {'$$description': ['``dict``-like structure where each key represents a directory and', 'the value is a list of glob patterns that should be installed in them.', '**DISCOURAGED**: please notice this might not work as expected with wheels.', 'Whenever possible, consider using data files inside the package directories', '(or create a new namespace package that only contains data files).', 'See `data files support', '`_.'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'array', 'items': {'type': 'string'}}}}, 'cmdclass': {'$$description': ['Mapping of distutils-style command names to ``setuptools.Command`` subclasses', 'which in turn should be represented by strings with a qualified class name', '(i.e., "dotted" form with module), e.g.::\n\n', ' cmdclass = {mycmd = "pkg.subpkg.module.CommandClass"}\n\n', 'The command class should be a directly defined at the top-level of the', 'containing module (no class nesting).'], 'type': 'object', 'patternProperties': {'^.*$': {'type': 'string', 'format': 'python-qualified-identifier'}}}, 'license-files': {'type': 'array', 'items': {'type': 'string'}, '$$description': ['**PROVISIONAL**: list of glob patterns for all license files being distributed.', '(likely to become standard with :pep:`639`).', "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``"], '$comment': 'TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?'}, 'dynamic': {'type': 'object', 'description': 'Instructions for loading :pep:`621`-related metadata dynamically', 'additionalProperties': False, 'properties': {'version': {'$$description': ['A version dynamically loaded via either the ``attr:`` or ``file:``', 'directives. Please make sure the given file or attribute respects :pep:`440`.', 'Also ensure to set ``project.dynamic`` accordingly.'], 'oneOf': [{'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'classifiers': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'description': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'entry-points': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}, 'optional-dependencies': {'type': 'object', 'propertyNames': {'type': 'string', 'format': 'pep508-identifier'}, 'additionalProperties': False, 'patternProperties': {'.+': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$ref': '#/definitions/file-directive'}]}}}, 'readme': {'type': 'object', 'anyOf': [{'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, {'type': 'object', 'properties': {'content-type': {'type': 'string'}, 'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'additionalProperties': False}], 'required': ['file']}}}}, 'definitions': {'package-name': {'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, 'file-directive': {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}, 'file-directive-for-dependencies': {'title': "'file:' directive for dependencies", 'allOf': [{'$$description': ['**BETA**: subset of the ``requirements.txt`` format', 'without ``pip`` flags and options', '(one :pep:`508`-compliant string per line,', 'lines that are blank or start with ``#`` are excluded).', 'See `dynamic metadata', '`_.']}, {'$id': '#/definitions/file-directive', 'title': "'file:' directive", 'description': 'Value is read from a file (or list of files and then concatenated)', 'type': 'object', 'additionalProperties': False, 'properties': {'file': {'oneOf': [{'type': 'string'}, {'type': 'array', 'items': {'type': 'string'}}]}}, 'required': ['file']}]}, 'attr-directive': {'title': "'attr:' directive", '$id': '#/definitions/attr-directive', '$$description': ['Value is read from a module attribute. Supports callables and iterables;', 'unsupported types are cast via ``str()``'], 'type': 'object', 'additionalProperties': False, 'properties': {'attr': {'type': 'string', 'format': 'python-qualified-identifier'}}, 'required': ['attr']}, 'find-directive': {'$id': '#/definitions/find-directive', 'title': "'find:' directive", 'type': 'object', 'additionalProperties': False, 'properties': {'find': {'type': 'object', '$$description': ['Dynamic `package discovery', '`_.'], 'additionalProperties': False, 'properties': {'where': {'description': 'Directories to be searched for packages (Unix-style relative path)', 'type': 'array', 'items': {'type': 'string'}}, 'exclude': {'type': 'array', '$$description': ['Exclude packages that match the values listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'include': {'type': 'array', '$$description': ['Restrict the found packages to just the ones listed in this field.', "Can container shell-style wildcards (e.g. ``'pkg.*'``)"], 'items': {'type': 'string'}}, 'namespaces': {'type': 'boolean', '$$description': ['When ``True``, directories without a ``__init__.py`` file will also', 'be scanned for :pep:`420`-style implicit namespaces']}}}}}}}, rule='additionalProperties') return data def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_html__definitions_file_directive_properties_file(data, custom_formats={}, name_prefix=None): @@ -673,15 +673,15 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_html__definitions_package_name(data, custom_formats={}, name_prefix=None): if not isinstance(data, (str)): - raise JsonSchemaValueException("" + (name_prefix or "data") + " must be string", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + " must be string", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, rule='type') data_any_of_count9 = 0 if not data_any_of_count9: try: if not isinstance(data, (str)): - raise JsonSchemaValueException("" + (name_prefix or "data") + " must be string", value=data, name="" + (name_prefix or "data") + "", definition={'type': 'string', 'format': 'python-module-name'}, rule='type') + raise JsonSchemaValueException("" + (name_prefix or "data") + " must be string", value=data, name="" + (name_prefix or "data") + "", definition={'type': 'string', 'format': 'python-module-name-relaxed'}, rule='type') if isinstance(data, str): - if not custom_formats["python-module-name"](data): - raise JsonSchemaValueException("" + (name_prefix or "data") + " must be python-module-name", value=data, name="" + (name_prefix or "data") + "", definition={'type': 'string', 'format': 'python-module-name'}, rule='format') + if not custom_formats["python-module-name-relaxed"](data): + raise JsonSchemaValueException("" + (name_prefix or "data") + " must be python-module-name-relaxed", value=data, name="" + (name_prefix or "data") + "", definition={'type': 'string', 'format': 'python-module-name-relaxed'}, rule='format') data_any_of_count9 += 1 except JsonSchemaValueException: pass if not data_any_of_count9: @@ -694,7 +694,7 @@ def validate_https___setuptools_pypa_io_en_latest_userguide_pyproject_config_htm data_any_of_count9 += 1 except JsonSchemaValueException: pass if not data_any_of_count9: - raise JsonSchemaValueException("" + (name_prefix or "data") + " cannot be validated by any definition", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, rule='anyOf') + raise JsonSchemaValueException("" + (name_prefix or "data") + " cannot be validated by any definition", value=data, name="" + (name_prefix or "data") + "", definition={'$id': '#/definitions/package-name', 'title': 'Valid package name', 'description': 'Valid package name (importable or :pep:`561`).', 'type': 'string', 'anyOf': [{'type': 'string', 'format': 'python-module-name-relaxed'}, {'type': 'string', 'format': 'pep561-stub-name'}]}, rule='anyOf') return data def validate_https___setuptools_pypa_io_en_latest_deprecated_distutils_configfile_html(data, custom_formats={}, name_prefix=None): diff --git a/uno/lib/python/setuptools/config/_validate_pyproject/formats.py b/uno/lib/python/setuptools/config/_validate_pyproject/formats.py index aacf4092..153b1f0b 100644 --- a/uno/lib/python/setuptools/config/_validate_pyproject/formats.py +++ b/uno/lib/python/setuptools/config/_validate_pyproject/formats.py @@ -83,7 +83,9 @@ def pep508_identifier(name: str) -> bool: from packaging import requirements as _req except ImportError: # pragma: no cover # let's try setuptools vendored version - from setuptools._vendor.packaging import requirements as _req # type: ignore + from setuptools._vendor.packaging import ( # type: ignore[no-redef] + requirements as _req, + ) def pep508(value: str) -> bool: """See :ref:`PyPA's dependency specifiers ` @@ -91,9 +93,9 @@ def pep508(value: str) -> bool: """ try: _req.Requirement(value) + return True except _req.InvalidRequirement: return False - return True except ImportError: # pragma: no cover _logger.warning( @@ -289,6 +291,25 @@ def python_module_name(value: str) -> bool: return python_qualified_identifier(value) +def python_module_name_relaxed(value: str) -> bool: + """Similar to :obj:`python_module_name`, but relaxed to also accept + dash characters (``-``) and cover special cases like ``pip-run``. + + It is recommended, however, that beginners avoid dash characters, + as they require advanced knowledge about Python internals. + + The following are disallowed: + + * names starting/ending in dashes, + * names ending in ``-stubs`` (potentially collide with :obj:`pep561_stub_name`). + """ + if value.startswith("-") or value.endswith("-"): + return False + if value.endswith("-stubs"): + return False # Avoid collision with PEP 561 + return python_module_name(value.replace("-", "_")) + + def python_entrypoint_group(value: str) -> bool: """See ``Data model > group`` in the :ref:`PyPA's entry-points specification `. diff --git a/uno/lib/python/setuptools/config/distutils.schema.json b/uno/lib/python/setuptools/config/distutils.schema.json new file mode 100644 index 00000000..93cd2e86 --- /dev/null +++ b/uno/lib/python/setuptools/config/distutils.schema.json @@ -0,0 +1,26 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + + "$id": "https://setuptools.pypa.io/en/latest/deprecated/distutils/configfile.html", + "title": "``tool.distutils`` table", + "$$description": [ + "**EXPERIMENTAL** (NOT OFFICIALLY SUPPORTED): Use ``tool.distutils``", + "subtables to configure arguments for ``distutils`` commands.", + "Originally, ``distutils`` allowed developers to configure arguments for", + "``setup.py`` commands via `distutils configuration files", + "`_.", + "See also `the old Python docs _`." + ], + + "type": "object", + "properties": { + "global": { + "type": "object", + "description": "Global options applied to all ``distutils`` commands" + } + }, + "patternProperties": { + ".+": {"type": "object"} + }, + "$comment": "TODO: Is there a practical way of making this schema more specific?" +} diff --git a/uno/lib/python/setuptools/config/expand.py b/uno/lib/python/setuptools/config/expand.py index de6339fa..dfee1c5d 100644 --- a/uno/lib/python/setuptools/config/expand.py +++ b/uno/lib/python/setuptools/config/expand.py @@ -25,28 +25,20 @@ import os import pathlib import sys -from glob import iglob from configparser import ConfigParser +from glob import iglob from importlib.machinery import ModuleSpec, all_suffixes from itertools import chain -from typing import ( - TYPE_CHECKING, - Any, - Callable, - Iterable, - Iterator, - Mapping, - TypeVar, -) from pathlib import Path from types import ModuleType +from typing import TYPE_CHECKING, Any, Callable, Iterable, Iterator, Mapping, TypeVar -from distutils.errors import DistutilsOptionError - -from .._path import same_path as _same_path, StrPath +from .._path import StrPath, same_path as _same_path from ..discovery import find_package_path from ..warnings import SetuptoolsWarning +from distutils.errors import DistutilsOptionError + if TYPE_CHECKING: from setuptools.dist import Distribution @@ -287,8 +279,9 @@ def find_packages( :rtype: list """ + from more_itertools import always_iterable, unique_everseen + from setuptools.discovery import construct_package_dir - from more_itertools import unique_everseen, always_iterable if namespaces: from setuptools.discovery import PEP420PackageFinder as PackageFinder diff --git a/uno/lib/python/setuptools/config/pyprojecttoml.py b/uno/lib/python/setuptools/config/pyprojecttoml.py index a83e43bb..943b9f5a 100644 --- a/uno/lib/python/setuptools/config/pyprojecttoml.py +++ b/uno/lib/python/setuptools/config/pyprojecttoml.py @@ -21,13 +21,13 @@ from ..errors import FileError, InvalidConfigError from ..warnings import SetuptoolsWarning from . import expand as _expand -from ._apply_pyprojecttoml import _PREVIOUSLY_DEFINED, _MissingDynamic -from ._apply_pyprojecttoml import apply as _apply +from ._apply_pyprojecttoml import _PREVIOUSLY_DEFINED, _MissingDynamic, apply as _apply if TYPE_CHECKING: - from setuptools.dist import Distribution from typing_extensions import Self + from setuptools.dist import Distribution + _logger = logging.getLogger(__name__) @@ -121,7 +121,7 @@ def read_configuration( # the default would be an improvement. # `ini2toml` backfills include_package_data=False when nothing is explicitly given, # therefore setting a default here is backwards compatible. - if dist and getattr(dist, "include_package_data", None) is not None: + if dist and dist.include_package_data is not None: setuptools_table.setdefault("include-package-data", dist.include_package_data) else: setuptools_table.setdefault("include-package-data", True) diff --git a/uno/lib/python/setuptools/config/setupcfg.py b/uno/lib/python/setuptools/config/setupcfg.py index 5a3b7478..e8254770 100644 --- a/uno/lib/python/setuptools/config/setupcfg.py +++ b/uno/lib/python/setuptools/config/setupcfg.py @@ -15,12 +15,11 @@ import functools import os from collections import defaultdict -from functools import partial -from functools import wraps +from functools import partial, wraps from typing import ( TYPE_CHECKING, - Callable, Any, + Callable, Dict, Generic, Iterable, @@ -30,20 +29,21 @@ Union, ) -from .._path import StrPath -from ..errors import FileError, OptionError from packaging.markers import default_environment as marker_env from packaging.requirements import InvalidRequirement, Requirement from packaging.specifiers import SpecifierSet from packaging.version import InvalidVersion, Version + +from .._path import StrPath +from ..errors import FileError, OptionError from ..warnings import SetuptoolsDeprecationWarning from . import expand if TYPE_CHECKING: - from distutils.dist import DistributionMetadata - from setuptools.dist import Distribution + from distutils.dist import DistributionMetadata + SingleCommandOptions = Dict["str", Tuple["str", Any]] """Dict that associate the name of the options of a particular command to a tuple. The first element of the tuple indicates the origin of the option value diff --git a/uno/lib/python/setuptools/config/setuptools.schema.json b/uno/lib/python/setuptools/config/setuptools.schema.json new file mode 100644 index 00000000..50ee6217 --- /dev/null +++ b/uno/lib/python/setuptools/config/setuptools.schema.json @@ -0,0 +1,352 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + + "$id": "https://setuptools.pypa.io/en/latest/userguide/pyproject_config.html", + "title": "``tool.setuptools`` table", + "$$description": [ + "``setuptools``-specific configurations that can be set by users that require", + "customization.", + "These configurations are completely optional and probably can be skipped when", + "creating simple packages. They are equivalent to some of the `Keywords", + "`_", + "used by the ``setup.py`` file, and can be set via the ``tool.setuptools`` table.", + "It considers only ``setuptools`` `parameters", + "`_", + "that are not covered by :pep:`621`; and intentionally excludes ``dependency_links``", + "and ``setup_requires`` (incompatible with modern workflows/standards)." + ], + + "type": "object", + "additionalProperties": false, + "properties": { + "platforms": { + "type": "array", + "items": {"type": "string"} + }, + "provides": { + "$$description": [ + "Package and virtual package names contained within this package", + "**(not supported by pip)**" + ], + "type": "array", + "items": {"type": "string", "format": "pep508-identifier"} + }, + "obsoletes": { + "$$description": [ + "Packages which this package renders obsolete", + "**(not supported by pip)**" + ], + "type": "array", + "items": {"type": "string", "format": "pep508-identifier"} + }, + "zip-safe": { + "$$description": [ + "Whether the project can be safely installed and run from a zip file.", + "**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and", + "``setup.py install`` in the context of ``eggs`` (**DEPRECATED**)." + ], + "type": "boolean" + }, + "script-files": { + "$$description": [ + "Legacy way of defining scripts (entry-points are preferred).", + "Equivalent to the ``script`` keyword in ``setup.py``", + "(it was renamed to avoid confusion with entry-point based ``project.scripts``", + "defined in :pep:`621`).", + "**DISCOURAGED**: generic script wrappers are tricky and may not work properly.", + "Whenever possible, please use ``project.scripts`` instead." + ], + "type": "array", + "items": {"type": "string"}, + "$comment": "TODO: is this field deprecated/should be removed?" + }, + "eager-resources": { + "$$description": [ + "Resources that should be extracted together, if any of them is needed,", + "or if any C extensions included in the project are imported.", + "**OBSOLETE**: only relevant for ``pkg_resources``, ``easy_install`` and", + "``setup.py install`` in the context of ``eggs`` (**DEPRECATED**)." + ], + "type": "array", + "items": {"type": "string"} + }, + "packages": { + "$$description": [ + "Packages that should be included in the distribution.", + "It can be given either as a list of package identifiers", + "or as a ``dict``-like structure with a single key ``find``", + "which corresponds to a dynamic call to", + "``setuptools.config.expand.find_packages`` function.", + "The ``find`` key is associated with a nested ``dict``-like structure that can", + "contain ``where``, ``include``, ``exclude`` and ``namespaces`` keys,", + "mimicking the keyword arguments of the associated function." + ], + "oneOf": [ + { + "title": "Array of Python package identifiers", + "type": "array", + "items": {"$ref": "#/definitions/package-name"} + }, + {"$ref": "#/definitions/find-directive"} + ] + }, + "package-dir": { + "$$description": [ + ":class:`dict`-like structure mapping from package names to directories where their", + "code can be found.", + "The empty string (as key) means that all packages are contained inside", + "the given directory will be included in the distribution." + ], + "type": "object", + "additionalProperties": false, + "propertyNames": { + "anyOf": [{"const": ""}, {"$ref": "#/definitions/package-name"}] + }, + "patternProperties": { + "^.*$": {"type": "string" } + } + }, + "package-data": { + "$$description": [ + "Mapping from package names to lists of glob patterns.", + "Usually this option is not needed when using ``include-package-data = true``", + "For more information on how to include data files, check ``setuptools`` `docs", + "`_." + ], + "type": "object", + "additionalProperties": false, + "propertyNames": { + "anyOf": [{"type": "string", "format": "python-module-name"}, {"const": "*"}] + }, + "patternProperties": { + "^.*$": {"type": "array", "items": {"type": "string"}} + } + }, + "include-package-data": { + "$$description": [ + "Automatically include any data files inside the package directories", + "that are specified by ``MANIFEST.in``", + "For more information on how to include data files, check ``setuptools`` `docs", + "`_." + ], + "type": "boolean" + }, + "exclude-package-data": { + "$$description": [ + "Mapping from package names to lists of glob patterns that should be excluded", + "For more information on how to include data files, check ``setuptools`` `docs", + "`_." + ], + "type": "object", + "additionalProperties": false, + "propertyNames": { + "anyOf": [{"type": "string", "format": "python-module-name"}, {"const": "*"}] + }, + "patternProperties": { + "^.*$": {"type": "array", "items": {"type": "string"}} + } + }, + "namespace-packages": { + "type": "array", + "items": {"type": "string", "format": "python-module-name-relaxed"}, + "$comment": "https://setuptools.pypa.io/en/latest/userguide/package_discovery.html", + "description": "**DEPRECATED**: use implicit namespaces instead (:pep:`420`)." + }, + "py-modules": { + "description": "Modules that setuptools will manipulate", + "type": "array", + "items": {"type": "string", "format": "python-module-name-relaxed"}, + "$comment": "TODO: clarify the relationship with ``packages``" + }, + "data-files": { + "$$description": [ + "``dict``-like structure where each key represents a directory and", + "the value is a list of glob patterns that should be installed in them.", + "**DISCOURAGED**: please notice this might not work as expected with wheels.", + "Whenever possible, consider using data files inside the package directories", + "(or create a new namespace package that only contains data files).", + "See `data files support", + "`_." + ], + "type": "object", + "patternProperties": { + "^.*$": {"type": "array", "items": {"type": "string"}} + } + }, + "cmdclass": { + "$$description": [ + "Mapping of distutils-style command names to ``setuptools.Command`` subclasses", + "which in turn should be represented by strings with a qualified class name", + "(i.e., \"dotted\" form with module), e.g.::\n\n", + " cmdclass = {mycmd = \"pkg.subpkg.module.CommandClass\"}\n\n", + "The command class should be a directly defined at the top-level of the", + "containing module (no class nesting)." + ], + "type": "object", + "patternProperties": { + "^.*$": {"type": "string", "format": "python-qualified-identifier"} + } + }, + "license-files": { + "type": "array", + "items": {"type": "string"}, + "$$description": [ + "**PROVISIONAL**: list of glob patterns for all license files being distributed.", + "(likely to become standard with :pep:`639`).", + "By default: ``['LICEN[CS]E*', 'COPYING*', 'NOTICE*', 'AUTHORS*']``" + ], + "$comment": "TODO: revise if PEP 639 is accepted. Probably ``project.license-files``?" + }, + "dynamic": { + "type": "object", + "description": "Instructions for loading :pep:`621`-related metadata dynamically", + "additionalProperties": false, + "properties": { + "version": { + "$$description": [ + "A version dynamically loaded via either the ``attr:`` or ``file:``", + "directives. Please make sure the given file or attribute respects :pep:`440`.", + "Also ensure to set ``project.dynamic`` accordingly." + ], + "oneOf": [ + {"$ref": "#/definitions/attr-directive"}, + {"$ref": "#/definitions/file-directive"} + ] + }, + "classifiers": {"$ref": "#/definitions/file-directive"}, + "description": {"$ref": "#/definitions/file-directive"}, + "entry-points": {"$ref": "#/definitions/file-directive"}, + "dependencies": {"$ref": "#/definitions/file-directive-for-dependencies"}, + "optional-dependencies": { + "type": "object", + "propertyNames": {"type": "string", "format": "pep508-identifier"}, + "additionalProperties": false, + "patternProperties": { + ".+": {"$ref": "#/definitions/file-directive-for-dependencies"} + } + }, + "readme": { + "type": "object", + "anyOf": [ + {"$ref": "#/definitions/file-directive"}, + { + "type": "object", + "properties": { + "content-type": {"type": "string"}, + "file": { "$ref": "#/definitions/file-directive/properties/file" } + }, + "additionalProperties": false} + ], + "required": ["file"] + } + } + } + }, + + "definitions": { + "package-name": { + "$id": "#/definitions/package-name", + "title": "Valid package name", + "description": "Valid package name (importable or :pep:`561`).", + "type": "string", + "anyOf": [ + {"type": "string", "format": "python-module-name-relaxed"}, + {"type": "string", "format": "pep561-stub-name"} + ] + }, + "file-directive": { + "$id": "#/definitions/file-directive", + "title": "'file:' directive", + "description": + "Value is read from a file (or list of files and then concatenated)", + "type": "object", + "additionalProperties": false, + "properties": { + "file": { + "oneOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}} + ] + } + }, + "required": ["file"] + }, + "file-directive-for-dependencies": { + "title": "'file:' directive for dependencies", + "allOf": [ + { + "$$description": [ + "**BETA**: subset of the ``requirements.txt`` format", + "without ``pip`` flags and options", + "(one :pep:`508`-compliant string per line,", + "lines that are blank or start with ``#`` are excluded).", + "See `dynamic metadata", + "`_." + ] + }, + {"$ref": "#/definitions/file-directive"} + ] + }, + "attr-directive": { + "title": "'attr:' directive", + "$id": "#/definitions/attr-directive", + "$$description": [ + "Value is read from a module attribute. Supports callables and iterables;", + "unsupported types are cast via ``str()``" + ], + "type": "object", + "additionalProperties": false, + "properties": { + "attr": {"type": "string", "format": "python-qualified-identifier"} + }, + "required": ["attr"] + }, + "find-directive": { + "$id": "#/definitions/find-directive", + "title": "'find:' directive", + "type": "object", + "additionalProperties": false, + "properties": { + "find": { + "type": "object", + "$$description": [ + "Dynamic `package discovery", + "`_." + ], + "additionalProperties": false, + "properties": { + "where": { + "description": + "Directories to be searched for packages (Unix-style relative path)", + "type": "array", + "items": {"type": "string"} + }, + "exclude": { + "type": "array", + "$$description": [ + "Exclude packages that match the values listed in this field.", + "Can container shell-style wildcards (e.g. ``'pkg.*'``)" + ], + "items": {"type": "string"} + }, + "include": { + "type": "array", + "$$description": [ + "Restrict the found packages to just the ones listed in this field.", + "Can container shell-style wildcards (e.g. ``'pkg.*'``)" + ], + "items": {"type": "string"} + }, + "namespaces": { + "type": "boolean", + "$$description": [ + "When ``True``, directories without a ``__init__.py`` file will also", + "be scanned for :pep:`420`-style implicit namespaces" + ] + } + } + } + } + } + } +} diff --git a/uno/lib/python/setuptools/depends.py b/uno/lib/python/setuptools/depends.py index 871a0925..9398b953 100644 --- a/uno/lib/python/setuptools/depends.py +++ b/uno/lib/python/setuptools/depends.py @@ -1,13 +1,12 @@ -import sys -import marshal import contextlib import dis +import marshal +import sys - -from . import _imp -from ._imp import find_module, PY_COMPILED, PY_FROZEN, PY_SOURCE from packaging.version import Version +from . import _imp +from ._imp import PY_COMPILED, PY_FROZEN, PY_SOURCE, find_module __all__ = ['Require', 'find_module'] diff --git a/uno/lib/python/setuptools/discovery.py b/uno/lib/python/setuptools/discovery.py index 3179852c..577be2f1 100644 --- a/uno/lib/python/setuptools/discovery.py +++ b/uno/lib/python/setuptools/discovery.py @@ -44,16 +44,12 @@ from fnmatch import fnmatchcase from glob import glob from pathlib import Path -from typing import ( - TYPE_CHECKING, - Iterable, - Iterator, - Mapping, -) +from typing import TYPE_CHECKING, Iterable, Iterator, Mapping import _distutils_hack.override # noqa: F401 from ._path import StrPath + from distutils import log from distutils.util import convert_path diff --git a/uno/lib/python/setuptools/dist.py b/uno/lib/python/setuptools/dist.py index 6a29b2b2..715e8fbb 100644 --- a/uno/lib/python/setuptools/dist.py +++ b/uno/lib/python/setuptools/dist.py @@ -10,31 +10,32 @@ from pathlib import Path from typing import TYPE_CHECKING, MutableMapping -import distutils.cmd -import distutils.command -import distutils.core -import distutils.dist -import distutils.log -from distutils.debug import DEBUG -from distutils.errors import DistutilsOptionError, DistutilsSetupError -from distutils.fancy_getopt import translate_longopt -from distutils.util import strtobool - from more_itertools import partition, unique_everseen -from ordered_set import OrderedSet from packaging.markers import InvalidMarker, Marker from packaging.specifiers import InvalidSpecifier, SpecifierSet from packaging.version import Version -from . import _entry_points -from . import _reqs -from . import command as _ # noqa -- imported for side-effects +from . import ( + _entry_points, + _reqs, + command as _, # noqa: F401 # imported for side-effects +) from ._importlib import metadata -from .config import setupcfg, pyprojecttoml +from .config import pyprojecttoml, setupcfg from .discovery import ConfigDiscovery from .monkey import get_unpatched from .warnings import InformationOnly, SetuptoolsDeprecationWarning +import distutils.cmd +import distutils.command +import distutils.core +import distutils.dist +import distutils.log +from distutils.debug import DEBUG +from distutils.errors import DistutilsOptionError, DistutilsSetupError +from distutils.fancy_getopt import translate_longopt +from distutils.util import strtobool + __all__ = ['Distribution'] sequence = tuple, list @@ -55,7 +56,7 @@ def assert_string_list(dist, attr, value): try: # verify that value is a list or tuple to exclude unordered # or single-use iterables - assert isinstance(value, (list, tuple)) + assert isinstance(value, sequence) # verify that elements of value are strings assert ''.join(value) != value except (TypeError, ValueError, AttributeError, AssertionError) as e: @@ -249,7 +250,7 @@ class Distribution(_Distribution): _DISTUTILS_UNSUPPORTED_METADATA = { 'long_description_content_type': lambda: None, 'project_urls': dict, - 'provides_extras': OrderedSet, + 'provides_extras': dict, # behaves like an ordered set 'license_file': lambda: None, 'license_files': lambda: None, 'install_requires': list, @@ -265,6 +266,8 @@ def __init__(self, attrs: MutableMapping | None = None) -> None: self.package_data: dict[str, list[str]] = {} attrs = attrs or {} self.dist_files: list[tuple[str, str, str]] = [] + self.include_package_data: bool | None = None + self.exclude_package_data: dict[str, list[str]] | None = None # Filter-out setuptools' specific options. self.src_root = attrs.pop("src_root", None) self.dependency_links = attrs.pop('dependency_links', []) @@ -345,7 +348,7 @@ def _finalize_requires(self): # Setuptools allows a weird ": syntax for extras extra = extra.split(':')[0] if extra: - self.metadata.provides_extras.add(extra) + self.metadata.provides_extras.setdefault(extra) def _normalize_requires(self): """Make sure requirement-related attributes exist and are normalized""" diff --git a/uno/lib/python/setuptools/errors.py b/uno/lib/python/setuptools/errors.py index 67a5a1df..dd4e58e9 100644 --- a/uno/lib/python/setuptools/errors.py +++ b/uno/lib/python/setuptools/errors.py @@ -5,7 +5,6 @@ from distutils import errors as _distutils_errors - # Re-export errors from distutils to facilitate the migration to PEP632 ByteCompileError = _distutils_errors.DistutilsByteCompileError diff --git a/uno/lib/python/setuptools/extension.py b/uno/lib/python/setuptools/extension.py index 25420f42..b9fff236 100644 --- a/uno/lib/python/setuptools/extension.py +++ b/uno/lib/python/setuptools/extension.py @@ -1,12 +1,15 @@ -import re +from __future__ import annotations + import functools -import distutils.core -import distutils.errors -import distutils.extension +import re from typing import TYPE_CHECKING from .monkey import get_unpatched +import distutils.core +import distutils.errors +import distutils.extension + def _have_cython(): """ @@ -126,10 +129,19 @@ class Extension(_Extension): specified on Windows. (since v63) """ - def __init__(self, name, sources, *args, **kw): + # These 4 are set and used in setuptools/command/build_ext.py + # The lack of a default value and risk of `AttributeError` is purposeful + # to avoid people forgetting to call finalize_options if they modify the extension list. + # See example/rationale in https://github.com/pypa/setuptools/issues/4529. + _full_name: str #: Private API, internal use only. + _links_to_dynamic: bool #: Private API, internal use only. + _needs_stub: bool #: Private API, internal use only. + _file_name: str #: Private API, internal use only. + + def __init__(self, name: str, sources, *args, py_limited_api: bool = False, **kw): # The *args is needed for compatibility as calls may use positional # arguments. py_limited_api may be set only via keyword. - self.py_limited_api = kw.pop("py_limited_api", False) + self.py_limited_api = py_limited_api super().__init__(name, sources, *args, **kw) def _convert_pyx_sources_to_lang(self): diff --git a/uno/lib/python/setuptools/glob.py b/uno/lib/python/setuptools/glob.py index a184c0b6..ffe0ae92 100644 --- a/uno/lib/python/setuptools/glob.py +++ b/uno/lib/python/setuptools/glob.py @@ -6,9 +6,9 @@ * Hidden files are not ignored. """ +import fnmatch import os import re -import fnmatch __all__ = ["glob", "iglob", "escape"] diff --git a/uno/lib/python/setuptools/installer.py b/uno/lib/python/setuptools/installer.py index a6aff723..ce3559cd 100644 --- a/uno/lib/python/setuptools/installer.py +++ b/uno/lib/python/setuptools/installer.py @@ -3,13 +3,14 @@ import subprocess import sys import tempfile -from distutils import log -from distutils.errors import DistutilsError from functools import partial from . import _reqs -from .wheel import Wheel from .warnings import SetuptoolsDeprecationWarning +from .wheel import Wheel + +from distutils import log +from distutils.errors import DistutilsError def _fixup_find_links(find_links): diff --git a/uno/lib/python/setuptools/launch.py b/uno/lib/python/setuptools/launch.py index 0208fdf3..56c7d035 100644 --- a/uno/lib/python/setuptools/launch.py +++ b/uno/lib/python/setuptools/launch.py @@ -6,8 +6,8 @@ # Note that setuptools gets imported implicitly by the # invocation of this script using python -m setuptools.launch -import tokenize import sys +import tokenize def run(): diff --git a/uno/lib/python/setuptools/logging.py b/uno/lib/python/setuptools/logging.py index ceca99ca..e9674c5a 100644 --- a/uno/lib/python/setuptools/logging.py +++ b/uno/lib/python/setuptools/logging.py @@ -1,9 +1,11 @@ -import sys import inspect import logging -import distutils.log +import sys + from . import monkey +import distutils.log + def _not_warning(record): return record.levelno < logging.WARNING diff --git a/uno/lib/python/setuptools/modified.py b/uno/lib/python/setuptools/modified.py index af6ceeac..245a6158 100644 --- a/uno/lib/python/setuptools/modified.py +++ b/uno/lib/python/setuptools/modified.py @@ -1,7 +1,7 @@ from ._distutils._modified import ( newer, - newer_pairwise, newer_group, + newer_pairwise, newer_pairwise_group, ) diff --git a/uno/lib/python/setuptools/monkey.py b/uno/lib/python/setuptools/monkey.py index e513f952..abcc2755 100644 --- a/uno/lib/python/setuptools/monkey.py +++ b/uno/lib/python/setuptools/monkey.py @@ -14,7 +14,6 @@ import distutils.filelist - _T = TypeVar("_T") __all__: list[str] = [] diff --git a/uno/lib/python/setuptools/msvc.py b/uno/lib/python/setuptools/msvc.py index 27680592..ca332d59 100644 --- a/uno/lib/python/setuptools/msvc.py +++ b/uno/lib/python/setuptools/msvc.py @@ -13,19 +13,20 @@ from __future__ import annotations -import json -from os import listdir, pathsep -from os.path import join, isfile, isdir, dirname -from subprocess import CalledProcessError import contextlib -import platform import itertools +import json +import platform import subprocess -import distutils.errors +from os import listdir, pathsep +from os.path import dirname, isdir, isfile, join +from subprocess import CalledProcessError from typing import TYPE_CHECKING from more_itertools import unique_everseen +import distutils.errors + # https://github.com/python/mypy/issues/8166 if not TYPE_CHECKING and platform.system() == 'Windows': import winreg diff --git a/uno/lib/python/setuptools/namespaces.py b/uno/lib/python/setuptools/namespaces.py index 2f2c1cfb..e82439e3 100644 --- a/uno/lib/python/setuptools/namespaces.py +++ b/uno/lib/python/setuptools/namespaces.py @@ -1,9 +1,9 @@ -import os -from distutils import log import itertools +import os from .compat import py39 +from distutils import log flatten = itertools.chain.from_iterable diff --git a/uno/lib/python/setuptools/package_index.py b/uno/lib/python/setuptools/package_index.py index c24c7837..a66cbb2e 100644 --- a/uno/lib/python/setuptools/package_index.py +++ b/uno/lib/python/setuptools/package_index.py @@ -1,49 +1,49 @@ """PyPI and direct package downloading.""" -import sys -import subprocess -import os -import re -import io -import shutil -import socket import base64 -import hashlib -import itertools import configparser +import hashlib import html import http.client +import io +import itertools +import os +import re +import shutil +import socket +import subprocess +import sys +import urllib.error import urllib.parse import urllib.request -import urllib.error +from fnmatch import translate from functools import wraps +from more_itertools import unique_everseen + import setuptools from pkg_resources import ( - CHECKOUT_DIST, - Distribution, BINARY_DIST, - normalize_path, + CHECKOUT_DIST, + DEVELOP_DIST, + EGG_DIST, SOURCE_DIST, + Distribution, Environment, + Requirement, find_distributions, + normalize_path, + parse_version, safe_name, safe_version, to_filename, - Requirement, - DEVELOP_DIST, - EGG_DIST, - parse_version, ) -from distutils import log -from distutils.errors import DistutilsError -from fnmatch import translate from setuptools.wheel import Wheel -from more_itertools import unique_everseen - -from .unicode_utils import _read_utf8_with_fallback, _cfg_read_utf8_with_fallback +from .unicode_utils import _cfg_read_utf8_with_fallback, _read_utf8_with_fallback +from distutils import log +from distutils.errors import DistutilsError EGG_FRAGMENT = re.compile(r'^egg=([-A-Za-z0-9_.+!]+)$') HREF = re.compile(r"""href\s*=\s*['"]?([^'"> ]+)""", re.I) diff --git a/uno/lib/python/setuptools/sandbox.py b/uno/lib/python/setuptools/sandbox.py index 147b2674..7d545f10 100644 --- a/uno/lib/python/setuptools/sandbox.py +++ b/uno/lib/python/setuptools/sandbox.py @@ -1,29 +1,26 @@ from __future__ import annotations -import os -import sys -import tempfile -import operator +import builtins +import contextlib import functools import itertools -import re -import contextlib +import operator +import os import pickle +import re +import sys +import tempfile import textwrap -import builtins import pkg_resources -from distutils.errors import DistutilsError from pkg_resources import working_set +from distutils.errors import DistutilsError + if sys.platform.startswith('java'): import org.python.modules.posix.PosixModule as _os else: _os = sys.modules[os.name] -try: - _file = file # type: ignore[name-defined] # Check for global variable -except NameError: - _file = None _open = open @@ -283,15 +280,11 @@ def _copy(self, source): def __enter__(self): self._copy(self) - if _file: - builtins.file = self._file builtins.open = self._open self._active = True def __exit__(self, exc_type, exc_value, traceback): self._active = False - if _file: - builtins.file = _file builtins.open = _open self._copy(_os) @@ -324,8 +317,6 @@ def wrap(self, path, *args, **kw): return wrap - if _file: - _file = _mk_single_path_wrapper('file', _file) _open = _mk_single_path_wrapper('open', _open) for __name in [ "stat", @@ -442,13 +433,6 @@ def _violation(self, operation, *args, **kw): raise SandboxViolation(operation, args, kw) - if _file: - - def _file(self, path, mode='r', *args, **kw): - if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): - self._violation("file", path, mode, *args, **kw) - return _file(path, mode, *args, **kw) - def _open(self, path, mode='r', *args, **kw): if mode not in ('r', 'rt', 'rb', 'rU', 'U') and not self._ok(path): self._violation("open", path, mode, *args, **kw) diff --git a/uno/lib/python/setuptools/tests/__init__.py b/uno/lib/python/setuptools/tests/__init__.py index 738ebf43..eb70bfb7 100644 --- a/uno/lib/python/setuptools/tests/__init__.py +++ b/uno/lib/python/setuptools/tests/__init__.py @@ -3,13 +3,11 @@ import pytest - __all__ = ['fail_on_ascii'] -locale_encoding = ( - locale.getencoding() - if sys.version_info >= (3, 11) - else locale.getpreferredencoding(False) -) +if sys.version_info >= (3, 11): + locale_encoding = locale.getencoding() +else: + locale_encoding = locale.getpreferredencoding(False) is_ascii = locale_encoding == 'ANSI_X3.4-1968' fail_on_ascii = pytest.mark.xfail(is_ascii, reason="Test fails in this locale") diff --git a/uno/lib/python/setuptools/tests/compat/py39.py b/uno/lib/python/setuptools/tests/compat/py39.py index 9c86065c..1fdb9dac 100644 --- a/uno/lib/python/setuptools/tests/compat/py39.py +++ b/uno/lib/python/setuptools/tests/compat/py39.py @@ -1,4 +1,3 @@ from jaraco.test.cpython import from_test_support, try_import - os_helper = try_import('os_helper') or from_test_support('can_symlink') diff --git a/uno/lib/python/setuptools/tests/config/downloads/preload.py b/uno/lib/python/setuptools/tests/config/downloads/preload.py index d559beff..8eeb5dd7 100644 --- a/uno/lib/python/setuptools/tests/config/downloads/preload.py +++ b/uno/lib/python/setuptools/tests/config/downloads/preload.py @@ -13,7 +13,6 @@ from . import retrieve_file, urls_from_file - if __name__ == "__main__": urls = urls_from_file(Path(sys.argv[1])) list(map(retrieve_file, urls)) diff --git a/uno/lib/python/setuptools/tests/config/test_apply_pyprojecttoml.py b/uno/lib/python/setuptools/tests/config/test_apply_pyprojecttoml.py index 6650a657..78959b64 100644 --- a/uno/lib/python/setuptools/tests/config/test_apply_pyprojecttoml.py +++ b/uno/lib/python/setuptools/tests/config/test_apply_pyprojecttoml.py @@ -15,20 +15,17 @@ import pytest from ini2toml.api import LiteTranslator - from packaging.metadata import Metadata import setuptools # noqa ensure monkey patch to metadata -from setuptools.dist import Distribution -from setuptools.config import setupcfg, pyprojecttoml -from setuptools.config import expand -from setuptools.config._apply_pyprojecttoml import _MissingDynamic, _some_attrgetter from setuptools.command.egg_info import write_requirements +from setuptools.config import expand, pyprojecttoml, setupcfg +from setuptools.config._apply_pyprojecttoml import _MissingDynamic, _some_attrgetter +from setuptools.dist import Distribution from setuptools.errors import RemovedConfigError from .downloads import retrieve_file, urls_from_file - HERE = Path(__file__).parent EXAMPLES_FILE = "setupcfg_examples.txt" @@ -300,6 +297,33 @@ def test_default_patterns(self, tmp_path): assert set(dist.metadata.license_files) == {*license_files, "LICENSE.txt"} +class TestPyModules: + # https://github.com/pypa/setuptools/issues/4316 + + def dist(self, name): + toml_config = f""" + [project] + name = "test" + version = "42.0" + [tool.setuptools] + py-modules = [{name!r}] + """ + pyproject = Path("pyproject.toml") + pyproject.write_text(cleandoc(toml_config), encoding="utf-8") + return pyprojecttoml.apply_configuration(Distribution({}), pyproject) + + @pytest.mark.parametrize("module", ["pip-run", "abc-d.λ-xyz-e"]) + def test_valid_module_name(self, tmp_path, monkeypatch, module): + monkeypatch.chdir(tmp_path) + assert module in self.dist(module).py_modules + + @pytest.mark.parametrize("module", ["pip run", "-pip-run", "pip-run-stubs"]) + def test_invalid_module_name(self, tmp_path, monkeypatch, module): + monkeypatch.chdir(tmp_path) + with pytest.raises(ValueError, match="py-modules"): + self.dist(module).py_modules + + class TestDeprecatedFields: def test_namespace_packages(self, tmp_path): pyproject = tmp_path / "pyproject.toml" diff --git a/uno/lib/python/setuptools/tests/config/test_expand.py b/uno/lib/python/setuptools/tests/config/test_expand.py index b309a1ce..f51d2008 100644 --- a/uno/lib/python/setuptools/tests/config/test_expand.py +++ b/uno/lib/python/setuptools/tests/config/test_expand.py @@ -4,10 +4,11 @@ import pytest -from distutils.errors import DistutilsOptionError from setuptools.config import expand from setuptools.discovery import find_package_path +from distutils.errors import DistutilsOptionError + def write_files(files, root_dir): for file, content in files.items(): diff --git a/uno/lib/python/setuptools/tests/config/test_pyprojecttoml.py b/uno/lib/python/setuptools/tests/config/test_pyprojecttoml.py index bf8cae5a..bb15ce10 100644 --- a/uno/lib/python/setuptools/tests/config/test_pyprojecttoml.py +++ b/uno/lib/python/setuptools/tests/config/test_pyprojecttoml.py @@ -7,18 +7,17 @@ import tomli_w from path import Path +import setuptools # noqa: F401 # force distutils.core to be patched from setuptools.config.pyprojecttoml import ( _ToolsTypoInMetadata, - read_configuration, - expand_configuration, apply_configuration, + expand_configuration, + read_configuration, validate, ) from setuptools.dist import Distribution from setuptools.errors import OptionError - -import setuptools # noqa -- force distutils.core to be patched import distutils.core EXAMPLE = """ diff --git a/uno/lib/python/setuptools/tests/config/test_setupcfg.py b/uno/lib/python/setuptools/tests/config/test_setupcfg.py index 0074fe23..4f0a7349 100644 --- a/uno/lib/python/setuptools/tests/config/test_setupcfg.py +++ b/uno/lib/python/setuptools/tests/config/test_setupcfg.py @@ -5,14 +5,16 @@ from unittest.mock import Mock, patch import pytest +from packaging.requirements import InvalidRequirement -from distutils.errors import DistutilsOptionError, DistutilsFileError -from setuptools.dist import Distribution, _Distribution from setuptools.config.setupcfg import ConfigHandler, read_configuration -from packaging.requirements import InvalidRequirement +from setuptools.dist import Distribution, _Distribution from setuptools.warnings import SetuptoolsDeprecationWarning + from ..textwrap import DALS +from distutils.errors import DistutilsFileError, DistutilsOptionError + class ErrConfigHandler(ConfigHandler): """Erroneous handler. Fails to implement required methods.""" @@ -673,7 +675,7 @@ def test_extras_require(self, tmpdir): 'pdf': ['ReportLab>=1.2', 'RXP'], 'rest': ['docutils>=0.3', 'pack==1.1,==1.3'], } - assert dist.metadata.provides_extras == set(['pdf', 'rest']) + assert set(dist.metadata.provides_extras) == {'pdf', 'rest'} @pytest.mark.parametrize( "config", diff --git a/uno/lib/python/setuptools/tests/contexts.py b/uno/lib/python/setuptools/tests/contexts.py index 112cdf4b..97cceea0 100644 --- a/uno/lib/python/setuptools/tests/contexts.py +++ b/uno/lib/python/setuptools/tests/contexts.py @@ -1,10 +1,10 @@ -import tempfile +import contextlib +import io import os import shutil -import sys -import contextlib import site -import io +import sys +import tempfile from filelock import FileLock diff --git a/uno/lib/python/setuptools/tests/environment.py b/uno/lib/python/setuptools/tests/environment.py index b9de4fda..ed5499ef 100644 --- a/uno/lib/python/setuptools/tests/environment.py +++ b/uno/lib/python/setuptools/tests/environment.py @@ -1,8 +1,8 @@ import os -import sys import subprocess +import sys import unicodedata -from subprocess import Popen as _Popen, PIPE as _PIPE +from subprocess import PIPE as _PIPE, Popen as _Popen import jaraco.envs diff --git a/uno/lib/python/setuptools/tests/fixtures.py b/uno/lib/python/setuptools/tests/fixtures.py index a2870f11..a5472984 100644 --- a/uno/lib/python/setuptools/tests/fixtures.py +++ b/uno/lib/python/setuptools/tests/fixtures.py @@ -1,11 +1,11 @@ -import os import contextlib -import sys +import os import subprocess +import sys from pathlib import Path -import pytest import path +import pytest from . import contexts, environment diff --git a/uno/lib/python/setuptools/tests/integration/helpers.py b/uno/lib/python/setuptools/tests/integration/helpers.py index 615c43b2..77b196e0 100644 --- a/uno/lib/python/setuptools/tests/integration/helpers.py +++ b/uno/lib/python/setuptools/tests/integration/helpers.py @@ -8,8 +8,8 @@ import os import subprocess import tarfile -from zipfile import ZipFile from pathlib import Path +from zipfile import ZipFile def run(cmd, env=None): diff --git a/uno/lib/python/setuptools/tests/integration/test_pip_install_sdist.py b/uno/lib/python/setuptools/tests/integration/test_pip_install_sdist.py index ee70b1c2..2d59337a 100644 --- a/uno/lib/python/setuptools/tests/integration/test_pip_install_sdist.py +++ b/uno/lib/python/setuptools/tests/integration/test_pip_install_sdist.py @@ -137,7 +137,7 @@ def test_install_sdist(package, version, tmp_path, venv_python, setuptools_wheel # Use a virtualenv to simulate PEP 517 isolation # but install fresh setuptools wheel to ensure the version under development env = EXTRA_ENV_VARS.get(package, {}) - run([*venv_pip, "install", "wheel", "-I", setuptools_wheel]) + run([*venv_pip, "install", "--force-reinstall", setuptools_wheel]) run([*venv_pip, "install", *INSTALL_OPTIONS, sdist], env) # Execute a simple script to make sure the package was installed correctly diff --git a/uno/lib/python/setuptools/tests/server.py b/uno/lib/python/setuptools/tests/server.py index 8cb735f1..15bbc3b1 100644 --- a/uno/lib/python/setuptools/tests/server.py +++ b/uno/lib/python/setuptools/tests/server.py @@ -1,9 +1,9 @@ """Basic http server for tests to simulate PyPI or custom indexes""" +import http.server import os -import time import threading -import http.server +import time import urllib.parse import urllib.request diff --git a/uno/lib/python/setuptools/tests/test_archive_util.py b/uno/lib/python/setuptools/tests/test_archive_util.py index 06d7f05a..e3efc628 100644 --- a/uno/lib/python/setuptools/tests/test_archive_util.py +++ b/uno/lib/python/setuptools/tests/test_archive_util.py @@ -1,5 +1,5 @@ -import tarfile import io +import tarfile import pytest diff --git a/uno/lib/python/setuptools/tests/test_bdist_deprecations.py b/uno/lib/python/setuptools/tests/test_bdist_deprecations.py index f2b99b05..d9d67b06 100644 --- a/uno/lib/python/setuptools/tests/test_bdist_deprecations.py +++ b/uno/lib/python/setuptools/tests/test_bdist_deprecations.py @@ -5,8 +5,8 @@ import pytest -from setuptools.dist import Distribution from setuptools import SetuptoolsDeprecationWarning +from setuptools.dist import Distribution @pytest.mark.skipif(sys.platform == 'win32', reason='non-Windows only') diff --git a/uno/lib/python/setuptools/tests/test_bdist_wheel.py b/uno/lib/python/setuptools/tests/test_bdist_wheel.py index 3ca277ba..a1e3d9a7 100644 --- a/uno/lib/python/setuptools/tests/test_bdist_wheel.py +++ b/uno/lib/python/setuptools/tests/test_bdist_wheel.py @@ -16,9 +16,9 @@ import jaraco.path import pytest +from packaging import tags import setuptools -from distutils.core import run_setup from setuptools.command.bdist_wheel import ( bdist_wheel, get_abi_tag, @@ -26,7 +26,8 @@ remove_readonly_exc, ) from setuptools.dist import Distribution -from packaging import tags + +from distutils.core import run_setup DEFAULT_FILES = { "dummy_dist-1.0.dist-info/top_level.txt", diff --git a/uno/lib/python/setuptools/tests/test_build.py b/uno/lib/python/setuptools/tests/test_build.py index 141522ef..f0f1d9dc 100644 --- a/uno/lib/python/setuptools/tests/test_build.py +++ b/uno/lib/python/setuptools/tests/test_build.py @@ -1,6 +1,6 @@ from setuptools import Command -from setuptools.dist import Distribution from setuptools.command.build import build +from setuptools.dist import Distribution def test_distribution_gives_setuptools_build_obj(tmpdir_cwd): diff --git a/uno/lib/python/setuptools/tests/test_build_clib.py b/uno/lib/python/setuptools/tests/test_build_clib.py index 2c5b956c..b5315df4 100644 --- a/uno/lib/python/setuptools/tests/test_build_clib.py +++ b/uno/lib/python/setuptools/tests/test_build_clib.py @@ -1,12 +1,13 @@ +import random from unittest import mock import pytest -import random -from distutils.errors import DistutilsSetupError from setuptools.command.build_clib import build_clib from setuptools.dist import Distribution +from distutils.errors import DistutilsSetupError + class TestBuildCLib: @mock.patch('setuptools.command.build_clib.newer_pairwise_group') diff --git a/uno/lib/python/setuptools/tests/test_build_ext.py b/uno/lib/python/setuptools/tests/test_build_ext.py index 0482fb5d..814fbd86 100644 --- a/uno/lib/python/setuptools/tests/test_build_ext.py +++ b/uno/lib/python/setuptools/tests/test_build_ext.py @@ -1,21 +1,20 @@ import os import sys -import distutils.command.build_ext as orig -from distutils.sysconfig import get_config_var from importlib.util import cache_from_source as _compiled_file_name +import pytest from jaraco import path from setuptools.command.build_ext import build_ext, get_abi3_suffix from setuptools.dist import Distribution -from setuptools.extension import Extension from setuptools.errors import CompileError +from setuptools.extension import Extension from . import environment from .textwrap import DALS -import pytest - +import distutils.command.build_ext as orig +from distutils.sysconfig import get_config_var IS_PYPY = '__pypy__' in sys.builtin_module_names @@ -189,6 +188,7 @@ def get_build_ext_cmd(self, optional: bool, **opts): dist = Distribution(dict(ext_modules=[extension])) dist.script_name = 'setup.py' cmd = build_ext(dist) + # TODO: False-positive [attr-defined], raise upstream vars(cmd).update(build_lib=".build/lib", build_temp=".build/tmp", **opts) cmd.ensure_finalized() return cmd diff --git a/uno/lib/python/setuptools/tests/test_build_meta.py b/uno/lib/python/setuptools/tests/test_build_meta.py index ecb1dcfd..c34f7116 100644 --- a/uno/lib/python/setuptools/tests/test_build_meta.py +++ b/uno/lib/python/setuptools/tests/test_build_meta.py @@ -1,17 +1,18 @@ +import contextlib +import importlib import os -import sys +import re import shutil import signal +import sys import tarfile -import importlib -import contextlib from concurrent import futures -import re -from zipfile import ZipFile from pathlib import Path +from zipfile import ZipFile import pytest from jaraco import path +from packaging.requirements import Requirement from .textwrap import DALS @@ -436,18 +437,16 @@ def test_build_with_pyproject_config(self, tmpdir, setup_script): } assert license == "---- placeholder MIT license ----" - metadata = metadata.replace("(", "").replace(")", "") - # ^-- compatibility hack for pypa/wheel#552 - for line in ( "Summary: This is a Python package", "License: MIT", "Classifier: Intended Audience :: Developers", "Requires-Dist: appdirs", - "Requires-Dist: tomli >=1 ; extra == 'all'", - "Requires-Dist: importlib ; python_version == \"2.6\" and extra == 'all'", + "Requires-Dist: " + str(Requirement('tomli>=1 ; extra == "all"')), + "Requires-Dist: " + + str(Requirement('importlib; python_version=="2.6" and extra =="all"')), ): - assert line in metadata + assert line in metadata, (line, metadata) assert metadata.strip().endswith("This is a ``README``") assert epoints.strip() == "[console_scripts]\nfoo = foo.cli:main" diff --git a/uno/lib/python/setuptools/tests/test_build_py.py b/uno/lib/python/setuptools/tests/test_build_py.py index 6900fdef..b8cd77dc 100644 --- a/uno/lib/python/setuptools/tests/test_build_py.py +++ b/uno/lib/python/setuptools/tests/test_build_py.py @@ -1,12 +1,12 @@ import os -import stat import shutil +import stat import warnings from pathlib import Path from unittest.mock import Mock -import pytest import jaraco.path +import pytest from setuptools import SetuptoolsDeprecationWarning from setuptools.dist import Distribution diff --git a/uno/lib/python/setuptools/tests/test_config_discovery.py b/uno/lib/python/setuptools/tests/test_config_discovery.py index ff9e672b..af172953 100644 --- a/uno/lib/python/setuptools/tests/test_config_discovery.py +++ b/uno/lib/python/setuptools/tests/test_config_discovery.py @@ -3,22 +3,22 @@ from configparser import ConfigParser from itertools import product +import jaraco.path +import pytest +from path import Path + +import setuptools # noqa: F401 # force distutils.core to be patched from setuptools.command.sdist import sdist -from setuptools.dist import Distribution from setuptools.discovery import find_package_path, find_parent_package +from setuptools.dist import Distribution from setuptools.errors import PackageDiscoveryError -import setuptools # noqa -- force distutils.core to be patched -import distutils.core - -import pytest -import jaraco.path -from path import Path - from .contexts import quiet from .integration.helpers import get_sdist_members, get_wheel_members, run from .textwrap import DALS +import distutils.core + class TestFindParentPackage: def test_single_package(self, tmp_path): diff --git a/uno/lib/python/setuptools/tests/test_core_metadata.py b/uno/lib/python/setuptools/tests/test_core_metadata.py index eaabf20a..34828ac7 100644 --- a/uno/lib/python/setuptools/tests/test_core_metadata.py +++ b/uno/lib/python/setuptools/tests/test_core_metadata.py @@ -1,17 +1,15 @@ import functools -import io import importlib +import io from email import message_from_string import pytest - from packaging.metadata import Metadata -from setuptools import sic, _reqs -from setuptools.dist import Distribution +from setuptools import _reqs, sic from setuptools._core_metadata import rfc822_escape, rfc822_unescape from setuptools.command.egg_info import egg_info, write_requirements - +from setuptools.dist import Distribution EXAMPLE_BASE_INFO = dict( name="package", @@ -190,7 +188,7 @@ def test_read_metadata(name, attrs): ('requires', dist_class.get_requires), ('classifiers', dist_class.get_classifiers), ('project_urls', lambda s: getattr(s, 'project_urls', {})), - ('provides_extras', lambda s: getattr(s, 'provides_extras', set())), + ('provides_extras', lambda s: getattr(s, 'provides_extras', {})), ] for attr, getter in tested_attrs: diff --git a/uno/lib/python/setuptools/tests/test_develop.py b/uno/lib/python/setuptools/tests/test_develop.py index 6f17beb7..929fa9c2 100644 --- a/uno/lib/python/setuptools/tests/test_develop.py +++ b/uno/lib/python/setuptools/tests/test_develop.py @@ -1,18 +1,18 @@ """develop tests""" import os -import sys -import subprocess import pathlib import platform +import subprocess +import sys import pytest +from setuptools._path import paths_on_pythonpath from setuptools.command.develop import develop from setuptools.dist import Distribution -from setuptools._path import paths_on_pythonpath -from . import contexts -from . import namespaces + +from . import contexts, namespaces SETUP_PY = """\ from setuptools import setup diff --git a/uno/lib/python/setuptools/tests/test_dist.py b/uno/lib/python/setuptools/tests/test_dist.py index 99cd5825..597785b5 100644 --- a/uno/lib/python/setuptools/tests/test_dist.py +++ b/uno/lib/python/setuptools/tests/test_dist.py @@ -1,20 +1,19 @@ import collections -import re import os -import urllib.request +import re import urllib.parse -from distutils.errors import DistutilsSetupError -from setuptools.dist import ( - check_package_data, - check_specifier, -) +import urllib.request + +import pytest + from setuptools import Distribution +from setuptools.dist import check_package_data, check_specifier -from .textwrap import DALS from .test_easy_install import make_nspkg_sdist from .test_find_packages import ensure_files +from .textwrap import DALS -import pytest +from distutils.errors import DistutilsSetupError def test_dist_fetch_build_egg(tmpdir): @@ -78,12 +77,12 @@ def test_provides_extras_deterministic_order(): extras['b'] = ['bar'] attrs = dict(extras_require=extras) dist = Distribution(attrs) - assert dist.metadata.provides_extras == ['a', 'b'] + assert list(dist.metadata.provides_extras) == ['a', 'b'] attrs['extras_require'] = collections.OrderedDict( reversed(list(attrs['extras_require'].items())) ) dist = Distribution(attrs) - assert dist.metadata.provides_extras == ['b', 'a'] + assert list(dist.metadata.provides_extras) == ['b', 'a'] CHECK_PACKAGE_DATA_TESTS = ( diff --git a/uno/lib/python/setuptools/tests/test_dist_info.py b/uno/lib/python/setuptools/tests/test_dist_info.py index 44be6c32..6e109c9d 100644 --- a/uno/lib/python/setuptools/tests/test_dist_info.py +++ b/uno/lib/python/setuptools/tests/test_dist_info.py @@ -11,8 +11,8 @@ import pkg_resources from setuptools.archive_util import unpack_archive -from .textwrap import DALS +from .textwrap import DALS read = partial(pathlib.Path.read_text, encoding="utf-8") diff --git a/uno/lib/python/setuptools/tests/test_distutils_adoption.py b/uno/lib/python/setuptools/tests/test_distutils_adoption.py index 74883d21..0b020ba9 100644 --- a/uno/lib/python/setuptools/tests/test_distutils_adoption.py +++ b/uno/lib/python/setuptools/tests/test_distutils_adoption.py @@ -1,11 +1,10 @@ import os -import sys import platform +import sys import textwrap import pytest - IS_PYPY = '__pypy__' in sys.builtin_module_names _TEXT_KWARGS = {"text": True, "encoding": "utf-8"} # For subprocess.run diff --git a/uno/lib/python/setuptools/tests/test_easy_install.py b/uno/lib/python/setuptools/tests/test_easy_install.py index 7346a079..ca6af966 100644 --- a/uno/lib/python/setuptools/tests/test_easy_install.py +++ b/uno/lib/python/setuptools/tests/test_easy_install.py @@ -1,42 +1,42 @@ """Easy install Tests""" -import sys -import os -import tempfile -import site import contextlib -import tarfile -import logging -import itertools -import distutils.errors import io -from typing import NamedTuple -import zipfile -import time +import itertools +import logging +import os +import pathlib import re +import site import subprocess -import pathlib +import sys +import tarfile +import tempfile +import time import warnings +import zipfile from pathlib import Path +from typing import NamedTuple from unittest import mock import pytest from jaraco import path -from setuptools import sandbox -from setuptools.sandbox import run_setup +import pkg_resources import setuptools.command.easy_install as ei +from pkg_resources import Distribution as PRDistribution, normalize_path, working_set +from setuptools import sandbox from setuptools.command.easy_install import PthDistributions from setuptools.dist import Distribution -from pkg_resources import normalize_path, working_set -from pkg_resources import Distribution as PRDistribution -from setuptools.tests.server import MockServer, path_to_url +from setuptools.sandbox import run_setup from setuptools.tests import fail_on_ascii -import pkg_resources +from setuptools.tests.server import MockServer, path_to_url from . import contexts from .textwrap import DALS +import distutils.errors + @pytest.fixture(autouse=True) def pip_disable_index(monkeypatch): diff --git a/uno/lib/python/setuptools/tests/test_editable_install.py b/uno/lib/python/setuptools/tests/test_editable_install.py index 24c10a50..287367ac 100644 --- a/uno/lib/python/setuptools/tests/test_editable_install.py +++ b/uno/lib/python/setuptools/tests/test_editable_install.py @@ -1,8 +1,8 @@ import os +import platform import stat -import sys import subprocess -import platform +import sys from copy import deepcopy from importlib import import_module from importlib.machinery import EXTENSION_SUFFIXES @@ -11,31 +11,31 @@ from unittest.mock import Mock from uuid import uuid4 -from distutils.core import run_setup - import jaraco.envs import jaraco.path import pytest from path import Path as _Path -from . import contexts, namespaces - from setuptools._importlib import resources as importlib_resources from setuptools.command.editable_wheel import ( _DebuggingTips, - _LinkTree, - _TopLevelFinder, _encode_pth, - _find_virtual_namespaces, _find_namespaces, _find_package_roots, + _find_virtual_namespaces, _finder_template, + _LinkTree, + _TopLevelFinder, editable_wheel, ) from setuptools.dist import Distribution from setuptools.extension import Extension from setuptools.warnings import SetuptoolsDeprecationWarning +from . import contexts, namespaces + +from distutils.core import run_setup + @pytest.fixture(params=["strict", "lenient"]) def editable_opts(request): diff --git a/uno/lib/python/setuptools/tests/test_egg_info.py b/uno/lib/python/setuptools/tests/test_egg_info.py index 856dd127..6e8d0c68 100644 --- a/uno/lib/python/setuptools/tests/test_egg_info.py +++ b/uno/lib/python/setuptools/tests/test_egg_info.py @@ -1,11 +1,11 @@ from __future__ import annotations -import sys import ast -import os import glob +import os import re import stat +import sys import time from pathlib import Path from unittest import mock @@ -14,16 +14,11 @@ from jaraco import path from setuptools import errors -from setuptools.command.egg_info import ( - egg_info, - manifest_maker, - write_entries, -) +from setuptools.command.egg_info import egg_info, manifest_maker, write_entries from setuptools.dist import Distribution -from . import environment +from . import contexts, environment from .textwrap import DALS -from . import contexts class Environment(str): diff --git a/uno/lib/python/setuptools/tests/test_extern.py b/uno/lib/python/setuptools/tests/test_extern.py index da01b25b..d7eb3c62 100644 --- a/uno/lib/python/setuptools/tests/test_extern.py +++ b/uno/lib/python/setuptools/tests/test_extern.py @@ -1,19 +1,14 @@ import importlib import pickle +import packaging + from setuptools import Distribution -import ordered_set def test_reimport_extern(): - ordered_set2 = importlib.import_module(ordered_set.__name__) - assert ordered_set is ordered_set2 - - -def test_orderedset_pickle_roundtrip(): - o1 = ordered_set.OrderedSet([1, 2, 5]) - o2 = pickle.loads(pickle.dumps(o1)) - assert o1 == o2 + packaging2 = importlib.import_module(packaging.__name__) + assert packaging is packaging2 def test_distribution_picklable(): diff --git a/uno/lib/python/setuptools/tests/test_find_packages.py b/uno/lib/python/setuptools/tests/test_find_packages.py index 0f4e2bef..9fd9f8f6 100644 --- a/uno/lib/python/setuptools/tests/test_find_packages.py +++ b/uno/lib/python/setuptools/tests/test_find_packages.py @@ -6,8 +6,7 @@ import pytest -from setuptools import find_packages -from setuptools import find_namespace_packages +from setuptools import find_namespace_packages, find_packages from setuptools.discovery import FlatLayoutPackageFinder from .compat.py39 import os_helper diff --git a/uno/lib/python/setuptools/tests/test_find_py_modules.py b/uno/lib/python/setuptools/tests/test_find_py_modules.py index 2459c98f..8034b544 100644 --- a/uno/lib/python/setuptools/tests/test_find_py_modules.py +++ b/uno/lib/python/setuptools/tests/test_find_py_modules.py @@ -6,8 +6,8 @@ from setuptools.discovery import FlatLayoutModuleFinder, ModuleFinder -from .test_find_packages import ensure_files from .compat.py39 import os_helper +from .test_find_packages import ensure_files class TestModuleFinder: diff --git a/uno/lib/python/setuptools/tests/test_install_scripts.py b/uno/lib/python/setuptools/tests/test_install_scripts.py index 595b7ade..2ae54965 100644 --- a/uno/lib/python/setuptools/tests/test_install_scripts.py +++ b/uno/lib/python/setuptools/tests/test_install_scripts.py @@ -6,6 +6,7 @@ from setuptools.command.install_scripts import install_scripts from setuptools.dist import Distribution + from . import contexts diff --git a/uno/lib/python/setuptools/tests/test_integration.py b/uno/lib/python/setuptools/tests/test_integration.py index 78f459d0..b0e7d67b 100644 --- a/uno/lib/python/setuptools/tests/test_integration.py +++ b/uno/lib/python/setuptools/tests/test_integration.py @@ -10,11 +10,10 @@ import pytest -from setuptools.command.easy_install import easy_install from setuptools.command import easy_install as easy_install_pkg +from setuptools.command.easy_install import easy_install from setuptools.dist import Distribution - pytestmark = pytest.mark.skipif( 'platform.python_implementation() == "PyPy" and platform.system() == "Windows"', reason="pypa/setuptools#2496", diff --git a/uno/lib/python/setuptools/tests/test_logging.py b/uno/lib/python/setuptools/tests/test_logging.py index cf89b3bd..e01df727 100644 --- a/uno/lib/python/setuptools/tests/test_logging.py +++ b/uno/lib/python/setuptools/tests/test_logging.py @@ -5,7 +5,6 @@ import pytest - IS_PYPY = '__pypy__' in sys.builtin_module_names @@ -25,6 +24,7 @@ def test_verbosity_level(tmp_path, monkeypatch, flag, expected_level): """Make sure the correct verbosity level is set (issue #3038)""" import setuptools # noqa: F401 # import setuptools to monkeypatch distutils + import distutils # <- load distutils after all the patches take place logger = logging.Logger(__name__) @@ -61,7 +61,9 @@ def test_patching_does_not_cause_problems(): # Ensure `dist.log` is only patched if necessary import _distutils_hack + import setuptools.logging + from distutils import dist setuptools.logging.configure() diff --git a/uno/lib/python/setuptools/tests/test_manifest.py b/uno/lib/python/setuptools/tests/test_manifest.py index f3eba733..ae5572b8 100644 --- a/uno/lib/python/setuptools/tests/test_manifest.py +++ b/uno/lib/python/setuptools/tests/test_manifest.py @@ -3,22 +3,22 @@ from __future__ import annotations import contextlib +import io +import itertools +import logging import os import shutil import sys import tempfile -import itertools -import io -import logging -from distutils import log -from distutils.errors import DistutilsTemplateError + +import pytest from setuptools.command.egg_info import FileList, egg_info, translate_pattern from setuptools.dist import Distribution from setuptools.tests.textwrap import DALS -import pytest - +from distutils import log +from distutils.errors import DistutilsTemplateError IS_PYPY = '__pypy__' in sys.builtin_module_names diff --git a/uno/lib/python/setuptools/tests/test_msvc14.py b/uno/lib/python/setuptools/tests/test_msvc14.py index 4b834453..57d3cc38 100644 --- a/uno/lib/python/setuptools/tests/test_msvc14.py +++ b/uno/lib/python/setuptools/tests/test_msvc14.py @@ -3,10 +3,12 @@ """ import os -from distutils.errors import DistutilsPlatformError -import pytest import sys +import pytest + +from distutils.errors import DistutilsPlatformError + @pytest.mark.skipif(sys.platform != "win32", reason="These tests are only for win32") class TestMSVC14: diff --git a/uno/lib/python/setuptools/tests/test_namespaces.py b/uno/lib/python/setuptools/tests/test_namespaces.py index 56689301..a0f4120b 100644 --- a/uno/lib/python/setuptools/tests/test_namespaces.py +++ b/uno/lib/python/setuptools/tests/test_namespaces.py @@ -1,5 +1,5 @@ -import sys import subprocess +import sys from setuptools._path import paths_on_pythonpath diff --git a/uno/lib/python/setuptools/tests/test_packageindex.py b/uno/lib/python/setuptools/tests/test_packageindex.py index f5f37e05..e1f84586 100644 --- a/uno/lib/python/setuptools/tests/test_packageindex.py +++ b/uno/lib/python/setuptools/tests/test_packageindex.py @@ -1,13 +1,14 @@ -import distutils.errors -import urllib.request -import urllib.error import http.client +import urllib.error +import urllib.request from inspect import cleandoc import pytest import setuptools.package_index +import distutils.errors + class TestPackageIndex: def test_regex(self): diff --git a/uno/lib/python/setuptools/tests/test_register.py b/uno/lib/python/setuptools/tests/test_register.py index ed85e9bb..0c7d109d 100644 --- a/uno/lib/python/setuptools/tests/test_register.py +++ b/uno/lib/python/setuptools/tests/test_register.py @@ -1,11 +1,11 @@ -from setuptools.command.register import register -from setuptools.dist import Distribution -from setuptools.errors import RemovedCommandError - from unittest import mock import pytest +from setuptools.command.register import register +from setuptools.dist import Distribution +from setuptools.errors import RemovedCommandError + class TestRegister: def test_register_exception(self): diff --git a/uno/lib/python/setuptools/tests/test_sdist.py b/uno/lib/python/setuptools/tests/test_sdist.py index 096cdc39..2df202fd 100644 --- a/uno/lib/python/setuptools/tests/test_sdist.py +++ b/uno/lib/python/setuptools/tests/test_sdist.py @@ -1,32 +1,31 @@ """sdist tests""" +import contextlib +import io +import logging import os import sys +import tarfile import tempfile import unicodedata -import contextlib -import io -import tarfile -import logging -import distutils from inspect import cleandoc from unittest import mock +import jaraco.path import pytest -from distutils.core import run_setup -from setuptools import Command +from setuptools import Command, SetuptoolsDeprecationWarning from setuptools._importlib import metadata -from setuptools import SetuptoolsDeprecationWarning -from setuptools.command.sdist import sdist from setuptools.command.egg_info import manifest_maker +from setuptools.command.sdist import sdist from setuptools.dist import Distribution from setuptools.extension import Extension from setuptools.tests import fail_on_ascii -from .text import Filenames -import jaraco.path +from .text import Filenames +import distutils +from distutils.core import run_setup SETUP_ATTRS = { 'name': 'sdist_test', diff --git a/uno/lib/python/setuptools/tests/test_setuptools.py b/uno/lib/python/setuptools/tests/test_setuptools.py index 9865ee84..6af1d98c 100644 --- a/uno/lib/python/setuptools/tests/test_setuptools.py +++ b/uno/lib/python/setuptools/tests/test_setuptools.py @@ -1,22 +1,22 @@ """Tests for the 'setuptools' package""" +import os import re import sys -import os -import distutils.core -import distutils.cmd -from distutils.errors import DistutilsSetupError -from distutils.core import Extension from zipfile import ZipFile import pytest +from packaging.version import Version import setuptools -import setuptools.dist import setuptools.depends as dep +import setuptools.dist from setuptools.depends import Require -from packaging.version import Version +import distutils.cmd +import distutils.core +from distutils.core import Extension +from distutils.errors import DistutilsSetupError @pytest.fixture(autouse=True) diff --git a/uno/lib/python/setuptools/tests/test_upload.py b/uno/lib/python/setuptools/tests/test_upload.py index 4ed59bc2..cbcd455c 100644 --- a/uno/lib/python/setuptools/tests/test_upload.py +++ b/uno/lib/python/setuptools/tests/test_upload.py @@ -1,11 +1,11 @@ -from setuptools.command.upload import upload -from setuptools.dist import Distribution -from setuptools.errors import RemovedCommandError - from unittest import mock import pytest +from setuptools.command.upload import upload +from setuptools.dist import Distribution +from setuptools.errors import RemovedCommandError + class TestUpload: def test_upload_exception(self): diff --git a/uno/lib/python/setuptools/tests/test_virtualenv.py b/uno/lib/python/setuptools/tests/test_virtualenv.py index 4554581e..cdc10f50 100644 --- a/uno/lib/python/setuptools/tests/test_virtualenv.py +++ b/uno/lib/python/setuptools/tests/test_virtualenv.py @@ -1,9 +1,8 @@ import os -import sys import subprocess -from urllib.request import urlopen +import sys from urllib.error import URLError - +from urllib.request import urlopen import pytest diff --git a/uno/lib/python/setuptools/tests/test_warnings.py b/uno/lib/python/setuptools/tests/test_warnings.py index ac6d0779..41193d4f 100644 --- a/uno/lib/python/setuptools/tests/test_warnings.py +++ b/uno/lib/python/setuptools/tests/test_warnings.py @@ -4,7 +4,6 @@ from setuptools.warnings import SetuptoolsDeprecationWarning, SetuptoolsWarning - _EXAMPLES = { "default": dict( args=("Hello {x}", "\n\t{target} {v:.1f}"), diff --git a/uno/lib/python/setuptools/tests/test_wheel.py b/uno/lib/python/setuptools/tests/test_wheel.py index cc5d54b6..ee46f664 100644 --- a/uno/lib/python/setuptools/tests/test_wheel.py +++ b/uno/lib/python/setuptools/tests/test_wheel.py @@ -2,31 +2,31 @@ from __future__ import annotations -from distutils.sysconfig import get_config_var -from distutils.util import get_platform import contextlib -import pathlib -import stat import glob import inspect import os +import pathlib import shutil +import stat import subprocess import sys -from typing import Any import zipfile +from typing import Any import pytest from jaraco import path - -from pkg_resources import Distribution, PathMetadata, PY_MAJOR -from packaging.utils import canonicalize_name from packaging.tags import parse_tag +from packaging.utils import canonicalize_name + +from pkg_resources import PY_MAJOR, Distribution, PathMetadata from setuptools.wheel import Wheel from .contexts import tempdir from .textwrap import DALS +from distutils.sysconfig import get_config_var +from distutils.util import get_platform WHEEL_INFO_TESTS = ( ('invalid.whl', ValueError), diff --git a/uno/lib/python/setuptools/tests/test_windows_wrappers.py b/uno/lib/python/setuptools/tests/test_windows_wrappers.py index b2726893..4a112baf 100644 --- a/uno/lib/python/setuptools/tests/test_windows_wrappers.py +++ b/uno/lib/python/setuptools/tests/test_windows_wrappers.py @@ -13,15 +13,15 @@ """ import pathlib -import sys import platform -import textwrap import subprocess +import sys +import textwrap import pytest -from setuptools.command.easy_install import nt_quote_arg import pkg_resources +from setuptools.command.easy_install import nt_quote_arg pytestmark = pytest.mark.skipif(sys.platform != 'win32', reason="Windows only") diff --git a/uno/lib/python/setuptools/unicode_utils.py b/uno/lib/python/setuptools/unicode_utils.py index 696b34c4..862d79e8 100644 --- a/uno/lib/python/setuptools/unicode_utils.py +++ b/uno/lib/python/setuptools/unicode_utils.py @@ -1,5 +1,5 @@ -import unicodedata import sys +import unicodedata from configparser import ConfigParser from .compat import py39 diff --git a/uno/lib/python/setuptools/wheel.py b/uno/lib/python/setuptools/wheel.py index a05cd98d..69a73df2 100644 --- a/uno/lib/python/setuptools/wheel.py +++ b/uno/lib/python/setuptools/wheel.py @@ -1,26 +1,25 @@ """Wheels support.""" +import contextlib import email -import itertools import functools +import itertools import os import posixpath import re import zipfile -import contextlib -from packaging.version import Version as parse_version from packaging.tags import sys_tags from packaging.utils import canonicalize_name - -from distutils.util import get_platform +from packaging.version import Version as parse_version import setuptools -from setuptools.command.egg_info import write_requirements, _egg_basename from setuptools.archive_util import _unpack_zipfile_obj +from setuptools.command.egg_info import _egg_basename, write_requirements from .unicode_utils import _read_utf8_with_fallback +from distutils.util import get_platform WHEEL_NAME = re.compile( r"""^(?P.+?)-(?P\d.*?) diff --git a/uno/lib/python/setuptools/windows_support.py b/uno/lib/python/setuptools/windows_support.py index 8299ac1c..7a2b53a2 100644 --- a/uno/lib/python/setuptools/windows_support.py +++ b/uno/lib/python/setuptools/windows_support.py @@ -8,7 +8,7 @@ def windows_only(func): @windows_only -def hide_file(path): +def hide_file(path: str) -> None: """ Set the hidden attribute on a file or directory. @@ -17,8 +17,8 @@ def hide_file(path): `path` must be text. """ import ctypes + import ctypes.wintypes - __import__('ctypes.wintypes') SetFileAttributes = ctypes.windll.kernel32.SetFileAttributesW SetFileAttributes.argtypes = ctypes.wintypes.LPWSTR, ctypes.wintypes.DWORD SetFileAttributes.restype = ctypes.wintypes.BOOL diff --git a/uno/lib/uno/embedded/__init__.py b/uno/lib/uno/embedded/__init__.py index 8ce27600..7392676a 100644 --- a/uno/lib/uno/embedded/__init__.py +++ b/uno/lib/uno/embedded/__init__.py @@ -30,20 +30,8 @@ from . import sdbc from . import sdbcx -from .unotool import createService from .unotool import getConfiguration -from .unotool import getDialog -from .unotool import getDocument -from .unotool import getFileSequence -from .unotool import getPropertyValueSet -from .unotool import getResourceLocation -from .unotool import getSimpleFile -from .unotool import getStringResource -from .configuration import g_extension from .configuration import g_identifier from .options import OptionsManager - -from .logger import getLogger - diff --git a/uno/lib/uno/embedded/documenthandler.py b/uno/lib/uno/embedded/documenthandler.py index 02f3d592..586fe6de 100644 --- a/uno/lib/uno/embedded/documenthandler.py +++ b/uno/lib/uno/embedded/documenthandler.py @@ -55,6 +55,7 @@ from .configuration import g_create from .configuration import g_exist from .configuration import g_path +from .configuration import g_shutdown import traceback @@ -62,7 +63,7 @@ class DocumentHandler(unohelper.Base, XCloseListener, XStorageChangeListener): - def __init__(self, ctx, lock, logger, url): + def __init__(self, ctx, lock, logger, driver, url): self._ctx = ctx self._directory = 'database' self._prefix = '.' @@ -72,6 +73,7 @@ def __init__(self, ctx, lock, logger, url): self._logger = logger self._created = False self._path, self._folder = self._getDataBaseInfo(url) + self._driver = driver self._url = url @property @@ -112,9 +114,9 @@ def notifyStorageChange(self, document, storage): # XEventListener def disposing(self, event): - url = self._url - self._logger.logprb(INFO, 'DocumentHandler', 'disposing()', 221, url) document = event.Source + url = document.getLocation() + self._logger.logprb(INFO, 'DocumentHandler', 'disposing()', 221, url) document.removeCloseListener(self) document.removeStorageChangeListener(self) self._url = None @@ -178,13 +180,18 @@ def _getDocumentName(self, title): return name if sep else extension def _getConnectionUrl(self, exist): - url = self._getDataBaseUrl() + self._sep + g_catalog - path = uno.fileUrlToSystemPath(url) if g_path else url + path = self._getConnectionPath() url = g_protocol + path + g_options return url + g_exist if exist else url + g_create + def _getConnectionPath(self): + url = self._getDataBaseUrl() + self._sep + g_catalog + return uno.fileUrlToSystemPath(url) if g_path else url + def _closeDataBase(self, document, target, cls, method, resource): try: + if g_shutdown: + self._shutdownDataBase() service = 'com.sun.star.embed.FileSystemStorageFactory' args = (self._getDataBaseUrl(), SEEKABLEREAD) source = createService(self._ctx, service).createInstanceWithArguments(args) @@ -196,6 +203,15 @@ def _closeDataBase(self, document, target, cls, method, resource): self._logger.logprb(SEVERE, cls, method, resource + 1, self._url, traceback.format_exc()) return False + def _shutdownDataBase(self): + # XXX: Some databases need to be shutdown if we want all files to be closed (ie: Derby) + path = self._getConnectionPath() + url = g_protocol + path + g_shutdown + try: + self._driver.connect(url, ()) + except Exception as e: + pass + # DocumentHandler private setter methods def _copyStorage(self, source, target): count = 0 diff --git a/uno/lib/uno/embedded/driver.py b/uno/lib/uno/embedded/driver.py index 05e5016d..4b7420f0 100644 --- a/uno/lib/uno/embedded/driver.py +++ b/uno/lib/uno/embedded/driver.py @@ -92,7 +92,7 @@ def connect(self, url, infos): if storage is None or location is None: self._logException(112, url, ' ') raise self._getException(1001, None, 111, 112, url, '\n') - handler = self._getDocumentHandler(location) + handler = self._getDocumentHandler(driver, location) # XXX: Getting path from handler unpacks the database files path = handler.getConnectionUrl(storage) self._logger.logprb(INFO, 'Driver', 'connect()', 113, location) @@ -202,11 +202,11 @@ def _getHandler(self, location): document = handler return document - def _getDocumentHandler(self, location): + def _getDocumentHandler(self, driver, location): with self._lock: handler = self._getHandler(location) if handler is None: - handler = DocumentHandler(self._ctx, self._lock, self._logger, location) + handler = DocumentHandler(self._ctx, self._lock, self._logger, driver, location) return handler def _setDocumentHandler(self, document, handler): diff --git a/uno/lib/uno/logger/dialog/logmanager.py b/uno/lib/uno/logger/dialog/logmanager.py index 8fc4410a..049f711f 100644 --- a/uno/lib/uno/logger/dialog/logmanager.py +++ b/uno/lib/uno/logger/dialog/logmanager.py @@ -55,12 +55,12 @@ class LogManager(unohelper.Base): def __init__(self, ctx, parent, requirements, filter, *defaults): self._ctx = ctx - self._model = LogModel(ctx, PoolListener(self), defaults) - self._view = LogWindow(ctx, WindowHandler(self), parent) self._requirements = requirements self._filter = filter self._dialog = None self._disabled = False + self._model = LogModel(ctx, PoolListener(self), defaults) + self._view = LogWindow(ctx, WindowHandler(self), parent) self._view.initLogger(self._model.getLoggerNames(filter)) # TODO: One shot disabler handler