biqqles/dataclassy

__dataclass_fields__ is missing

Closed this issue · 3 comments

I just found dataclassy and it looks really useful! I wanted to test it together with https://github.com/s-knibbs/dataclasses-jsonschema which I'm using in one of my projects, but got this:

>>> from dataclassy import dataclass
>>> from dataclasses_jsonschema import JsonSchemaMixin
>>> @dataclass
... class Item(JsonSchemaMixin):
...     id: str = ""
... 
>>> it=Item()
>>> it.to_json()
Traceback (most recent call last):
  File "/usr/lib/python3.8/dataclasses.py", line 1031, in fields
    fields = getattr(class_or_instance, _FIELDS)
AttributeError: type object 'Item' has no attribute '__dataclass_fields__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 861, in to_json
    return json.dumps(self.to_dict(omit_none, validate), **json_kwargs)
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 389, in to_dict
    for f in self._get_fields():
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 380, in _get_fields
    cls.__mapped_fields = _get_fields_uncached()
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 353, in _get_fields_uncached
    for f in fields(cls):
  File "/usr/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

Would it be possible to add/emulate __dataclass_fields__ to make these two compatible?

Hmm, the fact that this error is raised inside dataclasses makes me suspicious that this will not be the only problem. Also, it originates in a call to fields() which in dataclasses returns a dict with Field instances as values, a class which dataclassy does not have.

If you wanted to test whether it is really as simple as setting __dataclass_fields__, you could try setting

from dataclassy import fields

Item.__dataclass_fields__ = fields(Item)

But I am not hopeful. I think a better way to consider would be monkey-patching _get_fields. This seems like it might be quite easy since dataclassy already does a lot of the work for you - its fields() automatically removes internal fields and includes the type annotations in the result.

You were right, __dataclass_fields__ was not the problem. When I set it, I got:

>>> Item.__dataclass_fields__ = fields(Item)
>>> 
>>> it.to_json()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 862, in to_json
    return json.dumps(self.to_dict(omit_none, validate), **json_kwargs)
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 390, in to_dict
    for f in self._get_fields():
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 381, in _get_fields
    cls.__mapped_fields = _get_fields_uncached()
  File "/home/zdenal/arcor2_repos/arcor2/build-support/.venv/lib/python3.8/site-packages/dataclasses_jsonschema/__init__.py", line 354, in _get_fields_uncached
    for f in fields(cls):
  File "/usr/lib/python3.8/dataclasses.py", line 1037, in fields
    return tuple(f for f in fields.values() if f._field_type is _FIELD)
  File "/usr/lib/python3.8/dataclasses.py", line 1037, in <genexpr>
    return tuple(f for f in fields.values() if f._field_type is _FIELD)
AttributeError: type object 'str' has no attribute '_field_type'

Thank you for the tip to monkey-patch the _get_fields - I will try it.

Any luck with the patching? Or any more suggestions for dataclassy to make it easier? Otherwise I'll close this.