cattrs icon indicating copy to clipboard operation
cattrs copied to clipboard

Better Union resolution

Open DLumi opened this issue 10 months ago • 3 comments

  • 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.

DLumi avatar Aug 30 '23 08:08 DLumi