Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion Lib/importlib/metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,11 @@ def name(self):
"""Return the 'Name' metadata for the distribution package."""
return self.metadata['Name']

@property
def _normalized_name(self):
"""Return a normalized version of the name."""
return Prepared.normalize(self.name)

@property
def version(self):
"""Return the 'Version' metadata for the distribution package."""
Expand Down Expand Up @@ -795,6 +800,22 @@ def read_text(self, filename):
def locate_file(self, path):
return self._path.parent / path

@property
def _normalized_name(self):
"""
Performance optimization: where possible, resolve the
normalized name from the file system path.
"""
stem = os.path.basename(str(self._path))
return self._name_from_stem(stem) or super()._normalized_name

def _name_from_stem(self, stem):
name, ext = os.path.splitext(stem)
if ext not in ('.dist-info', '.egg-info'):
return
name, sep, rest = stem.partition('-')
return name


def distribution(distribution_name):
"""Get the ``Distribution`` instance for the named package.
Expand Down Expand Up @@ -849,7 +870,8 @@ def entry_points(**params) -> Union[EntryPoints, SelectableGroups]:

:return: EntryPoints or SelectableGroups for all installed packages.
"""
unique = functools.partial(unique_everseen, key=operator.attrgetter('name'))
norm_name = operator.attrgetter('_normalized_name')
unique = functools.partial(unique_everseen, key=norm_name)
eps = itertools.chain.from_iterable(
dist.entry_points for dist in unique(distributions())
)
Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_importlib/test_zip.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ def test_files(self):
for file in files('example'):
path = str(file.dist.locate_file(file))
assert '.egg/' in path, path

def test_normalized_name(self):
dist = distribution('example')
assert dist._normalized_name == 'example'
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
In importlib.metadata.entry_points, de-duplication of distributions no
longer requires loading the full metadata for PathDistribution objects,
improving entry point loading performance by ~10x.