attr'd classes don't have default attributes?
Today I stumbled over this one:
from attrs import define,field
from dataclasses import dataclass
@define
class N1:
foo:int|None = field(default=None)
class N2:
foo:int|None = None
def __init__(self, foo):
self.foo = 123
@dataclass
class N3:
foo:int|None = None
n3 = N3(foo=123)
del n3.foo
assert n3.foo is None
n2 = N2(foo=123)
del n2.foo
assert n2.foo is None
n1 = N1(foo=123)
del n1.foo
n1.foo # AttributeError
This is not what I'd expect when I decide to attrs-ize an existing class. Thus please either fix this, or add a reasonably prominent section that documents this (and other possible pitfalls) to the manual.
This has nothing to do with default arguments; what you're accessing there are class variables.
To be concrete: you're deleting the instance field n2.foo and therefore get N2.foo.
I'll have to have a closer look at what exactly happens there. We do some class sanitization (due to pre-typing attr.s/attr.ib times) and I'm not 100% sure how we handle class vars for slotted classes – we'll have to investigate how much of this is on purpose.
N.B. switching the DC example to slots makes it fail too:
@dataclasses.dataclass(slots=True)
class N3:
foo: int | None = None
n3 = N3(foo=123)
del n3.foo
print(n3.foo) # AttributeError: 'N3' object has no attribute 'foo'
This has nothing to do with default arguments; what you're accessing there are class variables.
Sure. I know. Sorry for being kindof sloppy expressing myself.
Thanks for looking into this. Even if you ultimately decide it's on purpose, having a chance to discover this issue by R'ing TFM instead of a lengthy debugging session would be helpful.