-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes no error thrown for Final fields declared with init=False and not assigned inside __init__ #14285
base: master
Are you sure you want to change the base?
Conversation
This comment has been minimized.
This comment has been minimized.
From the mypy primer output it seems like you need to exclude class definitions in stub files from your check. |
I think I fixed the issue. Could someone rerun the workflows? |
This comment has been minimized.
This comment has been minimized.
I'll see if I can set up mypy primer locally to get a better idea of what's going wrong. |
I tested the changes locally on yarl and discord.py and it was not throwing the errors anymore. |
According to mypy_primer, this change has no effect on the checked open source code. 🤖🎉 |
If the mistake is in a third-party library, does it still show an error in my own code? So, for example:
from dataclasses import dataclass, field
from typing import Final
@dataclass
class C:
x: Final[int] = field(init=False)
def __post_init__(self) -> None:
self.y = 3 # typo here
from some_library import C
C().x # an error here? |
I'm silly and didn't read the difference between x and y. I do understand your main point here though, and I'll take a look at how my code handles errors in imported libraries. |
It does show errors from third-party libraries, I assume we want to suppress those? |
Nevermind actually, I realized that a lot of other mypy checks have the same problem. So it should be fine! |
This PR is going in the right direction, but it feels to me like the implementation is too complicated, especially considering this is a relatively minor edge case. In particular, iterating over the body of a function in the dataclass plugin is not the best way to approach this, and it seems to duplicate functionality in the semantic analyzer which will make things harder to maintain and understand. Also I'd prefer it |
Fixes #13119
For all final field assignments to class variables in a dataclass i.e.
x: Final[int] = field()
, this PR checks whether this field is being properly assigned in the__init__
or__post_init__
methods. In the case where the field has the argumentinit=True
, no error is thrown if the field is assigned inside__init__
or__post_init__
which was previously a false positive. This addresses the last example given in the issue thread.In the case where the field has the argument
init=False
and it is not being assigned in__init__
or__post_init__
, on the line where it is a declared, the error "Final name must be initialized with a value" is now thrown. A new error was added and is thrown if that same field is accessed through the class "Final field "a" not set". This addresses the original false negative given in the issue thread.Tests Added (all in
check-dataclasses.test
):testErrorFinalFieldNoInitNoArgumentPassed
testNoErrorFinalFieldDelayedInit
testErrorFinalFieldInitNoArgumentPassed
testFinalFieldGeneratedInitArgumentPassed
testFinalFieldInit
testFinalFieldPostInit
testFinalDefiningNoRhs in
check-final.test
was modified to now throw the new error when an unset final attribute is accessed