Skip to content

Prefer the greater metadata directory when a path supplies several - #550

Open
jaraco wants to merge 1 commit into
mainfrom
feature/cpython-100666-prefer-greater-version
Open

jaraco wants to merge 1 commit into
mainfrom
feature/cpython-100666-prefer-greater-version

Conversation

@jaraco

@jaraco jaraco commented Oct 21, 2026

Copy link
Copy Markdown
Member

Addresses python/cpython#100666.

An unclean upgrade can leave a stale .dist-info beside the installed one. Lookup builds its per-name buckets straight from os.listdir, whose order is arbitrary, so which of the two answered version('torch') was a matter of chance.

Lookup.__init__ now considers the children in reverse lexicographic order (case-insensitively), the ordering preferred in the issue discussion. Because the buckets are built in that order and Distribution._prefer_valid partitions stably, the composition is: valid distributions first, and among those, the greater directory name first.

The sort lives in Lookup rather than FastPath.children() so that zip-backed children, which come back as a dict, are covered too.

Limitation

The ordering is lexicographic on the directory name, not on the parsed version, so foo-1.9.0 still sorts above foo-1.13.1. It therefore only approximates a preference for the newer version and won't resolve every instance of the reported condition. Parsing versions would require a version parser unavailable to the stdlib, so this is the heuristic on offer; the Lookup.__init__ docstring says so plainly rather than letting the change imply more than it delivers.

Tests

MultipleVersionsTests uses versions chosen so that lexicographic and version order disagree, which both exercises the heuristic and documents its limit:

  • test_greater_version_preferred — retrieval by name resolves to the greatest
  • test_discovery_order — the full discovered sequence, so preferring one doesn't hide the rest
  • test_greater_version_preferred_in_eggs — the same for legacy .egg-info
  • test_validity_preferred_to_version — a valid older distribution still beats an invalid newer one, the exact condition in the report (regression guard for Ensure stale empty python module directories don't break the build #489)

The first three fail with the sort reverted. An earlier two-version form of them passed without the fix by luck of the APFS listing order, hence the four versions and the exact-sequence assertion.

tox passes locally: 225 tests, mypy and ruff clean, perf within noise. Run with --ignore=.claude, as a stale git worktree under .claude/worktrees/ in my checkout gets collected by pytest and breaks the run independently of this change.

🤖 Generated with Claude Code

An unclean upgrade can leave a stale `.dist-info` beside the installed
one, and because the order of `os.listdir` is arbitrary, which of them
answered a query was a matter of chance. Consider the children in
reverse lexicographic order so the greater one is found first.

The ordering is lexicographic on the directory name and not on the
parsed version, so it only approximates a preference for the newer
version, but it needs no version parser and so is available to the
stdlib.

Ref python/cpython#100666.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant