-
-
Notifications
You must be signed in to change notification settings - Fork 129
Closed
Labels
Description
I'm using cattrs==25.3.0, and I'm trying to use a Union with subtypes that have aliases. I cannot get either the use_alias input in Converter nor the make_dict_structure_fn method [mentioned here] to correctly resolve non-conflicting union types while still using the alias. Union types without aliases work just fine. Lists (and presumably dict values) of some type with use_alias also work.
Is there another way this can/should be configured to make it work as I had expected? Is my expectation correct?
from attrs import define, field, has
from cattrs import Converter, gen
@define
class Cat:
cat_name: str = field(alias="catName")
@define
class Dog:
dog_name: str = field(alias="dogName")
@define
class Apartment:
pet: Cat | Dog
c0 = Converter()
c1 = Converter(use_alias=True)
c2 = Converter()
c2.register_structure_hook_factory(
has,
lambda cl: gen.make_dict_structure_fn(cl, c2, _cattrs_use_alias=True)
)
def structure(data, cls):
print("")
for (c, prefix) in (
(c0, "default "),
(c1, "use_alias "),
(c2, "hook_factory")
):
result = None
try:
result = c.structure(data, cls)
except Exception as ex:
result = type(ex)
print(f"{prefix} structure({data}, {cls.__name__}) == {result}")
snake_dog = dict(dog_name="snake")
camelDog = dict(dogName="camel")
snake_cat = dict(cat_name="snake")
camelCat = dict(catName="camel")
structure(dict(pet=snake_dog), Apartment)
structure(dict(pet=camelCat), Apartment)with output below. I expected use_alias and hook_factory to work with camelCat.
default structure({'pet': {'dog_name': 'snake'}}, Apartment) == Apartment(pet=Dog(dog_name='snake'))
use_alias structure({'pet': {'dog_name': 'snake'}}, Apartment) == <class 'cattrs.errors.ClassValidationError'>
hook_factory structure({'pet': {'dog_name': 'snake'}}, Apartment) == <class 'cattrs.errors.ClassValidationError'>
default structure({'pet': {'catName': 'camel'}}, Apartment) == <class 'cattrs.errors.ClassValidationError'>
use_alias structure({'pet': {'catName': 'camel'}}, Apartment) == <class 'cattrs.errors.ClassValidationError'>
hook_factory structure({'pet': {'catName': 'camel'}}, Apartment) == <class 'cattrs.errors.ClassValidationError'>