Skip to content

GenConverter.register_unstructure_hook fails with recursive unstructure_attrs_asdict #118

@spookylukey

Description

@spookylukey
  • cattrs version: 1.1.2, master
  • Python version: 3.9
  • Operating System: Linux

Description

I was trying to use register_unstructure_hook to add a handle that does normal asdict style unstructuring, plus adds an extra field (a type tag). I found that it worked the first time, but subsequent execution fails.

Test case:

import attr
import cattr

converter = cattr.GenConverter()


@attr.s
class C:
    a: int = attr.ib(default=1)


def handler(obj):
    return {
        'type_tag': obj.__class__.__name__,
        **converter.unstructure_attrs_asdict(obj)
    }


converter.register_unstructure_hook(C, handler)

inst = C()

expected = {'type_tag': 'C', 'a': 1}

unstructured1 = converter.unstructure(inst)
unstructured2 = converter.unstructure(inst)

assert unstructured1 == expected, repr(unstructured1)
assert unstructured2 == unstructured1, repr(unstructured2)

You see it fails on the final assertion, not the first i.e. the second call behaves differently from the first, which was very surprising.

I found that I'm possibly "doing it wrong" - if I use cattr.global_converter.unstructure_attrs_asdict instead of converter.unstructure_attrs_asdict I get the intended behaviour. It's not clear to me if this is a bug or something that needs to be added to the documentation.

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