rnag / rnag/dataclass-wizard

Generating and interpreting tags for union types

Open
#255 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
250
Forks
36
PR merge metrics
No merged PRs in 30d

Description

In the following code the __tag__ field is not generated for a member of a union type:

from dataclasses import dataclass

import dataclass_wizard as dw
from dataclass_wizard import LoadMeta


@dataclass
class ResErr:
    item_id: str
    msg: str


@dataclass
class ResOk:
    item_id: str
    item: str


Res = ResErr | ResOk

LoadMeta(tag='ResErr').bind_to(ResErr)
LoadMeta(tag='ResOk').bind_to(ResOk)

err = ResErr(item_id='Q0001', msg='err')
print(dw.asdict(err))
# {'item_id': 'Q0001', 'msg': 'err'}

When specifying the union type explicitely in asdict:

res = dw.asdict(err, cls=Res)

The following error occurs:

Traceback (most recent call last):
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/_dumpers.py", line 1288, in asdict
    return cls.__dataclass_wizard_to_dict__(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'types.UnionType' object has no attribute '__dataclass_wizard_to_dict__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/foo/Code/dw-test/src/kgqa_eval/scripts/dw_tag_1.py", line 31, in <module>
    print(dw.asdict(err, cls=Res))
          ~~~~~~~~~^^^^^^^^^^^^^^
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/_dumpers.py", line 1292, in asdict
    fn = dump_func_for_dataclass(cls)
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/_dumpers.py", line 831, in dump_func_for_dataclass
    cls_fields = dataclass_fields(cls)
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/utils/_dataclass_compat.py", line 113, in dataclass_fields
    return FIELDS[cls]
           ~~~~~~^^^^^
  File "/home/foo/.local/share/uv/python/cpython-3.13.13-linux-x86_64-gnu/lib/python3.13/weakref.py", line 415, in __getitem__
    return self.data[ref(key)]
                     ~~~^^^^^
TypeError: cannot create weak reference to 'types.UnionType' object

When a container type is defined, then the __tag__ field is generated:

@dataclass
class Container:
    res: Res


err = Container(res=ResErr(item_id='Q0001', msg='err'))
print(dw.asdict(err))
# {'res': {'item_id': 'Q0001', 'msg': 'err', '__tag__': 'ResErr'}}

Is it possible to generate the __tag__ field in the first example as well?

It also would be nice to be able to parse a dict to the Res union type:

res = dw.fromdict(Res, {'item_id': 'Q0001', 'msg': 'err', '__tag__': 'ResErr'})
print(res)

Currenty this results in the following error:

Traceback (most recent call last):
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/_loaders.py", line 1671, in fromdict
    return cls.__dataclass_wizard_from_dict__(d)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'types.UnionType' object has no attribute '__dataclass_wizard_from_dict__'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/home/foo/Code/dw-test/src/kgqa_eval/scripts/dw_tag_1.py", line 34, in <module>
    err = dw.fromdict(Res, {'item_id': 'Q0001', 'msg': 'err', '__tag__': 'ResErr'})
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/_loaders.py", line 1674, in fromdict
    fn = load_func_for_dataclass(cls)
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/_loaders.py", line 1142, in load_func_for_dataclass
    fields = dataclass_fields(cls)
  File "/home/foo/Code/dw-test/.venv/lib/python3.13/site-packages/dataclass_wizard/utils/_dataclass_compat.py", line 113, in dataclass_fields
    return FIELDS[cls]
           ~~~~~~^^^^^
  File "/home/foo/.local/share/uv/python/cpython-3.13.13-linux-x86_64-gnu/lib/python3.13/weakref.py", line 415, in __getitem__
    return self.data[ref(key)]
                     ~~~^^^^^
TypeError: cannot create weak reference to 'types.UnionType' object

The used version of dataclass-wizard is 1.0.0.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the asdict and fromdict entry points in _dumpers.py and _loaders.py, then trace the union handling behind the reported errors. Use the ResErr/ResOk examples as regression cases. Done means direct serialization adds the expected tag and fromdict can resolve the tagged Res union, while the existing Container behavior remains intact.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.