Skip to content

Commit 4c44ed0

Browse files
committed
Merge v8.9.0
2 parents a9f883f + 613e980 commit 4c44ed0

File tree

4 files changed

+60
-2
lines changed

4 files changed

+60
-2
lines changed

NEWS.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ Deprecations and Removals
66

77
- Added ``MetadataNotFound`` (subclass of ``FileNotFoundError``) and updated ``Distribution.metadata``/``metadata()`` to raise it when the metadata files are missing instead of returning ``None`` (python/cpython#143387). (#532)
88

9+
v8.9.0
10+
======
11+
12+
Features
13+
--------
14+
15+
- Ported changes from CPython (python/cpython#110937, python/cpython#140141, python/cpython#143658)
16+
917

1018
v8.8.0
1119
======

exercises.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,13 @@ def entrypoint_regexp_perf():
4545
input = '0' + ' ' * 2**10 + '0' # end warmup
4646

4747
re.match(importlib_metadata.EntryPoint.pattern, input)
48+
49+
50+
def normalize_perf():
51+
# python/cpython#143658
52+
import importlib_metadata # end warmup
53+
54+
# operation completes in < 1ms, so repeat it to get visibility
55+
# https://github.com/jaraco/pytest-perf/issues/12
56+
for _ in range(1000):
57+
importlib_metadata.Prepared.normalize('sample')

importlib_metadata/__init__.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
'DistributionFinder',
4747
'PackageMetadata',
4848
'PackageNotFoundError',
49+
'PackagePath',
4950
'MetadataNotFound',
5051
'SimplePath',
5152
'distribution',
@@ -467,7 +468,7 @@ def from_name(cls, name: str) -> Distribution:
467468
try:
468469
return next(iter(cls._prefer_valid(cls.discover(name=name))))
469470
except StopIteration:
470-
raise PackageNotFoundError(name)
471+
raise PackageNotFoundError(name) from None
471472

472473
@classmethod
473474
def discover(
@@ -961,8 +962,15 @@ def __init__(self, name: str | None):
961962
def normalize(name):
962963
"""
963964
PEP 503 normalization plus dashes as underscores.
965+
966+
Specifically avoids ``re.sub`` as prescribed for performance
967+
benefits (see python/cpython#143658).
964968
"""
965-
return re.sub(r"[-_.]+", "-", name).lower().replace('-', '_')
969+
value = name.lower().replace("-", "_").replace(".", "_")
970+
# Condense repeats
971+
while "__" in value:
972+
value = value.replace("__", "_")
973+
return value
966974

967975
@staticmethod
968976
def legacy_normalize(name):

tests/test_api.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from importlib_metadata import (
77
Distribution,
88
PackageNotFoundError,
9+
Prepared,
910
distribution,
1011
entry_points,
1112
files,
@@ -317,3 +318,34 @@ class InvalidateCache(unittest.TestCase):
317318
def test_invalidate_cache(self):
318319
# No externally observable behavior, but ensures test coverage...
319320
importlib.invalidate_caches()
321+
322+
323+
class PreparedTests(unittest.TestCase):
324+
@fixtures.parameterize(
325+
# Simple
326+
dict(input='sample', expected='sample'),
327+
# Mixed case
328+
dict(input='Sample', expected='sample'),
329+
dict(input='SAMPLE', expected='sample'),
330+
dict(input='SaMpLe', expected='sample'),
331+
# Separator conversions
332+
dict(input='sample-pkg', expected='sample_pkg'),
333+
dict(input='sample.pkg', expected='sample_pkg'),
334+
dict(input='sample_pkg', expected='sample_pkg'),
335+
# Multiple separators
336+
dict(input='sample---pkg', expected='sample_pkg'),
337+
dict(input='sample___pkg', expected='sample_pkg'),
338+
dict(input='sample...pkg', expected='sample_pkg'),
339+
# Mixed separators
340+
dict(input='sample-._pkg', expected='sample_pkg'),
341+
dict(input='sample_.-pkg', expected='sample_pkg'),
342+
# Complex
343+
dict(input='Sample__Pkg-name.foo', expected='sample_pkg_name_foo'),
344+
dict(input='Sample__Pkg.name__foo', expected='sample_pkg_name_foo'),
345+
# Uppercase with separators
346+
dict(input='SAMPLE-PKG', expected='sample_pkg'),
347+
dict(input='Sample.Pkg', expected='sample_pkg'),
348+
dict(input='SAMPLE_PKG', expected='sample_pkg'),
349+
)
350+
def test_normalize(self, input, expected):
351+
self.assertEqual(Prepared.normalize(input), expected)

0 commit comments

Comments
 (0)