Skip to content

Commit c93a9f7

Browse files
authored
Merge pull request #272 from anntzer/moreperf
Further optimize distribution() searching.
2 parents c769ba8 + 7fc4f11 commit c93a9f7

File tree

1 file changed

+17
-10
lines changed

1 file changed

+17
-10
lines changed

importlib_metadata/__init__.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -493,15 +493,22 @@ class Prepared:
493493
"""
494494

495495
normalized = None
496-
suffixes = '.dist-info', '.egg-info'
496+
suffixes = 'dist-info', 'egg-info'
497497
exact_matches = [''][:0]
498+
egg_prefix = ''
499+
versionless_egg_name = ''
498500

499501
def __init__(self, name):
500502
self.name = name
501503
if name is None:
502504
return
503505
self.normalized = self.normalize(name)
504-
self.exact_matches = [self.normalized + suffix for suffix in self.suffixes]
506+
self.exact_matches = [
507+
self.normalized + '.' + suffix for suffix in self.suffixes
508+
]
509+
legacy_normalized = self.legacy_normalize(self.name)
510+
self.egg_prefix = legacy_normalized + '-'
511+
self.versionless_egg_name = legacy_normalized + '.egg'
505512

506513
@staticmethod
507514
def normalize(name):
@@ -520,8 +527,10 @@ def legacy_normalize(name):
520527

521528
def matches(self, cand, base):
522529
low = cand.lower()
523-
pre, ext = os.path.splitext(low)
524-
name, sep, rest = pre.partition('-')
530+
# rpartition is like os.path.splitext, but much faster. They'd only
531+
# differ if pre is empty, but in that case we don't have a match anyways.
532+
pre, _, ext = low.rpartition('.')
533+
name, _, rest = pre.partition('-')
525534
return (
526535
low in self.exact_matches
527536
or ext in self.suffixes
@@ -532,12 +541,9 @@ def matches(self, cand, base):
532541
)
533542

534543
def is_egg(self, base):
535-
normalized = self.legacy_normalize(self.name or '')
536-
prefix = normalized + '-' if normalized else ''
537-
versionless_egg_name = normalized + '.egg' if self.name else ''
538544
return (
539-
base == versionless_egg_name
540-
or base.startswith(prefix)
545+
base == self.versionless_egg_name
546+
or base.startswith(self.egg_prefix)
541547
and base.endswith('.egg')
542548
)
543549

@@ -565,8 +571,9 @@ def find_distributions(self, context=DistributionFinder.Context()):
565571
@classmethod
566572
def _search_paths(cls, name, paths):
567573
"""Find metadata directories in paths heuristically."""
574+
prepared = Prepared(name)
568575
return itertools.chain.from_iterable(
569-
path.search(Prepared(name)) for path in map(FastPath, paths)
576+
path.search(prepared) for path in map(FastPath, paths)
570577
)
571578

572579

0 commit comments

Comments
 (0)