`asdict` does not work with `field(init=False)`
I'm not sure if this is intended behavior or not but it definitely confused me, so maybe someone can help me understand it better.
Here's a simple example
from attrs import define, asdict
@define
class Coords:
x = attr.ib(type=int)
y = attr.ib(type=int, init=False)
asdict(Coords(x=1))
and it results with and attribute error
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Input In [67], in <cell line: 6>()
3 x = attr.ib(type=int)
4 y = attr.ib(type=int, init=False)
----> 6 asdict(Coords(x=1))
File ~/anaconda3/lib/python3.9/site-packages/attr/_next_gen.py:198, in asdict(inst, recurse, filter, value_serializer)
191 def asdict(inst, *, recurse=True, filter=None, value_serializer=None):
192 """
193 Same as `attr.asdict`, except that collections types are always retained
194 and dict is always used as *dict_factory*.
195
196 .. versionadded:: 21.3.0
197 """
--> 198 return _asdict(
199 inst=inst,
200 recurse=recurse,
201 filter=filter,
202 value_serializer=value_serializer,
203 retain_collection_types=True,
204 )
File ~/anaconda3/lib/python3.9/site-packages/attr/_funcs.py:57, in asdict(inst, recurse, filter, dict_factory, retain_collection_types, value_serializer)
55 rv = dict_factory()
56 for a in attrs:
---> 57 v = getattr(inst, a.name)
58 if filter is not None and not filter(a, v):
59 continue
AttributeError: y
however I would expect to a dict with {"x": 1}. I appreciate some input on this.
As far as attrs is concerned, the y attribute does exist – it's just not our job to initialize it.
Thanks @hynek, would it be interesting to update asdict to return only initialized parameters by default or add a flag to expose an option to get all or init parameters only?
I'm thinking about sth like
addict(instance, init_only=True)
I'm happy to put in a PR if you're open to that.
The real question here is why would you declare a field that doesn't exist? This is a very special case and goes into serialization-framework territory.