python-attrs / python-attrs/cattrs
Better Union resolution
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 1.1k
- Forks
- 159
- Avg merge
- 12h 21m
- Merged PRs (30d)
- 6
Description
- 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.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with cattrs.structure and reproduce the three Union examples from the issue using the stated Python and cattrs versions. Compare the results with the expected consecutive resolution for str/int/float, attrs class/dict, and Enum/str inputs. Done means these examples resolve as described and unsupported Union inputs still raise an appropriate error.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100