rsinger86 / drf-typed

Type hints for enhanced API views and serializers.
https://rsinger86.github.io/drf-typed/
MIT License
80 stars 5 forks source link

RecursionError: maximum recursion depth exceeded in comparison #2

Open L4legenda opened 2 years ago

L4legenda commented 2 years ago

Using List in TSerializer causes an error

File "/Users/l4legenda/.vscode/extensions/ms-python.python-2022.10.0/pythonFiles/lib/python/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch_regular.py", line 469, in __call__
    return None if event == 'call' else NO_FTRACE
RecursionError: maximum recursion depth exceeded in comparison
rsinger86 commented 2 years ago

could you provide more details on what the full serializer definition looked like? Thanks!

TonisPiip commented 1 year ago

I'm getting the same issue.

In [16]: from datetime import date
    ...: from rest_typed.serializers import TSerializer
    ...: 
    ...: 
    ...: class MovieSerializer(TSerializer):
    ...:     release_date: date
    ...:     cast: List[str]
    ...: 
    ...: movie = MovieSerializer({
    ...:     'release_date': '2021-10-10',
    ...: 
    ...:     'cast': ['Steve Martin']
    ...: })

In [17]: movie
Out[17]: ---------------------------------------------------------------------------
RecursionError                            Traceback (most recent call last)
File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/IPython/core/formatters.py:708, in PlainTextFormatter.__call__(self, obj)
    701 stream = StringIO()
    702 printer = pretty.RepresentationPrinter(stream, self.verbose,
    703     self.max_width, self.newline,
    704     max_seq_length=self.max_seq_length,
    705     singleton_pprinters=self.singleton_printers,
    706     type_pprinters=self.type_printers,
    707     deferred_pprinters=self.deferred_printers)
--> 708 printer.pretty(obj)
    709 printer.flush()
    710 return stream.getvalue()

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/IPython/lib/pretty.py:410, in RepresentationPrinter.pretty(self, obj)
    407                         return meth(obj, self, cycle)
    408                 if cls is not object \
    409                         and callable(cls.__dict__.get('__repr__')):
--> 410                     return _repr_pprint(obj, self, cycle)
    412     return _default_pprint(obj, self, cycle)
    413 finally:

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/IPython/lib/pretty.py:778, in _repr_pprint(obj, p, cycle)
    776 """A pprint that just redirects to the normal repr function."""
    777 # Find newlines and replace them with p.break_()
--> 778 output = repr(obj)
    779 lines = output.splitlines()
    780 with p.group():

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/serializers.py:530, in Serializer.__repr__(self)
    529 def __repr__(self):
--> 530     return representation.serializer_repr(self, indent=1)

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/utils/representation.py:77, in serializer_repr(serializer, indent, force_many)
     75     fields = force_many.fields
     76 else:
---> 77     fields = serializer.fields
     79 for field_name, field in fields.items():
     80     ret += '\n' + indent_str + field_name + ' = '

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_typed/serializers/serializers.py:43, in TSerializerAttrFieldsMixin.__getattr__(self, name)
     42 def __getattr__(self, name: str):
---> 43     if name not in self.fields.keys():
     44         raise AttributeError(f"{name} does not exist.")
     46     if not hasattr(self, "_validated_data"):

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_typed/serializers/serializers.py:43, in TSerializerAttrFieldsMixin.__getattr__(self, name)
     42 def __getattr__(self, name: str):
---> 43     if name not in self.fields.keys():
     44         raise AttributeError(f"{name} does not exist.")
     46     if not hasattr(self, "_validated_data"):

    [... skipping similar frames: TSerializerAttrFieldsMixin.__getattr__ at line 43 (2950 times)]

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_typed/serializers/serializers.py:43, in TSerializerAttrFieldsMixin.__getattr__(self, name)
     42 def __getattr__(self, name: str):
---> 43     if name not in self.fields.keys():
     44         raise AttributeError(f"{name} does not exist.")
     46     if not hasattr(self, "_validated_data"):

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/django/utils/functional.py:48, in cached_property.__get__(self, instance, cls)
     46 if instance is None:
     47     return self
---> 48 res = instance.__dict__[self.name] = self.func(instance)
     49 return res

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/serializers.py:356, in Serializer.fields(self)
    352 # `fields` is evaluated lazily. We do this to ensure that we don't
    353 # have issues importing modules that use ModelSerializers as fields,
    354 # even if Django's app-loading stage has not yet run.
    355 fields = BindingDict(self)
--> 356 for key, value in self.get_fields().items():
    357     fields[key] = value
    358 return fields

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/serializers.py:379, in Serializer.get_fields(self)
    373 """
    374 Returns a dictionary of {field_name: field_instance}.
    375 """
    376 # Every new serializer is created with a clone of the field instances.
    377 # This allows users to dynamically modify the fields on a serializer
    378 # instance without affecting every other serializer instance.
--> 379 return copy.deepcopy(self._declared_fields)

File /usr/local/lib/python3.10/copy.py:172, in deepcopy(x, memo, _nil)
    170                 y = x
    171             else:
--> 172                 y = _reconstruct(x, memo, *rv)
    174 # If is its own copy, don't memoize.
    175 if y is not x:

File /usr/local/lib/python3.10/copy.py:297, in _reconstruct(x, memo, func, args, state, listiter, dictiter, deepcopy)
    295     for key, value in dictiter:
    296         key = deepcopy(key, memo)
--> 297         value = deepcopy(value, memo)
    298         y[key] = value
    299 else:

File /usr/local/lib/python3.10/copy.py:153, in deepcopy(x, memo, _nil)
    151 copier = getattr(x, "__deepcopy__", None)
    152 if copier is not None:
--> 153     y = copier(memo)
    154 else:
    155     reductor = dispatch_table.get(cls)

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/fields.py:655, in Field.__deepcopy__(self, memo)
    647 args = [
    648     copy.deepcopy(item) if not isinstance(item, REGEX_TYPE) else item
    649     for item in self._args
    650 ]
    651 kwargs = {
    652     key: (copy.deepcopy(value, memo) if (key not in ('validators', 'regex')) else value)
    653     for key, value in self._kwargs.items()
    654 }
--> 655 return self.__class__(*args, **kwargs)

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/fields.py:1209, in DateField.__init__(self, format, input_formats, **kwargs)
   1207 if input_formats is not None:
   1208     self.input_formats = input_formats
-> 1209 super().__init__(**kwargs)

File ~/.cache/pypoetry/virtualenvs/krah-9TtSrW0h-py3.10/lib/python3.10/site-packages/rest_framework/fields.py:354, in Field.__init__(self, read_only, write_only, required, default, initial, source, label, help_text, style, error_messages, validators, allow_null)
    352 messages = {}
    353 for cls in reversed(self.__class__.__mro__):
--> 354     messages.update(getattr(cls, 'default_error_messages', {}))
    355 messages.update(error_messages or {})
    356 self.error_messages = messages

RecursionError: maximum recursion depth exceeded while calling a Python object

In [18]: