Skip to content

Weird output while structuring unions with custom disambiguation function #267

Open
@pritsh

Description

@pritsh
  • cattrs version: 22.1.0
  • Python version: 3.9

Description

Thanks for this amazing library !!

I am trying to write disambiguation function to handle union type based on the default value of child class but got into weird error, also want to understand the correct way to do it with cattrs.

@define(kw_only=True)
class GenType:
    pass

@define(kw_only=True)
class TypeOne(GenType):
    id:Literal["A"] = "A"


@define(kw_only=True)
class TypeTwo(GenType):
   id:Literal["B"] = "B"

UniType = Union[TypeOne, TypeTwo]

@define(kw_only=True)
class Container:
    types: List[UniType]

def discriminate_model_types(value: typing.Any, _klass: typing.Type) -> UniType:
    # Write some logic to find the exact type !!, I was wondering if there is correct pythonic version to do this with cattrs.
    for child_cls in GenType.__subclasses__():
        if value["id"] == child_cls().id:
            return cattr.structure(value, child_cls)

def run_union_logic():
    json = {"types":[{"id":"A"}]}
    cattr.register_structure_hook(UniType, discriminate_model_types)
    obj =cattr.structure(json, Container)
    print(obj)

    json = {"id": "A"}
    obj = cattr.structure(json, TypeOne)
    print(obj)

#Prints following:
#Container(types=[TypeOne()]) --> I dont know why property 'id' is not populated here. 
#TypeOne(id='A') 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions