Skip to content

TypeError: NoneType is not a dataclass and cannot be turned into one #143

@seva0stapenko

Description

@seva0stapenko

Greetings, I'm trying to define a set of related data classes, which closely mimic AWS APIs (hence properties in camel case).
I ran into an issue when class attribute name and name of attribute type are the same and attribute default value is None.
Here is a sample code:

from marshmallow_dataclass import dataclass
from marshmallow import Schema
from typing import Optional

@dataclass
class PaginationConfig:
    MaxItems: Optional[int] = None
    PageSize: Optional[int] = None

@dataclass
class PaginatorRequest:
    PaginationConfig: Optional[PaginationConfig] = None
    CatalogId: Optional[str] = None

Attempt to define class PaginatorRequest results in a rather long stack trace:

/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py:330: UserWarning: ****** WARNING ****** marshmallow_dataclass was called on the class <class 'NoneType'>, which is not a dataclass. It is going to try and convert the class into a dataclass, which may have undesirable side effects. To avoid this message, make sure all your classes and all the classes of their fields are either explicitly supported by marshmallow_dataclass, or define the schema explicitly using field(metadata=dict(marshmallow_field=...)). For more information, see https://github.com/lovasoa/marshmallow_dataclass/issues/51 ****** WARNING ******
  warnings.warn(
Traceback (most recent call last):
  File "/usr/local/Cellar/[email protected]/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 1031, in fields
    fields = getattr(class_or_instance, _FIELDS)
AttributeError: type object 'NoneType' has no attribute '__dataclass_fields__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 327, in _internal_class_schema
    fields: Tuple[dataclasses.Field, ...] = dataclasses.fields(clazz)
  File "/usr/local/Cellar/[email protected]/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 1033, in fields
    raise TypeError('must be called with a dataclass type or instance')
TypeError: must be called with a dataclass type or instance

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 341, in _internal_class_schema
    created_dataclass: type = dataclasses.dataclass(clazz)
  File "/usr/local/Cellar/[email protected]/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 1019, in dataclass
    return wrap(cls)
  File "/usr/local/Cellar/[email protected]/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 1011, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
  File "/usr/local/Cellar/[email protected]/3.8.10/Frameworks/Python.framework/Versions/3.8/lib/python3.8/dataclasses.py", line 824, in _process_class
    setattr(cls, _PARAMS, _DataclassParams(init, repr, eq, order,
TypeError: can't set attributes of built-in/extension type 'NoneType'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 145, in dataclass
    return add_schema(dc, base_schema)
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 193, in add_schema
    return decorator(_cls) if _cls else decorator
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 190, in decorator
    clazz.Schema = class_schema(clazz, base_schema)  # type: ignore
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 318, in class_schema
    return _internal_class_schema(clazz, base_schema)
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 355, in _internal_class_schema
    attributes.update(
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 358, in <genexpr>
    field_for_schema(
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 610, in field_for_schema
    nested_schema or forward_reference or _internal_class_schema(typ, base_schema)
  File "/usr/local/lib/python3.8/site-packages/marshmallow_dataclass/__init__.py", line 344, in _internal_class_schema
    raise TypeError(
TypeError: NoneType is not a dataclass and cannot be turned into one.

Renaming PaginatorRequest.PaginationConfig or class PaginationConfig to something else, or removing default assignment to None for PaginationConfig allows to side step the issue, though it would be much more preferably to have the underlying issue resolved.

Also, attempt to use attribute definition like PaginationConfig: Optional[PaginationConfig] = field(default=None) results in infinite recursion and and error RecursionError: maximum recursion depth exceeded while getting the repr of an object

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions