-
-
Notifications
You must be signed in to change notification settings - Fork 118
kw_only tuple support? #234
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I don't think it'd be difficult at all, I'll put it on my radar. In the meantime, here's how you can solve the issue yourself: from attrs import fields, has
from cattrs import GenConverter
c = GenConverter()
def structure_kw_attrs_fromtuple(obj, cls):
conv_obj = {}
for a, value in zip(fields(cls), obj):
# We detect the type by the metadata.
converted = c._structure_attribute(a, value)
conv_obj[a.name] = converted
return cls(**conv_obj)
c.register_structure_hook_func(
lambda t: has(t) and any(a.kw_only for a in fields(t)),
structure_kw_attrs_fromtuple,
) >>> c.structure(('', 2), B)
B(a='', b=2) |
Hmm, using this produces Ahaha, it's running when I'm trying to convert from a dict. Is there a way to make this tuple only? Or should I just implement the dict process here too? |
Ah, the hook I gave you will run automatically for any attrs class that has at least one kw arg. If you don't need it to run automatically, skip |
Don't see anything immediately wrong with my snippet, can you prepare a small sample? |
I'd be fine with it running automatically, but I want to be able to support dicts and tuples. (That is, |
|
(And here's the requested sample to see what I was thinking) import attrs
import cattrs
@attrs.define(kw_only=True)
class A:
a: str = ""
@attrs.define(kw_only=True)
class B(A):
b: int
converter = cattrs.GenConverter()
def structure_kw_attrs_fromtuple(obj, cls):
conv_obj = {}
for a, value in zip(attrs.fields(cls), obj):
# We detect the type by the metadata.
converted = converter._structure_attribute(a, value)
conv_obj[a.name] = converted
return cls(**conv_obj)
converter.register_structure_hook_func(
lambda t: attrs.has(t) and any(a.kw_only for a in attrs.fields(t)),
structure_kw_attrs_fromtuple,
)
print(converter.structure_attrs_fromdict({"a": "hi", "b": 2}, B))
# print(converter.structure({"a": "hi", "b": 2}, B)) # Breaks when the above is added
# converter.structure_attrs_fromtuple(('', 2), B) # Doesn't work when adding the above... or before adding it :)
print(converter.structure(('', 2), B)) |
Do you need to support dicts and tuples in the same payload? If not, you can just have two converters. If yes, it gets a little complicated but can still be done. |
No, I'd be fine with only supporting |
Just curious, can I copy an existing converter (with copy.copy or something) and make a few more modifications? If I went with two converters, I'd want most of the initial setup the same. |
I would just instantiate the
You can't right now. I've had people request it though, so it's on the roadmap. It'll probably be a |
Thanks! Couldn't you implement |
Description
I have a nested data structure using attrs and
kw_only
. Converting to a tuple works beautifully, letting me load this structure into a SQLite3 database.However, the other direction fails:
My current workaround is a little ugly and possibly not very efficient:
Would it be possible to make
fromtuple
work on akw_only
class, likeastuple
does? IMO,kw_only
is about subclassing & controlling manual creation, not raw conversion.Might be hard/impossible, but thought I'd ask.
The text was updated successfully, but these errors were encountered: