mirror of
https://github.com/python/cpython.git
synced 2025-08-21 17:25:34 +00:00
Inline the find_distributions functionality on PathFinder.
This commit is contained in:
parent
58533a71b2
commit
3b19b9d823
4 changed files with 822 additions and 693 deletions
|
@ -1359,6 +1359,57 @@ class PathFinder:
|
||||||
return None
|
return None
|
||||||
return spec.loader
|
return spec.loader
|
||||||
|
|
||||||
|
search_template = r'{pattern}(-.*)?\.(dist|egg)-info'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def find_distributions(cls, name=None, path=None):
|
||||||
|
"""Return an iterable of all Distribution instances capable of
|
||||||
|
loading the metadata for packages matching the name
|
||||||
|
(or all names if not supplied) along the paths in the list
|
||||||
|
of directories ``path`` (defaults to sys.path).
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
from importlib.metadata._hooks import PathDistribution
|
||||||
|
if path is None:
|
||||||
|
path = sys.path
|
||||||
|
pattern = '.*' if name is None else re.escape(name)
|
||||||
|
found = cls._search_paths(pattern, path)
|
||||||
|
return map(PathDistribution, found)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _search_paths(cls, pattern, paths):
|
||||||
|
"""
|
||||||
|
Find metadata directories in paths heuristically.
|
||||||
|
"""
|
||||||
|
import itertools
|
||||||
|
return itertools.chain.from_iterable(
|
||||||
|
cls._search_path(path, pattern)
|
||||||
|
for path in map(cls._switch_path, paths)
|
||||||
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _switch_path(path):
|
||||||
|
from contextlib import suppress
|
||||||
|
import zipfile
|
||||||
|
from pathlib import Path
|
||||||
|
with suppress(Exception):
|
||||||
|
return zipfile.Path(path)
|
||||||
|
return Path(path)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _predicate(cls, pattern, root, item):
|
||||||
|
import re
|
||||||
|
return re.match(pattern, str(item.name), flags=re.IGNORECASE)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _search_path(cls, root, pattern):
|
||||||
|
if not root.is_dir():
|
||||||
|
return ()
|
||||||
|
normalized = pattern.replace('-', '_')
|
||||||
|
matcher = cls.search_template.format(pattern=normalized)
|
||||||
|
return (item for item in root.iterdir()
|
||||||
|
if cls._predicate(matcher, root, item))
|
||||||
|
|
||||||
|
|
||||||
class FileFinder:
|
class FileFinder:
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,8 @@
|
||||||
import re
|
|
||||||
import sys
|
import sys
|
||||||
import zipfile
|
|
||||||
import itertools
|
|
||||||
|
|
||||||
from .api import Distribution
|
from .api import Distribution
|
||||||
from .abc import DistributionFinder
|
from .abc import DistributionFinder
|
||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
|
|
||||||
def install(cls):
|
def install(cls):
|
||||||
|
@ -25,57 +21,6 @@ class NullFinder(DistributionFinder):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@install
|
|
||||||
class MetadataPathFinder(NullFinder):
|
|
||||||
"""A degenerate finder for distribution packages on the file system.
|
|
||||||
|
|
||||||
This finder supplies only a find_distributions() method for versions
|
|
||||||
of Python that do not have a PathFinder find_distributions().
|
|
||||||
"""
|
|
||||||
search_template = r'{pattern}(-.*)?\.(dist|egg)-info'
|
|
||||||
|
|
||||||
def find_distributions(self, name=None, path=None):
|
|
||||||
"""Return an iterable of all Distribution instances capable of
|
|
||||||
loading the metadata for packages matching the name
|
|
||||||
(or all names if not supplied) along the paths in the list
|
|
||||||
of directories ``path`` (defaults to sys.path).
|
|
||||||
"""
|
|
||||||
if path is None:
|
|
||||||
path = sys.path
|
|
||||||
pattern = '.*' if name is None else re.escape(name)
|
|
||||||
found = self._search_paths(pattern, path)
|
|
||||||
return map(PathDistribution, found)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _search_paths(cls, pattern, paths):
|
|
||||||
"""
|
|
||||||
Find metadata directories in paths heuristically.
|
|
||||||
"""
|
|
||||||
return itertools.chain.from_iterable(
|
|
||||||
cls._search_path(path, pattern)
|
|
||||||
for path in map(cls._switch_path, paths)
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _switch_path(path):
|
|
||||||
with suppress(Exception):
|
|
||||||
return zipfile.Path(path)
|
|
||||||
return Path(path)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _predicate(cls, pattern, root, item):
|
|
||||||
return re.match(pattern, str(item.name), flags=re.IGNORECASE)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def _search_path(cls, root, pattern):
|
|
||||||
if not root.is_dir():
|
|
||||||
return ()
|
|
||||||
normalized = pattern.replace('-', '_')
|
|
||||||
matcher = cls.search_template.format(pattern=normalized)
|
|
||||||
return (item for item in root.iterdir()
|
|
||||||
if cls._predicate(matcher, root, item))
|
|
||||||
|
|
||||||
|
|
||||||
class PathDistribution(Distribution):
|
class PathDistribution(Distribution):
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
"""Construct a distribution from a path to the metadata directory."""
|
"""Construct a distribution from a path to the metadata directory."""
|
||||||
|
|
|
@ -7,7 +7,7 @@ import importlib
|
||||||
|
|
||||||
from . import fixtures
|
from . import fixtures
|
||||||
from importlib.metadata import (
|
from importlib.metadata import (
|
||||||
Distribution, PackageNotFoundError, _hooks, api, distributions,
|
Distribution, PackageNotFoundError, api, distributions,
|
||||||
entry_points, metadata, version)
|
entry_points, metadata, version)
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@ class BasicTests(fixtures.DistInfoPkg, unittest.TestCase):
|
||||||
|
|
||||||
def test_new_style_classes(self):
|
def test_new_style_classes(self):
|
||||||
self.assertIsInstance(Distribution, type)
|
self.assertIsInstance(Distribution, type)
|
||||||
self.assertIsInstance(_hooks.MetadataPathFinder, type)
|
|
||||||
|
|
||||||
|
|
||||||
class ImportTests(fixtures.DistInfoPkg, unittest.TestCase):
|
class ImportTests(fixtures.DistInfoPkg, unittest.TestCase):
|
||||||
|
|
1406
Python/importlib_external.h
generated
1406
Python/importlib_external.h
generated
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue