Reputation: 65
I want to deserialize MongoDB documents using attr and cattrs. Since noSQL has no fixed schema, I need to point somehow to the attr.ib-s that they could be missed, and not add them to the dict's object in this case.
I used colander before to do this kind of things and it provides a 'missing' parameter in colander.SchemaNode constructor that do exactly this by passing 'colander.drop' as an argument. I'm wondering how to do the same with these libraries, I didn't find anything in the documentation. So:
import attr
from cattr import structure
@attr.s
class ABC:
A: float = attr.ib()
B: float = attr.ib()
C: float = attr.ib()
d = {'A': 1, 'B': 2}
obj = structure(d, ABC)
Should return an object with only A and B attributes. I've been trying with some parameters (init, default...) and even with Optional class from typing lib, but all of the methods I tried returned the attribute in some way.
Thanks for your help.
Upvotes: 0
Views: 3597
Reputation: 701
(I'm the author of cattrs and a core contributor to attrs.)
Hello,
an attrs Python class will, by definition, have all of its fields in the instance __dict__
. When you say the structuring "should return an object with only A and B attributes", I'm assuming you want the instance returned to throw AttributeError
when you try accessing obj.C
.
To my knowledge this isn't possible with attrs, and neither is it in the spirit of attrs. You've defined your class to have three attributes, so it should have values in those attributes.
What you can do is use None
as a value marker for a missing value; this is the usual way of representing missing values in Python generally. The code snippet becomes:
from typing import Optional
import attr
from cattr import structure
@attr.s
class ABC:
A: float = attr.ib()
B: float = attr.ib()
C: Optional[float] = attr.ib(default=None)
d = {'A': 1, 'B': 2}
obj = structure(d, ABC)
You wouldn't want code that expects an instance of ABC
to have to deal with mysteriously missing attributes, right?
Upvotes: 8