Skip to content

GenConverter's unstructure RecursionError with class with forwardRef #159

@johnwlockwood

Description

@johnwlockwood
  • cattrs version: 1.4.0
  • Python version: 3.9.1
  • Operating System: Mac OS Big Sur

Description

After something that worked with cattrs 1.3.0, raises a RecursionError with 1.4.0.
With an attrs class defined with forward referencing annotations, GenConverter's unstructure exceeds it's recursion depth.
I expected unstructure to turn an instance of a class into a dict.

What I Did

from __future__ import annotations
from typing import Optional, List
import attr
from cattr import GenConverter
unstructure = GenConverter().unstructure

@attr.s
class Node(object):
  name: str = attr.ib()
  nodes: List[Node] = attr.ib(default=attr.Factory(list))
 

n = Node("Bob", nodes=[Node("Jim")])

>>> d = unstructure(n)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/converters.py", line 153, in unstructure
    return self._unstructure_func.dispatch(
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/dispatch.py", line 47, in _dispatch
    return self._function_dispatch.dispatch(cl)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/dispatch.py", line 121, in dispatch
    return handler(typ)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/converters.py", line 645, in gen_unstructure_attrs_fromdict
    h = make_dict_unstructure_fn(
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/gen.py", line 46, in make_dict_unstructure_fn
    handler = converter._unstructure_func.dispatch(a.type)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/dispatch.py", line 47, in _dispatch
    return self._function_dispatch.dispatch(cl)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/dispatch.py", line 121, in dispatch
    return handler(typ)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/converters.py", line 675, in gen_unstructure_iterable
    h = make_iterable_unstructure_fn(
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/gen.py", line 214, in make_iterable_unstructure_fn
    handler = converter._unstructure_func.dispatch(type_arg)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/dispatch.py", line 47, in _dispatch
    return self._function_dispatch.dispatch(cl)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/dispatch.py", line 121, in dispatch
    return handler(typ)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/converters.py", line 645, in gen_unstructure_attrs_fromdict
    h = make_dict_unstructure_fn(
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/gen.py", line 32, in make_dict_unstructure_fn
    attrs = adapted_fields(cl)  # type: ignore
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/cattr/_compat.py", line 80, in adapted_fields
    return attrs_fields(type)
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/attr/_make.py", line 1763, in fields
    if not isclass(cls):
  File "/Users/john/.pyenv/versions/br3/lib/python3.9/site-packages/attr/_compat.py", line 118, in isclass
    return isinstance(klass, type)
RecursionError: maximum recursion depth exceeded while calling a Python object

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