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
10 changes: 1 addition & 9 deletions importlib_metadata/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -922,22 +922,14 @@ def __init__(self, path: FastPath):
From the children in the path, calculate early all of the
children that appear to represent metadata (infos) or legacy
metadata (eggs).

Children are considered in reverse lexicographic order, so when
a path supplies more than one metadata directory for a
distribution, as an interrupted or unclean upgrade may leave
behind, the greater one is found first
(python/cpython#100666). Because the order is lexicographic on
the directory name and not on the parsed version, it only
approximates a preference for the newer version.
"""

base = os.path.basename(path.root).lower()
base_is_egg = base.endswith(".egg")
self.infos = FreezableDefaultDict(list)
self.eggs = FreezableDefaultDict(list)

for child in sorted(path.children(), key=str.lower, reverse=True):
for child in path.children():
low = child.lower()
if low.endswith((".dist-info", ".egg-info")):
# rpartition is faster than splitext and suitable for this purpose.
Expand Down
6 changes: 6 additions & 0 deletions newsfragments/+revert-prefer-greater-version.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Reverted the preference for the greater metadata directory added in v9.1.0.
The ordering was lexicographic on the directory name and not on the parsed
version, so it only approximated a preference for the newer version. Where a
path supplies more than one metadata directory for a distribution, discovery
once again reports them in the order the path supplies
(python/cpython#100666).
70 changes: 0 additions & 70 deletions tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,76 +208,6 @@ def test_missing_required_metadata(self):
unversioned.version


class MultipleVersionsTests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
"""
An unclean upgrade can leave more than one metadata directory for a
distribution in one path. Prefer the greater one.

Ref python/cpython#100666.
"""

# Deliberately not in version order; the preference follows the
# lexicographic ordering of the directory names, which only
# approximates the ordering of the versions they name.
versions = '1.12.1', '1.13.1', '1.9.0', '2.0.0'
expected = '2.0.0', '1.9.0', '1.13.1', '1.12.1'

@staticmethod
def make_pkg(name, version, files=None):
"""
Create metadata for a dist-info package at the indicated version.
"""
return {
f'{name}-{version}.dist-info': (
{'METADATA': f'Name: {name}\nVersion: {version}\n'}
if files is None
else files
),
}

def build_versions(self, *versions):
for ver in versions:
fixtures.build_files(self.make_pkg('foo', ver), self.site_dir)

def test_greater_version_preferred(self):
"""
Retrieving by name resolves to the greater version.
"""
self.build_versions(*self.versions)
assert version('foo') == self.expected[0]

def test_discovery_order(self):
"""
Preferring one version doesn't hide the others from discovery,
which reports them greatest first.
"""
self.build_versions(*self.versions)
found = tuple(dist.version for dist in Distribution.discover(name='foo'))
assert found == self.expected

def test_greater_version_preferred_in_eggs(self):
"""
Legacy egg-info metadata gets the same preference.
"""
fixtures.build_files(
{
f'foo-{ver}.egg-info': {'PKG-INFO': f'Name: foo\nVersion: {ver}\n'}
for ver in self.versions
},
self.site_dir,
)
assert version('foo') == self.expected[0]

def test_validity_preferred_to_version(self):
"""
A valid dist is still preferred to an invalid one of a greater
version, the condition that prompted the report.
"""
self.build_versions('1.12.1')
fixtures.build_files(self.make_pkg('foo', '2.0.0', files={}), self.site_dir)
assert version('foo') == '1.12.1'


class NonASCIITests(fixtures.OnSysPath, fixtures.SiteDir, unittest.TestCase):
@staticmethod
def pkg_with_non_ascii_description(site_dir):
Expand Down
Loading