Skip to content

prefer_attrib_converters doesn't work when the field is aliased #527

@ljnsn

Description

@ljnsn
  • cattrs version: 23.2.3
  • Python version: 3.11
  • Operating System: Linux

Description

I want to use the converter set on a field of an attrs model of mine. The field also has an alias. Trying to structure with cattrs doesn't work in this case.

What I Did

import enum
from typing import Any, Callable, Mapping

import attrs
import cattrs
from cattrs.gen import make_dict_unstructure_fn, make_dict_structure_fn


class X(enum.Enum):
    A = "a"
    B = "b"
    OTHER = "other"


def _x_or_other(value: Any) -> X:
    try:
        return X(value)
    except ValueError:
        return X.OTHER


@attrs.define()
class Bar:
    x: X = attrs.field(converter=_x_or_other, alias="Y")


converter = cattrs.Converter(prefer_attrib_converters=True)


def _to_alias_unstructure(cls: type[Any]) -> Callable[[Any], dict[str, Any]]:
    """Unstructure hook using alias."""
    return make_dict_unstructure_fn(
        cls,
        converter,
        _cattrs_use_alias=True,
    )


def _to_alias_structure(
    cls: type[Any],
) -> Callable[[Mapping[str, Any], Any], Callable[[Any, Any], Any]]:
    """Structure hook using alias."""
    return make_dict_structure_fn(
        cls,
        converter,
        _cattrs_use_alias=True,
    )


converter.register_unstructure_hook_factory(attrs.has, _to_alias_unstructure)
converter.register_structure_hook_factory(attrs.has, _to_alias_structure)

bar1 = {"Y": "a"}
bar2 = {"Y": "whatever"}

converter.structure(bar1, Bar)  # works
converter.structure(bar2, Bar)  # fails

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