cattrs
cattrs copied to clipboard
Better Union resolution
- cattrs version: 23.1.2
- Python version: 3.10.6
- Operating System: Win 10
Description
Right now I'm looking to migrate from dataclass + dacite to attrs + cattrs, but there's a feature in dacite that I miss in cattrs: consequtive resolution of Unions. What dacite does is that it takes each type in the Union and tries to match it to the data. If nothing is matched - the error is raised. This behavior seemed pretty intuitive for me.
However, if cattrs meets even a really basic Union like Union[str, int, float]
and data like '123'
it will pretend it doesn't know how to deal with this one, even if the resolution is really straightforward. Yes, you can probably write a hook for that, but manually describing each Union is really undesirable and error-prone. Maybe hook factory solves this, but I'm still figuring this stuff out, and my idea is that this should not be as complicated as it is right now.
What I Did
from attrs import define
from cattrs import structure
from enum import Enum
from typing import Union
c = structure('123', Union[str, int, float])
# Expected behavior: '123'
# Actual behavior: cattrs.errors.StructureHandlerNotFoundError: Unsupported type: typing.Union[str, int, float]. Register a structure hook for it.
@define
class C:
foo: str
c = structure({'foo': 'bar'}, Union[C, dict])
# Expected behavior: C(foo='bar')
# Actual behavior: cattrs.errors.StructureHandlerNotFoundError: Unsupported type: typing.Union[__main__.C, dict]. Register a structure hook for it.
class Foo(Enum):
BAR = 'Bar'
c = structure('Bar', Union[Foo, str])
# Expected behavior: Foo.BAR
# Actual behavior: cattrs.errors.StructureHandlerNotFoundError: Unsupported type: typing.Union[__main__.Foo, str]. Register a structure hook for it.