Default union disambiguation function doesn't work with renamed keys

Open
#265 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
3/5
Estimated time
1-2 days
Newbie friendliness
25/100
Issue type
Bug
Clarity
Mostly clear
Activity status
Stale
Tech stack
python
Domain
backend

Research direction

Start with src/cattrs/disambiguators.py at the linked default disambiguation function creator and reproduce the example using renamed keys. Trace how the generated hooks and union disambiguation select fields. Done means structuring both {'aField': 1} and {'anotherField': 1} into A | B succeeds with the shown renamed-key hooks, with regression coverage added where the project’s existing tests for disambiguation are located.

Written by the indexing model from the issue text.

Description

  • cattrs version: cattrs version: 22.1.0
  • Python version: 3.10
  • Operating System: MacOS Monterey 12.2.1
Description

I tried to structure some data into the union type with keys renaming. It doesn't work because the default disambiguation function creator builds it based on non-overriden fields (link). I could write a proper disambiguator myself but I think it should work out-of-the-box.

What I Did
from attrs import define
import cattrs
from cattrs.gen import make_dict_structure_fn, override

@define
class A:
    a_field: int


@define
class B:
    another_field: int


c = cattrs.GenConverter()

c.register_structure_hook(A, make_dict_structure_fn(A, c, a_field=override(rename="aField")))
c.register_structure_hook(B, make_dict_structure_fn(B, c, another_field=override(rename="anotherField")))

print(c.structure({'aField': 1}, A))
# A(a_field=1)

print(c.structure({'anotherField': 1}, B))
# B(another_field=1)

print(c.structure({'anotherField': 1}, A | B))
# B(another_field=1)

print(c.structure({'aField': 1}, A | B))
# raises ClassValidationError: While structuring B (1 sub-exception)
# ClassValidationError('While structuring B', [KeyError('another_field')])
Dominant language
Python
Stars
1.1k
Forks
159
Avg merge
12h 21m
Merged PRs (30d)
6

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.

More from python-attrs/cattrs

All issues in python-attrs/cattrs

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.