python-desert / desert

Deserialize to objects while staying DRY
https://desert.readthedocs.io
MIT License
158 stars 10 forks source link

desert fails on recursive type hints #88

Open sveinse opened 4 years ago

sveinse commented 4 years ago

Given a definition of a binary tree type hint BTREE = Union[LEAF, Tuple['BTREE', 'BTREE']], this cause desert schema to end up in an indefinite loop in lib\typing.py. Given that it is stuck in a loop in stdlib, I am not sure if this is a desert issue vs a typing issue or if typing wasn't really designed for recursive type hints like this in the first place.

from typing import Optional, Union, Tuple
import desert
import attr

# Can be any type
LEAF = str

# Binary tree definition
BTREE = Union[LEAF, Tuple['BTREE', 'BTREE']]

def test_btree():

    @attr.s(slots=True)
    class A:
        x: BTREE = attr.ib(default='leaf')

    a = A()
    schema = desert.schema(A)
    d = schema.dump(a)

Results in

Traceback (most recent call last):
  File "C:\sveinse\tests\test_tree.py", line 19, in test_btree
    schema = desert.schema(A)
  File "c:\sveinse\venv\lib\site-packages\desert\__init__.py", line 24, in schema
    return desert._make.class_schema(cls, meta=meta)(many=many)
  File "c:\sveinse\venv\lib\site-packages\desert\_make.py", line 124, in class_schema
    field.metadata,
  File "c:\sveinse\venv\lib\site-packages\desert\_make.py", line 225, in field_for_schema
    if not field and typ in _native_to_marshmallow:
  File "C:\Users\sveinse\AppData\Local\Programs\Python\Python37-32\lib\typing.py", line 666, in __hash__
    return hash((Union, frozenset(self.__args__)))
  File "C:\Users\sveinse\AppData\Local\Programs\Python\Python37-32\lib\typing.py", line 667, in __hash__
    return hash((self.__origin__, self.__args__))
  File "C:\Users\sveinse\AppData\Local\Programs\Python\Python37-32\lib\typing.py", line 666, in __hash__
    return hash((Union, frozenset(self.__args__)))
.... and forever.
sveinse commented 4 years ago

This is an issue on py 3.7, while it is not on py 3.8. This makes this issue an python issue, not a desert issue, does it not?

python-desert commented 4 years ago

This might be an upstream issue in Python or typing_inspect, or maybe we're just doing it wrong. We could try to figure out a workaround. I've opened https://github.com/python-desert/desert/issues/89 to discuss our general situation regarding recursive types and unions.