Class fields and instance fields behavior
Hello, Patrick
currently, data classes allow fields to be either class or instance variables for example
@dc.dataclass
class Test:
a:int = 1
def __init__(self) -> None:
pass
Test().__dict__ # {}
Test.__dict__['a'] # 1 -> class variable
I think it is better to log a warning or to raise an uninitialized field error to disallow this behavior. As the user might be under the impression that a is a parameter of the Test instance (as shown in the Test repr ) while it's not.
Hmm, that's an interesting edge-case.
Probably the fix is to adjust this check to use in self.__dict__ instead of in dir(self)?
I could see this change having some unintended consequences -- it'd be worth running the Diffrax test suite against such a change as a test to see what happens.
I think maybe you don't need to check for if field.init , AFAIK the field should be initialized at that point of your code, even if init=False.
So that line could be something like this, missing_names = set(self.__dataclass_fields__)-set(vars(self))
To add on this issue, I think dataclasses has asymmetric handling for defaults.
For example this code does not raise any error and assign a as class var
import dataclasses as dc
@dc.dataclass
class Test:
a:int = dc.field(default=1)
def __init__(self) -> None:
pass
Test() # Test(a=1)
But this code raises an error
@dc.dataclass
class Test:
a:int = dc.field(default_factory=lambda: 1)
def __init__(self) -> None:
pass
Test() # AttributeError
Yep, agreed.