Skip to content

Commit

Permalink
Move MetadataPathFinder back into the metadata package. Let importlib…
Browse files Browse the repository at this point in the history
….PathFinder.find_distributions just call into MetadataPathFinder.find_distributions. Ref #88.
  • Loading branch information
jaraco committed Sep 11, 2019
1 parent a808efb commit 83b48ec
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 63 deletions.
63 changes: 0 additions & 63 deletions Lib/importlib/_bootstrap_external.py

This file was deleted.

54 changes: 54 additions & 0 deletions Lib/importlib/metadata.py
@@ -1,10 +1,12 @@
import io
import os
import re
import abc
import csv
import sys
import email
import pathlib
import zipfile
import operator
import functools
import itertools
Expand Down Expand Up @@ -363,6 +365,58 @@ def find_distributions(self, context=Context()):
"""


class MetadataPathFinder(DistributionFinder):
@classmethod
def find_distributions(cls, context=DistributionFinder.Context()):
"""
Find distributions.
Return an iterable of all Distribution instances capable of
loading the metadata for packages matching ``context.name``
(or all names if ``None`` indicated) along the paths in the list
of directories ``context.path``.
"""
found = cls._search_paths(context.pattern, context.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):
PYPY_OPEN_BUG = False
if not PYPY_OPEN_BUG or os.path.isfile(path): # pragma: no branch
with suppress(Exception):
return zipfile.Path(path)
return pathlib.Path(path)

@classmethod
def _matches_info(cls, normalized, item):
template = r'{pattern}(-.*)?\.(dist|egg)-info'
manifest = template.format(pattern=normalized)
return re.match(manifest, item.name, flags=re.IGNORECASE)

@classmethod
def _matches_legacy(cls, normalized, item):
template = r'{pattern}-.*\.egg[\\/]EGG-INFO'
manifest = template.format(pattern=normalized)
return re.search(manifest, str(item), flags=re.IGNORECASE)

@classmethod
def _search_path(cls, root, pattern):
if not root.is_dir():
return ()
normalized = pattern.replace('-', '_')
return (item for item in root.iterdir()
if cls._matches_info(normalized, item)
or cls._matches_legacy(normalized, item))


class PathDistribution(Distribution):
def __init__(self, path):
"""Construct a distribution from a path to the metadata directory.
Expand Down

0 comments on commit 83b48ec

Please sign in to comment.