Keep every base's slots under multiple inheritance - #180
Merged
Merged
Conversation
…eritance-slots Fix DataClassNode slot accumulation under multiple inheritance
The slot accumulation added in the previous commit was written against an earlier `__init_subclass__`, where `ancestors` was in plain `__mro__` order and had to be reversed to merge annotations base-first. PR #166 has since rebuilt that list from `reversed(cls.__mro__)`, so it already arrives base-first and reversing it again inverted the merge order: a diamond `class D(B, C)` produced slots in `B`-then-`C` order rather than the declaration order the ancestors imply. Because none of the edited lines overlapped, the change applied cleanly on top of #166 while its meaning changed underneath it, and the accompanying test failed on the merge commit. Deriving `_SLOTS` from the merged annotations also left `new_slots` written but never read. Ruff does not report it, because `new_slots.append(...)` counts as a reference for F841. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GypKU5KdLfs2Cf8kS2TzJa
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.
Closes #173.
Builds on @Liyu0310-Code's work in #175, which was merged into this branch so their commit is carried over intact, and finishes it.
The bug
DataClassNode.__init_subclass__accumulated slots by reading the inherited_SLOTS/_SLOT_ANNOTATIONSattributes, which resolve through the MRO to only the first inheritance chain. Under diamond inheritance the slots of every base after the first were silently dropped, soitems(),__iter__,to_obj()and the hash all ignored them, and constructing the class failed with a misleadingTypeError: object.__init__() takes exactly one argument.The fix collects annotations from every data-class ancestor and derives
_SLOTSfrom the merged mapping. The reproducer in #173 now gives:What this branch corrects
df537d6fixes two things in the merged change:The ancestors were iterated in the wrong order. The slot merge was written against an earlier
__init_subclass__, whereancestorswas in plain__mro__order and had to be reversed to merge base-first. #166 has since rebuilt that list fromreversed(cls.__mro__), so it already arrives base-first, and reversing it again inverted the merge order — a diamondclass D(B, C)came out inB-then-Corder. None of the edited lines overlapped with #166's, so the change applied cleanly while its meaning changed underneath it, andtest_multiple_inheritancefailed on the merge commit. The test itself was right; only the implementation disagreed with it.new_slotshad become dead. Once_SLOTSis derived from the merged annotations, the list is written but never read. Ruff does not report it:F841wants a local that is never referenced, andnew_slots.append(...)counts as a reference.Validation
test_multiple_inheritancefails ond7c0f6a(the merge of Fix DataClassNode slot accumulation under multiple inheritance #175) and passes here. Reinstating the extrareversed()reproduces the failure on this branch, so the test is pinned to the defect rather than passing incidentally.uv run --frozen --extra dev pytest— 175 passed, 19 subtestsuv run --frozen --extra dev ruff check graphtage test docs bindist— cleanuv run --frozen --extra dev make -C docs html SPHINXOPTS="-W --keep-going"— build succeededThe full suite passing matters here beyond the new test: every in-tree
DataClassNodeis constructed positionally by its builder, so a change to_SLOTSordering would surface as widespread failures rather than quietly.🤖 Generated with Claude Code
https://claude.ai/code/session_01GypKU5KdLfs2Cf8kS2TzJa