Backport PR #57 on branch versions/v0.4.x (🐛 fix: stop members with equal values collapsing into aliases) - #59
Merged
nstarman merged 1 commit intoAug 7, 2026
Conversation
…s collapsing into aliases (cherry picked from commit 378e466) Two adjustments were needed; the rest applied unchanged. `_MemberKey` is written out here instead of the `@dataclass(frozen=True, slots=True, eq=False, repr=False)` used on `main`: this branch supports Python 3.9, where `dataclass` has no `slots` parameter. `main` only recently moved to the dataclass form, so this is that same class one revision back, not new code. The generated `__eq__` had to be disabled on `main` regardless -- comparing by field is precisely the aliasing the class prevents -- so little is lost. The import line conflicted: this branch takes `Callable` from `typing` rather than `collections.abc`, kept as-is with the new names added alongside. Ruff dropped the quotes from `_missing_`'s return annotation, which are redundant under this branch's `from __future__ import annotations`, and two comments naming 3.10 as the floor now say 3.9. Verified on 3.9 and 3.13 (this branch's CI matrix) plus 3.10-3.12: 51 passed, 100% coverage, `nox -s lint` clean. 3.9's `enum` honours a `_value_` set in `__new__` before the duplicate scan, same as later versions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## versions/v0.4.x #59 +/- ##
===================================================
Coverage ? 100.00%
===================================================
Files ? 3
Lines ? 100
Branches ? 0
===================================================
Hits ? 100
Misses ? 0
Partials ? 0 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Manual backport of #57 to
versions/v0.4.x, per the MrMeeseeks instructions on that PR (the automated cherry-pick conflicted).Fixes
enum.Enumfolding members with equal values into aliases. Two collision modes, both silent: any two uninstalled dependencies share theNOT_INSTALLEDsentinel, and distributions released together share a version number. The surviving member then answers.installed/.versionfor the wrong package.Differences from
main_MemberKeyis written out rather than a dataclass.mainuses@dataclass(frozen=True, slots=True, eq=False, repr=False), but this branch supports Python 3.9, wheredataclasshas noslotsparameter. This is the same class one revision earlier onmain, not new code —mainonly moved to the dataclass form after the original review. Little is lost: the generated__eq__had to be disabled there anyway, since comparing by field is exactly the aliasing this class exists to prevent.Import line. This branch takes
Callablefromtypingrather thancollections.abc; kept as-is, with the new names added alongside. That was the cherry-pick conflict.Two follow-on tidies. Ruff dropped the quotes from
_missing_'s return annotation (redundant under this branch'sfrom __future__ import annotations), and two comments naming 3.10 as the version floor now say 3.9.Everything else applied unchanged.
Verification
nox -s lint(pre-commit, pylint, mypy)3.9's
enumhonours a_value_set in__new__before the duplicate scan, same as later versions — which is what makes the fix portable this far back.Milestone
v0.4.xset. TheStill Needs Manual Backportlabel on #57 should come off once this merges.🤖 Generated with Claude Code