mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
bpo-34632: Add importlib.metadata (GH-12547)
Add importlib.metadata module as forward port of the standalone importlib_metadata.
This commit is contained in:
parent
6dbbe748e1
commit
1bbf7b661f
15 changed files with 2049 additions and 639 deletions
|
@ -1363,6 +1363,58 @@ class PathFinder:
|
|||
return None
|
||||
return spec.loader
|
||||
|
||||
search_template = r'(?:{pattern}(-.*)?\.(dist|egg)-info|EGG-INFO)'
|
||||
|
||||
@classmethod
|
||||
def find_distributions(cls, name=None, path=None):
|
||||
"""
|
||||
Find distributions.
|
||||
|
||||
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 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:
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue