Open
Description
from typing import Final
from dataclasses import dataclass, field
@dataclass
class Foo:
a: Final[int] = field(init=False) # no error
Foo().a # runtime error
related: #13118
from typing import Final
from dataclasses import dataclass, field
@dataclass
class Foo:
a: Final[int] = field(init=False) # no error
Foo().a # runtime error
related: #13118
Activity
odesenfans commentedon Jul 16, 2022
There is no error either when the member is not final. IMO the whole premise is dubious when it comes to OO, having a parameter that you cannot initialize through the constructor and that has no value will result in an incomplete object.
The solution could be to reject fields where
init=False
and the user does not specify a default value.odesenfans commentedon Jul 16, 2022
Just checked, the error also occurs for normal classes:
DetachHead commentedon Jul 16, 2022
i guess that's the same issue as #686
odesenfans commentedon Jul 16, 2022
I don't think it is, this issue has to do with mypy being unable to determine if this variable can be initialized.
I tried to fix this issue but it seems not trivial to resolve properly. Use cases like the one below show that the field can be initialized in methods like
__post_init__
.JukkaL commentedon Jul 16, 2022
What if we'd only flag the error if there is no
__post_init__
? It's not used very commonly, so we might still be able to handle a decent fraction of all use cases.odesenfans commentedon Jul 17, 2022
I checked, but there are other use cases like this one:
which are considered legitimate code (here: overriding
__init__
in the dataclass). I don't know how easy/hard it is to check inside__init__
and__post_init__
to see if attributes are correctly assigned.jakezych commentedon Dec 6, 2022
Hi! I'm interested in working on this issue. I've spent some time trying to familiarize myself with
dataclasses.py
anddefault.py
as I think this is where most of the implementation would be.I'm thinking that in
collect_attributes
, we extract theinit
argument and its value inis_in_init
, but I'm not exactly sure where we can access all of the statements belonging to the__init__
or__post_init__
method to check if the attribute is actually being initialized. Would that also be in the for loop on line 415?Also, I'm also not exactly sure where the actual error would get thrown. I noticed that
Plugin
base class has a methodget_attribute_hook
which could be implemented indefault.py
to return a new callback method written indataclasses.py
that could throw the error when an attribute that has not been initialized is accessed. Is this the right idea?I'm new to this project so any guidance on this issue would be super helpful, thank you!
KotlinIsland commentedon Dec 6, 2022
@odesenfans I think the difference is that in the OP
Final
is used, in your examples you are omitting theFinal
.I found another case of high suspicion:
This error is a sus imposter false positive.
5 remaining items