Skip to content
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

Structuring a non-dict type as TypedDict raises AttributeError #615

Closed
bluetech opened this issue Jan 5, 2025 · 5 comments · Fixed by #616 or #617
Closed

Structuring a non-dict type as TypedDict raises AttributeError #615

bluetech opened this issue Jan 5, 2025 · 5 comments · Fixed by #616 or #617
Milestone

Comments

@bluetech
Copy link
Contributor

bluetech commented Jan 5, 2025

  • cattrs version: 24.1.0
  • Python version: 3.11
  • Operating System: Linux

Description

I am structuring a TypedDict type. The input is arbitrary (from JSON), and I want to offload the validation to cattrs.
The problem is, if the input is not a dict (in my case, not a JSON object), cattrs raises an AttributeError instead of the expected cattrs.errors.ClassValidationError.

from typing import TypedDict
import cattrs

class MyTypedDict(TypedDict):
    foo: int

cattrs.structure(42, MyTypedDict)

I would like to avoid catching AttributeError or adding my own pre-checks.

What I Did

Running the script above results in:

Traceback (most recent call last):
  File "x.py", line 8, in <module>
    cattrs.structure(42, MyTypedDict)
  File "venv/lib/python3.11/site-packages/cattrs/converters.py", line 544, in structure
    return self._structure_func.dispatch(cl)(obj, cl)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<cattrs generated structure __main__.MyTypedDict>", line 2, in structure_MyTypedDict
AttributeError: 'int' object has no attribute 'copy'
@Tinche
Copy link
Member

Tinche commented Jan 5, 2025

Hm, agreed. Let me get this for the next version.

@Tinche Tinche added this to the 24.2 milestone Jan 5, 2025
@Tinche Tinche linked a pull request Jan 6, 2025 that will close this issue
@Tinche
Copy link
Member

Tinche commented Jan 6, 2025

I think I got this on main. Can you give it a try and let me know?

@bluetech
Copy link
Contributor Author

bluetech commented Jan 6, 2025

Thanks! I will try it on my real example and let you know.

Regarding the fix, did you intentionally avoid an isinstance check? I wonder for example what happens if the input is a list (JSON array) -- a list does have a copy() method.

@Tinche
Copy link
Member

Tinche commented Jan 6, 2025

Hm, interesting. My thinking is this: catching an AttributeError adds essentially no overhead, and a separate isinstance check would be felt, especially on small dicts. It's also a little unclear what to check against (collections.abc.Mapping presumably).

Let me see what happens if a list is passed in when I get to a computer.

@Tinche
Copy link
Member

Tinche commented Jan 6, 2025

I think you're right, the error message kind of sucks when lists are involved.

Here's a new try: #617

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