-
-
Notifications
You must be signed in to change notification settings - Fork 113
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
Register Hooks for Generic Classes #216
Comments
You got it right. So then you use the |
OK very nice! However, to make it easier for other users: Usually in cattrs, when you un-/structure a certain class and this class does not have an un-/structure hook itself, but its parent, cattrs will use the un-/structure of the parent. cattrs could be designed in that way that it sees def main3() -> None:
print("•••• direct ••••")
converter.unstructure(MyClass())
converter.structure("hello1", MyClass)
print("•••• With str ••••")
converter.unstructure(MyClass[str]()) # Do call MyClass.serialize()
converter.unstructure(MyBase(a=MyClass[str]())) # Do call MyClass.serialize()
converter.structure("hello3", MyClass[str]) # Do call MyClass.deserialize()
if __name__ == '__main__':
converter.register_structure_hook(MyClass, MyClass.deserialize)
converter.register_unstructure_hook(MyClass, MyClass.serialize)
main3() I do not know so much about |
Problem of this issue also described here #87 |
I also just hit this, with an attribute of type
The workaround was to do this (i already had the issubclass_safe function): def issubclass_safe(sub: Any, sup: type) -> bool:
if typing.get_origin(sub) is not None:
# is an instantiation of a generic type, so compare also the unparameterized type
if issubclass_safe(typing.get_origin(sub), sup):
return True
# check if sub is actually a class, otherwise issubclass throws
return inspect.isclass(sub) and issubclass(sub, sup)
_converter.register_structure_hook_func(
lambda t: issubclass_safe(t, Foo), But in my opinion cattrs should use |
I want to register structure/unstructure hooks for classes which inherit
typing.Generic
and using aT = typing.TypeVar('T')
, i.e.MyClass(typing.Generic[T])
– so that the structure/unstructure hooks are called whenMyClass
is used with a concrete type, for exampleMyClass[str]
.In the code box below you can see an example in the function
main1()
about that. So the question is: Is there an intended correct way to register structure/unstructure hooks for Generic Classes?I currently make use of
register_structure_hook_func
and check the correct condition myself. The statementMyClass[str]
will generate antyping._GenericAlias
instance which__origin__
arrtribute holds a reference to the classMyClass
, which is the condition I check.Output:
The reason why
converter.register_structure_hook(MyClass[T], MyClass.deserialize)
is probably howtyping._GenericAlias
defines__eq__
and__hash__
, i.e two of them are only equal when both__origin__
and all args (above this isT
vs.str
) are equal :The text was updated successfully, but these errors were encountered: