Skip to content

Still not able to structure using an alias #553

New issue

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

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

Already on GitHub? Sign in to your account

Closed
cj4ssi opened this issue Jul 12, 2024 · 3 comments
Closed

Still not able to structure using an alias #553

cj4ssi opened this issue Jul 12, 2024 · 3 comments

Comments

@cj4ssi
Copy link

cj4ssi commented Jul 12, 2024

Description

It is still not possible to structure a dict using the alias of a field. Supposedly this was fixed in #322.

Example:

from attrs import mutable, field
from cattrs import stucture

@mutable
class Thing:
  one:int
  _two:int = field(alias='two')

structure({'one': 1, 'two': 2}, Thing)  # raises cattrs.errors.ClassValidationError on "_two" missing from `Thing`

This is due to the line obtaining the value of the to-be-structured data via name only, in `BaseConverter.structure_attrs_fromdict:

for a in fields(cl):
    try:
        val = obj[a.name]
    except KeyError:
        continue

val = obj[a.name]

The fix is easy, but I am only authorized to file issues, not fixes, with this account. Will submit MR when possible.

@Tinche
Copy link
Member

Tinche commented Jul 12, 2024

So that's actually working as intended, see https://catt.rs/en/latest/customizing.html#use-alias for more details.

Aliases aren't used by default, that would have been a large compatibility break when it was introduced in attrs.

Here's a snippet to enable them for your class:

from attrs import field, mutable

from cattrs import Converter
from cattrs.gen import make_dict_structure_fn


@mutable
class Thing:
    one: int
    _two: int = field(alias="two")


c = Converter()
c.register_structure_hook(
    Thing, make_dict_structure_fn(Thing, c, _cattrs_use_alias=True)
)

c.structure({"one": 1, "two": 2}, Thing)

They can also be enabled for all attrs classes using a hook factory, let me know if you'd like an example for that.

@Tinche Tinche closed this as completed Jul 12, 2024
@NodeJSmith
Copy link

PSA: Make sure you call structure on the converter instance (e.g. c.structure, like @Tinche's example), not on cattrs. Otherwise you'll spend 30 minutes trying to figure out what's not working, write up a whole comment explaining the issue and then erase it to write a PSA instead

@Tinche
Copy link
Member

Tinche commented Jul 23, 2024

I know you're joking but if you apply the register_structure_hook to the global converter (cattrs.global_converter) it'll work with cattrs.structure. I always recommend having a separate converter though, because who knows what else could be using the global one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants