Skip to content

Mixing generic container from typing and built-in crashes on py3.7-8 #218

@bibajz

Description

@bibajz
  • cattrs version: 22.1.0dev0
  • Python version: 3.7, 3.8 (FAILS) 3.9, 3.10 (OK)
  • Operating System: irrelevant

Description

Specifying an empty generic type from a standard library - so far tested on dict and list - crashes, since these types do not have __args__ attribute until py3.9

Python 3.8.10 (default, Nov 26 2021, 20:14:08) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import typing as t
>>> 
>>> import attrs
>>> import cattrs
>>>
>>> @attrs.define
... class A1:
...     bs: t.List[dict]
... 

>>> @attrs.define
... class A2:
...     bs: t.List[list]
...

>>> @attrs.define
... class D:
...     d: dict
... 

>>> cattrs.structure({"bs": [{}, {"a": 1}]}, A1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 300, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
  File "<cattrs generated structure __main__.A1>", line 3, in structure_A1
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 478, in _structure_list
    return [
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 479, in <listcomp>
    self._structure_func.dispatch(elem_type)(e, elem_type)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/dispatch.py", line 49, in _dispatch
    return self._function_dispatch.dispatch(cl)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/dispatch.py", line 126, in dispatch
    return handler(typ)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 790, in gen_structure_mapping
    h = make_mapping_structure_fn(cl, self)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/gen.py", line 465, in make_mapping_structure_fn
    if not is_bare(cl):
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/_compat.py", line 171, in is_bare
    args = type.__args__
AttributeError: type object 'dict' has no attribute '__args__'

>>> cattrs.structure({"bs": [[], [1]]}, A2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 300, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
  File "<cattrs generated structure __main__.A2>", line 3, in structure_A2
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 478, in _structure_list
    return [
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 479, in <listcomp>
    self._structure_func.dispatch(elem_type)(e, elem_type)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 474, in _structure_list
    if is_bare(cl) or cl.__args__[0] is Any:
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/_compat.py", line 171, in is_bare
    args = type.__args__
AttributeError: type object 'list' has no attribute '__args__'
>>>
>>> cattrs.structure({"d": {}}, D)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 300, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/dispatch.py", line 49, in _dispatch
    return self._function_dispatch.dispatch(cl)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/dispatch.py", line 126, in dispatch
    return handler(typ)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 740, in gen_structure_attrs_fromdict
    h = make_dict_structure_fn(
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/gen.py", line 280, in make_dict_structure_fn
    handler = converter._structure_func.dispatch(t)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/dispatch.py", line 49, in _dispatch
    return self._function_dispatch.dispatch(cl)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/dispatch.py", line 126, in dispatch
    return handler(typ)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/converters.py", line 790, in gen_structure_mapping
    h = make_mapping_structure_fn(cl, self)
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/gen.py", line 465, in make_mapping_structure_fn
    if not is_bare(cl):
  File "/home/libor/.virtualenvs/cattrs/lib/python3.8/site-packages/cattr/_compat.py", line 171, in is_bare
    args = type.__args__
AttributeError: type object 'dict' has no attribute '__args__'

Swapping dict/list for their upper-cased variants produces expected behaviour

>>> @attrs.define
... class D2:
...     d: typing.Dict
... 
>>> 
>>> cattrs.structure({"d": {}}, D2)
D2(d={})

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions