From 596abd00469bc10562ae3cdc8ea02827797b8e23 Mon Sep 17 00:00:00 2001 From: Benoit Pierre Date: Thu, 12 May 2022 21:15:45 +0200 Subject: [PATCH] fix `PathDistribution._normalized_name` implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - apply PEP 503 normalization to the extracted names (e.g.: `zope..inter_face-4.2.dist-info` must yield the name `zope_inter_face`) `entry_points(…)` can yield the entry-points of a shadowed distribution. For example: with a version of `mypkg` in the system' site-packages directory when working from another development checkout of the same package (with a `mypkg.egg-info` directory mishandled by the first bug). --- importlib_metadata/__init__.py | 5 +++- tests/test_main.py | 43 +++++++++++++++++++++++++++------- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/importlib_metadata/__init__.py b/importlib_metadata/__init__.py index e4e3a506..0ae677f8 100644 --- a/importlib_metadata/__init__.py +++ b/importlib_metadata/__init__.py @@ -956,7 +956,10 @@ def _normalized_name(self): 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 + ) @staticmethod def _name_from_stem(stem): diff --git a/tests/test_main.py b/tests/test_main.py index 1a64af56..90c65260 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -14,6 +14,7 @@ EntryPoint, MetadataPathFinder, PackageNotFoundError, + distribution, distributions, entry_points, metadata, @@ -87,15 +88,17 @@ def pkg_with_dashes(site_dir): metadata = metadata_dir / 'METADATA' with metadata.open('w', encoding='utf-8') as strm: strm.write('Version: 1.0\n') - return 'my-pkg' + return 'my-pkg', 'my_pkg' def test_dashes_in_dist_name_found_as_underscores(self): """ For a package with a dash in the name, the dist-info metadata uses underscores in the name. Ensure the metadata loads. """ - pkg_name = self.pkg_with_dashes(self.site_dir) - assert version(pkg_name) == '1.0' + pkg_name, norm_pkg_name = self.pkg_with_dashes(self.site_dir) + dist = distribution(pkg_name) + assert dist._normalized_name == norm_pkg_name + assert dist.version == '1.0' @staticmethod def pkg_with_mixed_case(site_dir): @@ -108,16 +111,40 @@ def pkg_with_mixed_case(site_dir): metadata = metadata_dir / 'METADATA' with metadata.open('w', encoding='utf-8') as strm: strm.write('Version: 1.0\n') - return 'CherryPy' + return 'CheRRypY', 'cherrypy' def test_dist_name_found_as_any_case(self): """ Ensure the metadata loads when queried with any case. """ - pkg_name = self.pkg_with_mixed_case(self.site_dir) - assert version(pkg_name) == '1.0' - assert version(pkg_name.lower()) == '1.0' - assert version(pkg_name.upper()) == '1.0' + pkg_name, norm_pkg_name = self.pkg_with_mixed_case(self.site_dir) + for name_variant in (pkg_name, pkg_name.lower(), pkg_name.upper()): + dist = distribution(name_variant) + assert dist._normalized_name == norm_pkg_name + assert dist.version == '1.0' + + @staticmethod + def pkg_with_replaced_chars(site_dir): + """ + Create minimal metadata for a package with some + characters replaced by PEP 503 normalization + in the name. + """ + metadata_dir = site_dir / 'zope..inter_face-4.2.dist-info' + metadata_dir.mkdir() + metadata = metadata_dir / 'METADATA' + with metadata.open('w', encoding='utf-8') as strm: + strm.write('Version: 4.2\n') + return 'zope-inter._FACE', 'zope_inter_face' + + def test_dist_name_pep503_normalization(self): + """ + Ensure the distribution name is properly normalized. + """ + pkg_name, norm_pkg_name = self.pkg_with_replaced_chars(self.site_dir) + dist = distribution(pkg_name) + assert dist._normalized_name == norm_pkg_name + assert dist.version == '4.2' class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):