Restrict type inference of dataclass attributes. #1130
Merged
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.
Steps
Description
The change in #1126 used type annotations to infer
Instance
values for instance attributes of dataclasses:https://github.com/PyCQA/astroid/blob/f5f1125e31b85f2c2002189c8ad95a691fd56c83/astroid/brain/brain_dataclasses.py#L82-L111
This works well for most types, but type annotations from
typing
are different: they don't exactly represent new classes themselves, but really are "hints" about what the type of a variable should be. But the current code isn't aware of this, and so createsInstance
s of these type annotation classes.For generic collection types like
typing.List
, this isn't an issue, since astroid proxies these to the corresponding built-in collection (likelist
), seeastroid/brain/brain_typing.py
(I think, haven't looked into the details). But for other types this is an issue, since 1-to-1 proxying doesn't always make sense.In #1129, an attribute is inferred to be an
Instance of typing.Callable
, but that class doesn't have a__call__
method, leading to anot-callable
pylint error. This caused a regression because the previously-inferred value,Uninferable
, was more permissive and caused pylint to skip these kinds of typechecks.So for now I've created an allowed list of typing types for which astroid support inference, and currently included only the generic collection types. All other type annotations from
typing
will revert to yieldingUninferable
.You'll also note that I've pulled out the type annotation inference code into a separate protected function, but left it in
brain_dataclasses.py
. It could be made public, extended, and used more generically, but... I didn't want to rock the boat, so leaving that discussion to later. 😅More testing
On the pylint side, all of the typecheck checkers should include a new cases for dataclass attributes, which are using this new approach. Hopefully to prevent new regressions like #1129 in the future. I can work on this later, but I think I'm going to take some time off astroid/pylint after this immediate issue gets resolved.
Type of Changes
Related Issue
Closes #1129