gh-148941: Skip generating __init__, __repr__, __eq__ when class already defines them#153601
Open
q121212 wants to merge 1 commit into
Open
gh-148941: Skip generating __init__, __repr__, __eq__ when class already defines them#153601q121212 wants to merge 1 commit into
q121212 wants to merge 1 commit into
Conversation
…s already defines them When @DataClass(init=True) is applied to a class that already defines __init__ in its own __dict__, the generated __init__ is always discarded by _set_new_attribute. However, _init_fn was still called unconditionally, and its field-ordering validation raised TypeError for inherited fields with defaults followed by fields without. Add '__x__' not in cls.__dict__ guards to the if init:, if repr:, and if eq: blocks in _process_class. Methods with 'raise' cells in the design tables (order, frozen) are intentionally NOT skipped early.
|
Most changes to Python require a NEWS entry. Add one using the blurb_it web app or the blurb command-line tool. If this change has little impact on Python users, wait for a maintainer to apply the |
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.
gh-148941: Skip generating init, repr, eq when class already defines them
Bug
When
@dataclass(init=True)(the default) is applied to a class thatalready defines
__init__in its own__dict__, the generated__init__is always discarded by_set_new_attribute. However,_init_fnwas still called unconditionally, and its field-orderingvalidation raised
TypeErrorwhen inherited fields with defaults werefollowed by fields without defaults:
The docs state: "If the class already defines
__init__(), thisparameter is ignored." The design tables at the top of
Lib/dataclasses.pyalso document this as the intended behaviour:for all of
__init__,__repr__, and__eq__, the cell whereparameter=Trueandclass has method in __dict__is intentionallyblank (= no action).
Fix
Add
'__x__' not in cls.__dict__guards to theif init:,if repr:,and
if eq:blocks in_process_class. This skips the generation(and its validation) entirely when the class's own method would have
been preserved by
_set_new_attributeanyway.Methods with 'raise' cells in the design tables (
order,frozen)are intentionally NOT skipped early — their existing
TypeError-on-overwrite behaviour is correct.Tests
test_skip_methods_when_defined.pyadded toLib/test/test_dataclasses/covering:
__init__: base with default + child without default (the exactreproducer from dataclass tries to generate
__init__()even though the class already defines one #148941), default_factory variant, KW_ONLY variant,three-level inheritance chain
__init__: NOT skipped when only a base class defines it (onlycls.__dict__matters)__repr__: skipped when custom__repr__defined__eq__: skipped when custom__eq__definedorder/frozen: still raiseTypeError(raise cells untouched)All existing dataclasses tests continue to pass.
NEWS
Misc/NEWS.d/next/Library/...rstadded.