Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

configure_tagged_union doesn't mix with forbid_extra_keys=True #402

Closed
twm opened this issue Aug 1, 2023 · 1 comment · Fixed by #443
Closed

configure_tagged_union doesn't mix with forbid_extra_keys=True #402

twm opened this issue Aug 1, 2023 · 1 comment · Fixed by #443
Labels
Milestone

Comments

@twm
Copy link

twm commented Aug 1, 2023

  • cattrs version: 23.1.2
  • Python version: 3.10.12
  • Operating System: Linux (Ubuntu 22.04)

Description

I tried to mix cattrs.strategies.configure_tagged_union with a converter configured with forbid_extra_keys=True. Ideally this would work out of the box — structuring would remove the _type key before structuring the specific union member. Failing that this should be mentioned in the docs.

What I Did

Given tagged_union.py:

import attrs
from cattrs import Converter
from cattrs.strategies import configure_tagged_union


@attrs.define
class A:
    pass


@attrs.define
class B:
    pass


c = Converter(forbid_extra_keys=True)
configure_tagged_union(A | B, c)

data = c.unstructure(A(), A | B)
print(data)
c.structure(data, A | B)

I get an exception because of the _type keys that the tagged union strategy injects:

❯ python tagged_union.py 
{'_type': 'A'}
  + Exception Group Traceback (most recent call last):
  |   File ".../tagged_union.py", line 21, in <module>
  |     c.structure(data, A | B)
  |   File ".../venv/lib/python3.10/site-packages/cattrs/converters.py", line 334, in structure
  |     return self._structure_func.dispatch(cl)(obj, cl)
  |   File ".../venv/lib/python3.10/site-packages/cattrs/converters.py", line 651, in _structure_union
  |     return handler(obj, union)
  |   File ".../venv/lib/python3.10/site-packages/cattrs/strategies/_unions.py", line 86, in structure_tagged_union
  |     return _tag_to_cl[val[_tag_name]](val)
  |   File ".../venv/lib/python3.10/site-packages/cattrs/strategies/_unions.py", line 52, in structure_union_member
  |     return _h(val, _cl)
  |   File "<cattrs generated structure __main__.A>", line 7, in structure_A
  |     if errors: raise __c_cve('While structuring ' + 'A', errors, __cl)
  | cattrs.errors.ClassValidationError: While structuring A (1 sub-exception)
  +-+---------------- 1 ----------------
    | cattrs.errors.ForbiddenExtraKeysError: Extra fields in constructor for A: _type
    +------------------------------------
@Tinche
Copy link
Member

Tinche commented Aug 1, 2023

Hm we can probably just fix it so it pops the discriminant key out. I don't think the current behavior is on purpose.

@Tinche Tinche added the bug label Aug 1, 2023
@Tinche Tinche added this to the 23.2 milestone Aug 5, 2023
@Tinche Tinche linked a pull request Nov 14, 2023 that will close this issue
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants