Skip to content

Commit c3421fb

Browse files
committed
Merge branch 'maint/2.x'
2 parents 2bc4989 + dd25a38 commit c3421fb

File tree

5 files changed

+72
-3
lines changed

5 files changed

+72
-3
lines changed

docs/changelog.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,18 @@
22
importlib_metadata NEWS
33
=========================
44

5+
v3.1.0
6+
======
7+
8+
* Merge with 2.1.0.
9+
10+
v2.1.0
11+
======
12+
13+
* #253: When querying for package metadata, the lookup
14+
now honors
15+
`package normalization rules <https://packaging.python.org/specifications/recording-installed-packages/>`_.
16+
517
v3.0.0
618
======
719

importlib_metadata/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ def search(self, name):
461461
for child in self.children():
462462
n_low = child.lower()
463463
if (n_low in name.exact_matches
464-
or n_low.startswith(name.prefix)
464+
or n_low.replace('.', '_').startswith(name.prefix)
465465
and n_low.endswith(name.suffixes)
466466
# legacy case:
467467
or self.is_egg(name) and n_low == 'egg-info'):
@@ -482,12 +482,19 @@ def __init__(self, name):
482482
self.name = name
483483
if name is None:
484484
return
485-
self.normalized = name.lower().replace('-', '_')
485+
self.normalized = self.normalize(name)
486486
self.prefix = self.normalized + '-'
487487
self.exact_matches = [
488488
self.normalized + suffix for suffix in self.suffixes]
489489
self.versionless_egg_name = self.normalized + '.egg'
490490

491+
@staticmethod
492+
def normalize(name):
493+
"""
494+
PEP 503 normalization plus dashes as underscores.
495+
"""
496+
return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_')
497+
491498

492499
@install
493500
class MetadataPathFinder(NullFinder, DistributionFinder):

setup.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ testing =
3838
importlib_resources>=1.3; python_version < "3.9"
3939
packaging
4040
pep517
41+
unittest2; python_version < "3"
4142
docs =
4243
sphinx
4344
rst.linker

tests/fixtures.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,36 @@ def setUp(self):
9999
build_files(DistInfoPkg.files, self.site_dir)
100100

101101

102+
class DistInfoPkgWithDot(OnSysPath, SiteDir):
103+
files = {
104+
"pkg_dot-1.0.0.dist-info": {
105+
"METADATA": """
106+
Name: pkg.dot
107+
Version: 1.0.0
108+
""",
109+
},
110+
}
111+
112+
def setUp(self):
113+
super(DistInfoPkgWithDot, self).setUp()
114+
build_files(DistInfoPkgWithDot.files, self.site_dir)
115+
116+
117+
class DistInfoPkgWithDotLegacy(OnSysPath, SiteDir):
118+
files = {
119+
"pkg.dot-1.0.0.dist-info": {
120+
"METADATA": """
121+
Name: pkg.dot
122+
Version: 1.0.0
123+
""",
124+
},
125+
}
126+
127+
def setUp(self):
128+
super(DistInfoPkgWithDotLegacy, self).setUp()
129+
build_files(DistInfoPkgWithDotLegacy.files, self.site_dir)
130+
131+
102132
class DistInfoPkgOffPath(SiteDir):
103133
def setUp(self):
104134
super(DistInfoPkgOffPath, self).setUp()

tests/test_api.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import re
22
import textwrap
3-
import unittest
3+
4+
try:
5+
import unittest2 as unittest
6+
except ImportError:
7+
import unittest
48

59
from . import fixtures
610
from importlib_metadata import (
@@ -12,6 +16,7 @@
1216
class APITests(
1317
fixtures.EggInfoPkg,
1418
fixtures.DistInfoPkg,
19+
fixtures.DistInfoPkgWithDot,
1520
fixtures.EggInfoFile,
1621
unittest.TestCase):
1722

@@ -31,6 +36,12 @@ def test_for_name_does_not_exist(self):
3136
with self.assertRaises(PackageNotFoundError):
3237
distribution('does-not-exist')
3338

39+
def test_name_normalization(self):
40+
names = 'pkg.dot', 'pkg_dot', 'pkg-dot', 'pkg..dot', 'Pkg.Dot'
41+
for name in names:
42+
with self.subTest(name):
43+
assert distribution(name).metadata['Name'] == 'pkg.dot'
44+
3445
def test_for_top_level(self):
3546
self.assertEqual(
3647
distribution('egginfo-pkg').read_text('top_level.txt').strip(),
@@ -146,6 +157,14 @@ def test_more_complex_deps_requires_text(self):
146157
assert deps == expected
147158

148159

160+
class LegacyDots(fixtures.DistInfoPkgWithDotLegacy, unittest.TestCase):
161+
def test_name_normalization(self):
162+
names = 'pkg.dot', 'pkg_dot', 'pkg-dot', 'pkg..dot', 'Pkg.Dot'
163+
for name in names:
164+
with self.subTest(name):
165+
assert distribution(name).metadata['Name'] == 'pkg.dot'
166+
167+
149168
class OffSysPathTests(fixtures.DistInfoPkgOffPath, unittest.TestCase):
150169
def test_find_distributions_specified_path(self):
151170
dists = Distribution.discover(path=[str(self.site_dir)])

0 commit comments

Comments
 (0)