From 9a5ca31af0ee07e5401ec7e0dda8ff1d035ce32d Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Thu, 10 Nov 2022 10:59:38 -0500 Subject: [3.10] gh-99130: Apply bugfixes from importlib_metadata 4.11.4. (#99132) --- Lib/importlib/metadata/__init__.py | 22 +++++++++++++++++----- Lib/importlib/metadata/_functools.py | 19 +++++++++++++++++++ Lib/test/test_importlib/test_metadata_api.py | 10 ++++++---- .../2022-11-05-11-42-15.gh-issue-99130.91MMXu.rst | 7 +++++++ 4 files changed, 49 insertions(+), 9 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-11-05-11-42-15.gh-issue-99130.91MMXu.rst diff --git a/Lib/importlib/metadata/__init__.py b/Lib/importlib/metadata/__init__.py index b3063cd..682067d 100644 --- a/Lib/importlib/metadata/__init__.py +++ b/Lib/importlib/metadata/__init__.py @@ -17,7 +17,7 @@ import collections from . import _adapters, _meta from ._meta import PackageMetadata from ._collections import FreezableDefaultDict, Pair -from ._functools import method_cache +from ._functools import method_cache, pass_none from ._itertools import unique_everseen from ._meta import PackageMetadata, SimplePath @@ -938,13 +938,25 @@ class PathDistribution(Distribution): normalized name from the file system path. """ stem = os.path.basename(str(self._path)) - return self._name_from_stem(stem) or super()._normalized_name + return ( + pass_none(Prepared.normalize)(self._name_from_stem(stem)) + or super()._normalized_name + ) - def _name_from_stem(self, stem): - name, ext = os.path.splitext(stem) + @staticmethod + def _name_from_stem(stem): + """ + >>> PathDistribution._name_from_stem('foo-3.0.egg-info') + 'foo' + >>> PathDistribution._name_from_stem('CherryPy-3.0.dist-info') + 'CherryPy' + >>> PathDistribution._name_from_stem('face.egg-info') + 'face' + """ + filename, ext = os.path.splitext(stem) if ext not in ('.dist-info', '.egg-info'): return - name, sep, rest = stem.partition('-') + name, sep, rest = filename.partition('-') return name diff --git a/Lib/importlib/metadata/_functools.py b/Lib/importlib/metadata/_functools.py index 73f50d0..71f66bd 100644 --- a/Lib/importlib/metadata/_functools.py +++ b/Lib/importlib/metadata/_functools.py @@ -83,3 +83,22 @@ def method_cache(method, cache_wrapper=None): wrapper.cache_clear = lambda: None return wrapper + + +# From jaraco.functools 3.3 +def pass_none(func): + """ + Wrap func so it's not called if its first param is None + + >>> print_text = pass_none(print) + >>> print_text('text') + text + >>> print_text(None) + """ + + @functools.wraps(func) + def wrapper(param, *args, **kwargs): + if param is not None: + return func(param, *args, **kwargs) + + return wrapper diff --git a/Lib/test/test_importlib/test_metadata_api.py b/Lib/test/test_importlib/test_metadata_api.py index 799f007..ab48281 100644 --- a/Lib/test/test_importlib/test_metadata_api.py +++ b/Lib/test/test_importlib/test_metadata_api.py @@ -89,13 +89,15 @@ class APITests( self.assertIn(ep.dist.name, ('distinfo-pkg', 'egginfo-pkg')) self.assertEqual(ep.dist.version, "1.0.0") - def test_entry_points_unique_packages(self): - # Entry points should only be exposed for the first package - # on sys.path with a given name. + def test_entry_points_unique_packages_normalized(self): + """ + Entry points should only be exposed for the first package + on sys.path with a given name (even when normalized). + """ alt_site_dir = self.fixtures.enter_context(fixtures.tempdir()) self.fixtures.enter_context(self.add_sys_path(alt_site_dir)) alt_pkg = { - "distinfo_pkg-1.1.0.dist-info": { + "DistInfo_pkg-1.1.0.dist-info": { "METADATA": """ Name: distinfo-pkg Version: 1.1.0 diff --git a/Misc/NEWS.d/next/Library/2022-11-05-11-42-15.gh-issue-99130.91MMXu.rst b/Misc/NEWS.d/next/Library/2022-11-05-11-42-15.gh-issue-99130.91MMXu.rst new file mode 100644 index 0000000..124d5e4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-11-05-11-42-15.gh-issue-99130.91MMXu.rst @@ -0,0 +1,7 @@ +Apply bugfixes from `importlib_metadata 4.11.4 +`_, +namely: In ``PathDistribution._name_from_stem``, avoid including parts of +the extension in the result. In ``PathDistribution._normalized_name``, +ensure names loaded from the stem of the filename are also normalized, +ensuring duplicate entry points by packages varying only by non-normalized +name are hidden. -- cgit v0.12