diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2024-07-10 11:16:37 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2024-07-10 11:28:06 +0300 |
commit | 02dce8fb96150aa1b41f0ead67e108999556a4a8 (patch) | |
tree | ac1187a3399be9acbb68cf59e0e691b643cfde3c | |
parent | 7a7d160e4e2aff543ecbe74a8b810adab7688808 (diff) | |
download | ydb-02dce8fb96150aa1b41f0ead67e108999556a4a8.tar.gz |
Intermediate changes
5 files changed, 199 insertions, 54 deletions
diff --git a/contrib/python/setuptools/py3/.dist-info/METADATA b/contrib/python/setuptools/py3/.dist-info/METADATA index 975dc27833..da4720019f 100644 --- a/contrib/python/setuptools/py3/.dist-info/METADATA +++ b/contrib/python/setuptools/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: setuptools -Version: 70.1.0 +Version: 70.1.1 Summary: Easily download, build, install, upgrade, and uninstall Python packages Author-email: Python Packaging Authority <distutils-sig@python.org> Project-URL: Homepage, https://github.com/pypa/setuptools diff --git a/contrib/python/setuptools/py3/pkg_resources/__init__.py b/contrib/python/setuptools/py3/pkg_resources/__init__.py index bb8588f7b7..8e01d93476 100644 --- a/contrib/python/setuptools/py3/pkg_resources/__init__.py +++ b/contrib/python/setuptools/py3/pkg_resources/__init__.py @@ -34,6 +34,7 @@ import re import types from typing import ( Any, + Literal, Dict, Iterator, Mapping, @@ -98,8 +99,8 @@ from pkg_resources.extern.packaging import version as _packaging_version from pkg_resources.extern.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 StrPath, StrOrBytesPath, BytesPath warnings.warn( "pkg_resources is deprecated as an API. " @@ -110,15 +111,20 @@ warnings.warn( _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 # Any object works, but let's indicate we expect something like a module (optionally has __loader__ or __file__) _ModuleLike = Union[object, types.ModuleType] -_ProviderFactoryType = Callable[[_ModuleLike], "IResourceProvider"] +# 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]] _AdapterT = TypeVar( @@ -131,6 +137,10 @@ class _LoaderProtocol(Protocol): def load_module(self, fullname: str, /) -> types.ModuleType: ... +class _ZipLoaderModule(Protocol): + __loader__: zipimport.zipimporter + + _PEP440_FALLBACK = re.compile(r"^v?(?P<safe>(?:[0-9]+!)?[0-9]+(?:\.[0-9]+)*)", re.I) @@ -404,7 +414,11 @@ def register_loader_type( _provider_factories[loader_type] = provider_factory -def get_provider(moduleOrReq: str | Requirement): +@overload +def get_provider(moduleOrReq: str) -> IResourceProvider: ... +@overload +def get_provider(moduleOrReq: Requirement) -> Distribution: ... +def get_provider(moduleOrReq: str | Requirement) -> IResourceProvider | Distribution: """Return an IResourceProvider for the named module or requirement""" if isinstance(moduleOrReq, Requirement): return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] @@ -515,22 +529,33 @@ def compatible_platforms(provided: str | None, required: str | None): return False -def get_distribution(dist: _EPDistType): +@overload +def get_distribution(dist: _DistributionT) -> _DistributionT: ... +@overload +def get_distribution(dist: _PkgReqType) -> Distribution: ... +def get_distribution(dist: Distribution | _PkgReqType) -> Distribution: """Return a current distribution object for a Requirement or string""" if isinstance(dist, str): dist = Requirement.parse(dist) if isinstance(dist, Requirement): - dist = get_provider(dist) + # Bad type narrowing, dist has to be a Requirement here, so get_provider has to return Distribution + dist = get_provider(dist) # type: ignore[assignment] if not isinstance(dist, Distribution): - raise TypeError("Expected string, Requirement, or Distribution", dist) + raise TypeError("Expected str, Requirement, or Distribution", dist) return dist -def load_entry_point(dist: _EPDistType, group: str, name: str): +def load_entry_point(dist: _EPDistType, group: str, name: str) -> _ResolvedEntryPoint: """Return `name` entry point of `group` for `dist` or raise ImportError""" return get_distribution(dist).load_entry_point(group, name) +@overload +def get_entry_map( + dist: _EPDistType, group: None = None +) -> dict[str, dict[str, EntryPoint]]: ... +@overload +def get_entry_map(dist: _EPDistType, group: str) -> dict[str, EntryPoint]: ... def get_entry_map(dist: _EPDistType, group: str | None = None): """Return the entry point map for `group`, or the full entry map""" return get_distribution(dist).get_entry_map(group) @@ -545,10 +570,10 @@ class IMetadataProvider(Protocol): def has_metadata(self, name: str) -> bool: """Does the package's distribution contain the named metadata?""" - def get_metadata(self, name: str): + def get_metadata(self, name: str) -> str: """The named metadata resource as a string""" - def get_metadata_lines(self, name: str): + def get_metadata_lines(self, name: str) -> Iterator[str]: """Yield named metadata resource as list of non-blank non-comment lines Leading and trailing whitespace is stripped from each line, and lines @@ -557,22 +582,26 @@ class IMetadataProvider(Protocol): def metadata_isdir(self, name: str) -> bool: """Is the named metadata a directory? (like ``os.path.isdir()``)""" - def metadata_listdir(self, name: str): + def metadata_listdir(self, name: str) -> list[str]: """List of metadata names in the directory (like ``os.listdir()``)""" - def run_script(self, script_name: str, namespace: dict[str, Any]): + def run_script(self, script_name: str, namespace: dict[str, Any]) -> None: """Execute the named script in the supplied namespace dictionary""" class IResourceProvider(IMetadataProvider, Protocol): """An object that provides access to package resources""" - def get_resource_filename(self, manager: ResourceManager, resource_name: str): + def get_resource_filename( + self, manager: ResourceManager, resource_name: str + ) -> str: """Return a true filesystem path for `resource_name` `manager` must be a ``ResourceManager``""" - def get_resource_stream(self, manager: ResourceManager, resource_name: str): + def get_resource_stream( + self, manager: ResourceManager, resource_name: str + ) -> _ResourceStream: """Return a readable file-like object for `resource_name` `manager` must be a ``ResourceManager``""" @@ -584,13 +613,13 @@ class IResourceProvider(IMetadataProvider, Protocol): `manager` must be a ``ResourceManager``""" - def has_resource(self, resource_name: str): + def has_resource(self, resource_name: str) -> bool: """Does the package contain the named resource?""" - def resource_isdir(self, resource_name: str): + def resource_isdir(self, resource_name: str) -> bool: """Is the named resource a directory? (like ``os.path.isdir()``)""" - def resource_listdir(self, resource_name: str): + def resource_listdir(self, resource_name: str) -> list[str]: """List of resource names in the directory (like ``os.listdir()``)""" @@ -724,7 +753,7 @@ class WorkingSet: The yield order is the order in which the items' path entries were added to the working set. """ - seen = {} + seen = set() for item in self.entries: if item not in self.entry_keys: # workaround a cache issue @@ -732,7 +761,7 @@ class WorkingSet: for key in self.entry_keys[item]: if key not in seen: - seen[key] = True + seen.add(key) yield self.by_key[key] def add( @@ -773,6 +802,26 @@ class WorkingSet: keys2.append(dist.key) self._added_new(dist) + @overload + def resolve( + self, + requirements: Iterable[Requirement], + env: Environment | None, + installer: _InstallerTypeT[_DistributionT], + replace_conflicting: bool = False, + extras: tuple[str, ...] | None = None, + ) -> list[_DistributionT]: ... + @overload + def resolve( + self, + requirements: Iterable[Requirement], + env: Environment | None = None, + *, + installer: _InstallerTypeT[_DistributionT], + replace_conflicting: bool = False, + extras: tuple[str, ...] | None = None, + ) -> list[_DistributionT]: ... + @overload def resolve( self, requirements: Iterable[Requirement], @@ -780,7 +829,15 @@ class WorkingSet: installer: _InstallerType | None = None, replace_conflicting: bool = False, extras: tuple[str, ...] | None = None, - ): + ) -> list[Distribution]: ... + def resolve( + self, + requirements: Iterable[Requirement], + env: Environment | None = None, + installer: _InstallerType | None | _InstallerTypeT[_DistributionT] = None, + replace_conflicting: bool = False, + extras: tuple[str, ...] | None = None, + ) -> list[Distribution] | list[_DistributionT]: """List all distributions needed to (recursively) meet `requirements` `requirements` must be a sequence of ``Requirement`` objects. `env`, @@ -808,7 +865,7 @@ class WorkingSet: # set up the stack requirements = list(requirements)[::-1] # set of processed requirements - processed = {} + processed = set() # key -> dist best = {} to_activate = [] @@ -842,7 +899,7 @@ class WorkingSet: required_by[new_requirement].add(req.project_name) req_extras[new_requirement] = req.extras - processed[req] = True + processed.add(req) # return list of distros to activate return to_activate @@ -878,13 +935,41 @@ class WorkingSet: raise VersionConflict(dist, req).with_context(dependent_req) return dist + @overload + def find_plugins( + self, + plugin_env: Environment, + full_env: Environment | None, + installer: _InstallerTypeT[_DistributionT], + fallback: bool = True, + ) -> tuple[list[_DistributionT], dict[Distribution, Exception]]: ... + @overload + def find_plugins( + self, + plugin_env: Environment, + full_env: Environment | None = None, + *, + installer: _InstallerTypeT[_DistributionT], + fallback: bool = True, + ) -> tuple[list[_DistributionT], dict[Distribution, Exception]]: ... + @overload def find_plugins( self, plugin_env: Environment, full_env: Environment | None = None, installer: _InstallerType | None = None, fallback: bool = True, - ): + ) -> tuple[list[Distribution], dict[Distribution, Exception]]: ... + def find_plugins( + self, + plugin_env: Environment, + full_env: Environment | None = None, + installer: _InstallerType | None | _InstallerTypeT[_DistributionT] = None, + fallback: bool = True, + ) -> tuple[ + list[Distribution] | list[_DistributionT], + dict[Distribution, Exception], + ]: """Find all activatable distributions in `plugin_env` Example usage:: @@ -923,8 +1008,8 @@ class WorkingSet: # scan project names in alphabetic order plugin_projects.sort() - error_info = {} - distributions = {} + error_info: dict[Distribution, Exception] = {} + distributions: dict[Distribution, Exception | None] = {} if full_env is None: env = Environment(self.entries) @@ -1121,13 +1206,29 @@ class Environment: dists.append(dist) dists.sort(key=operator.attrgetter('hashcmp'), reverse=True) + @overload def best_match( self, req: Requirement, working_set: WorkingSet, - installer: Callable[[Requirement], Any] | None = None, + installer: _InstallerTypeT[_DistributionT], replace_conflicting: bool = False, - ): + ) -> _DistributionT: ... + @overload + def best_match( + self, + req: Requirement, + working_set: WorkingSet, + installer: _InstallerType | None = None, + replace_conflicting: bool = False, + ) -> Distribution | None: ... + def best_match( + self, + req: Requirement, + working_set: WorkingSet, + installer: _InstallerType | None | _InstallerTypeT[_DistributionT] = None, + replace_conflicting: bool = False, + ) -> Distribution | None: """Find distribution best matching `req` and usable on `working_set` This calls the ``find(req)`` method of the `working_set` to see if a @@ -1154,11 +1255,32 @@ class Environment: # try to download/install return self.obtain(req, installer) + @overload def obtain( self, requirement: Requirement, - installer: Callable[[Requirement], Any] | None = None, - ): + installer: _InstallerTypeT[_DistributionT], + ) -> _DistributionT: ... + @overload + def obtain( + self, + requirement: Requirement, + installer: Callable[[Requirement], None] | None = None, + ) -> None: ... + @overload + def obtain( + self, + requirement: Requirement, + installer: _InstallerType | None = None, + ) -> Distribution | None: ... + def obtain( + self, + requirement: Requirement, + installer: Callable[[Requirement], None] + | _InstallerType + | None + | _InstallerTypeT[_DistributionT] = None, + ) -> Distribution | None: """Obtain a distribution matching `requirement` (e.g. via download) Obtain a distro that matches requirement (e.g. via download). In the @@ -1313,7 +1435,7 @@ class ResourceManager: self._warn_unsafe_extraction_path(extract_path) - self.cached_files[target_path] = 1 + self.cached_files[target_path] = True return target_path @staticmethod @@ -1515,7 +1637,6 @@ class NullProvider: egg_name: str | None = None egg_info: str | None = None loader: _LoaderProtocol | None = None - module_path: str | None # Some subclasses can have a None module_path def __init__(self, module: _ModuleLike): self.loader = getattr(module, '__loader__', None) @@ -1558,7 +1679,7 @@ class NullProvider: exc.reason += ' in {} file at path: {}'.format(name, path) raise - def get_metadata_lines(self, name: str): + def get_metadata_lines(self, name: str) -> Iterator[str]: return yield_lines(self.get_metadata(name)) def resource_isdir(self, resource_name: str): @@ -1570,7 +1691,7 @@ class NullProvider: def resource_listdir(self, resource_name: str): return self._listdir(self._fn(self.module_path, resource_name)) - def metadata_listdir(self, name: str): + def metadata_listdir(self, name: str) -> list[str]: if self.egg_info: return self._listdir(self._fn(self.egg_info, name)) return [] @@ -1583,6 +1704,7 @@ class NullProvider: **locals() ), ) + script_text = self.get_metadata(script).replace('\r\n', '\n') script_text = script_text.replace('\r', '\n') script_filename = self._fn(self.egg_info, script) @@ -1613,12 +1735,16 @@ class NullProvider: "Can't perform this operation for unregistered loader type" ) - def _listdir(self, path): + def _listdir(self, path) -> list[str]: raise NotImplementedError( "Can't perform this operation for unregistered loader type" ) - def _fn(self, base, resource_name: str): + def _fn(self, base: str | None, resource_name: str): + if base is None: + raise TypeError( + "`base` parameter in `_fn` is `None`. Either override this method or check the parameter first." + ) self._validate_resource_path(resource_name) if resource_name: return os.path.join(base, *resource_name.split('/')) @@ -1778,7 +1904,8 @@ DefaultProvider._register() class EmptyProvider(NullProvider): """Provider that returns nothing for all requests""" - module_path = None + # A special case, we don't want all Providers inheriting from NullProvider to have a potentially None module_path + module_path: str | None = None # type: ignore[assignment] _isdir = _has = lambda self, path: False @@ -1854,7 +1981,7 @@ class ZipProvider(EggProvider): # ZipProvider's loader should always be a zipimporter or equivalent loader: zipimport.zipimporter - def __init__(self, module: _ModuleLike): + def __init__(self, module: _ZipLoaderModule): super().__init__(module) self.zip_pre = self.loader.archive + os.sep @@ -1903,7 +2030,7 @@ class ZipProvider(EggProvider): return timestamp, size # FIXME: 'ZipProvider._extract_resource' is too complex (12) - def _extract_resource(self, manager: ResourceManager, zip_path): # noqa: C901 + def _extract_resource(self, manager: ResourceManager, zip_path) -> str: # noqa: C901 if zip_path in self._index(): for name in self._index()[zip_path]: last = self._extract_resource(manager, os.path.join(zip_path, name)) @@ -2040,7 +2167,7 @@ class FileMetadata(EmptyProvider): def has_metadata(self, name: str) -> bool: return name == 'PKG-INFO' and os.path.isfile(self.path) - def get_metadata(self, name): + def get_metadata(self, name: str): if name != 'PKG-INFO': raise KeyError("No metadata except PKG-INFO is available") @@ -2056,7 +2183,7 @@ class FileMetadata(EmptyProvider): msg = tmpl.format(**locals()) warnings.warn(msg) - def get_metadata_lines(self, name): + def get_metadata_lines(self, name: str) -> Iterator[str]: return yield_lines(self.get_metadata(name)) @@ -2582,12 +2709,26 @@ class EntryPoint: def __repr__(self): return "EntryPoint.parse(%r)" % str(self) + @overload + def load( + self, + require: Literal[True] = True, + env: Environment | None = None, + installer: _InstallerType | None = None, + ) -> _ResolvedEntryPoint: ... + @overload + def load( + self, + require: Literal[False], + *args: Any, + **kwargs: Any, + ) -> _ResolvedEntryPoint: ... def load( self, require: bool = True, *args: Environment | _InstallerType | None, **kwargs: Environment | _InstallerType | None, - ): + ) -> _ResolvedEntryPoint: """ Require packages for this EntryPoint, then resolve it. """ @@ -2604,7 +2745,7 @@ class EntryPoint: self.require(*args, **kwargs) # type: ignore return self.resolve() - def resolve(self): + def resolve(self) -> _ResolvedEntryPoint: """ Resolve the entry point from its module and attrs. """ @@ -3033,13 +3174,17 @@ class Distribution: return Requirement.parse(spec) - def load_entry_point(self, group: str, name: str): + def load_entry_point(self, group: str, name: str) -> _ResolvedEntryPoint: """Return the `name` entry point of `group` or raise ImportError""" ep = self.get_entry_info(group, name) if ep is None: raise ImportError("Entry point %r not found" % ((group, name),)) return ep.load() + @overload + def get_entry_map(self, group: None = None) -> dict[str, dict[str, EntryPoint]]: ... + @overload + def get_entry_map(self, group: str) -> dict[str, EntryPoint]: ... def get_entry_map(self, group: str | None = None): """Return the entry point map for `group`, or the full entry map""" if not hasattr(self, "_ep_map"): diff --git a/contrib/python/setuptools/py3/setuptools/command/easy_install.py b/contrib/python/setuptools/py3/setuptools/command/easy_install.py index eb6ba1025f..5ec5080131 100644 --- a/contrib/python/setuptools/py3/setuptools/command/easy_install.py +++ b/contrib/python/setuptools/py3/setuptools/command/easy_install.py @@ -1047,7 +1047,7 @@ class easy_install(Command): prefixes = get_exe_prefixes(dist_filename) to_compile = [] native_libs = [] - top_level = {} + top_level = set() def process(src, dst): s = src.lower() @@ -1059,10 +1059,10 @@ class easy_install(Command): dl = dst.lower() if dl.endswith('.pyd') or dl.endswith('.dll'): parts[-1] = bdist_egg.strip_module(parts[-1]) - top_level[os.path.splitext(parts[0])[0]] = True + top_level.add([os.path.splitext(parts[0])[0]]) native_libs.append(src) elif dl.endswith('.py') and old != 'SCRIPTS/': - top_level[os.path.splitext(parts[0])[0]] = True + top_level.add([os.path.splitext(parts[0])[0]]) to_compile.append(dst) return dst if not src.endswith('.pth'): @@ -1484,14 +1484,14 @@ def get_site_dirs(): def expand_paths(inputs): # noqa: C901 # is too complex (11) # FIXME """Yield sys.path directories that might contain "old-style" packages""" - seen = {} + seen = set() for dirname in inputs: dirname = normalize_path(dirname) if dirname in seen: continue - seen[dirname] = True + seen.add(dirname) if not os.path.isdir(dirname): continue @@ -1520,7 +1520,7 @@ def expand_paths(inputs): # noqa: C901 # is too complex (11) # FIXME if line in seen: continue - seen[line] = True + seen.add(line) if not os.path.isdir(line): continue @@ -1622,7 +1622,7 @@ class PthDistributions(Environment): def _load_raw(self): paths = [] dirty = saw_import = False - seen = dict.fromkeys(self.sitedirs) + seen = set(self.sitedirs) f = open(self.filename, 'rt', encoding=py39.LOCALE_ENCODING) # ^-- Requires encoding="locale" instead of "utf-8" (python/cpython#77102). for line in f: @@ -1643,7 +1643,7 @@ class PthDistributions(Environment): dirty = True paths.pop() continue - seen[normalized_path] = True + seen.add(normalized_path) f.close() # remove any trailing empty/blank line while paths and not paths[-1].strip(): diff --git a/contrib/python/setuptools/py3/setuptools/package_index.py b/contrib/python/setuptools/py3/setuptools/package_index.py index c8789e279f..c91e419923 100644 --- a/contrib/python/setuptools/py3/setuptools/package_index.py +++ b/contrib/python/setuptools/py3/setuptools/package_index.py @@ -627,7 +627,7 @@ class PackageIndex(Environment): """ # process a Requirement self.info("Searching for %s", requirement) - skipped = {} + skipped = set() dist = None def find(req, env=None): @@ -642,7 +642,7 @@ class PackageIndex(Environment): "Skipping development or system egg: %s", dist, ) - skipped[dist] = True + skipped.add(dist) continue test = dist in req and (dist.precedence <= SOURCE_DIST or not source) diff --git a/contrib/python/setuptools/py3/ya.make b/contrib/python/setuptools/py3/ya.make index 29bd4687af..a22c66f39e 100644 --- a/contrib/python/setuptools/py3/ya.make +++ b/contrib/python/setuptools/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(70.1.0) +VERSION(70.1.1) LICENSE(MIT) |