Repository navigation
Report final dataclass fields that are never initialized - #22314
Open
DipanshuAmbilkar03 wants to merge 2 commits into
Open
DipanshuAmbilkar03 wants to merge 2 commits into
DipanshuAmbilkar03 wants to merge 2 commits into
Conversation
A `Final` dataclass attribute can only be assigned inside `__init__()`. If the field is declared with `field(init=False)` and has neither a `default` nor a `default_factory`, nothing ever sets it, so reading the attribute fails with `AttributeError` at runtime. The `field(...)` call counted as an initializer, so the "Final name must be initialized with a value" check was skipped. Report the field instead when it is final, excluded from the generated `__init__()` and has no default value.
for more information, see https://pre-commit.ci
Contributor
|
According to mypy_primer, this change doesn't affect type check results on a corpus of open source code. ✅ |
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.
Fixes #13119
Summary
A
Finaldataclass field can only be assigned inside__init__(). If the field is declared withfield(init=False)and has neither adefaultnor adefault_factory, the generated__init__()never sets it, so the attribute is missing at runtime:mypy accepts this today, because the
field(...)call counts as an initializer and that is enough to skip the regular "Final name must be initialized with a value" check.Fix
While collecting dataclass attributes, I report a field when it is final, excluded from the generated
__init__()and has neither a default nor adefault_factory— that combination means nothing can ever assign the attribute.Fields with a default, plain
Finalfields that the generated__init__()sets, and fields of customdataclass_transformspecs keep the current behaviour.Test
testDataclassFinalFieldNotInInitintest-data/unit/check-dataclasses.testcovers the reported case plus the three shapes that must stay accepted:field(init=False, default=0),field(init=False, default_factory=int)and a plainFinal[int] = 0.Verification
pytest mypy/test/testcheck.py -k "Dataclass or dataclass"— 212 passed.pytest mypy/test/testfinegrained.py -k dataclass— 14 passed.python -m mypy --config-file mypy_self_check.ini -p mypy— clean.mypy/testsuite is running in CI as part of this PR.