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

TypedDicts not working with from __future__ import annotations #187

Closed
kpodp0ra opened this issue Jan 16, 2024 · 2 comments · Fixed by #191
Closed

TypedDicts not working with from __future__ import annotations #187

kpodp0ra opened this issue Jan 16, 2024 · 2 comments · Fixed by #191
Labels
bug Something isn't working

Comments

@kpodp0ra
Copy link

  • mashumaro version: 3.11
  • Python version: 3.10.13
  • Operating System: Ubuntu

What I Did

from __future__ import annotations
from mashumaro.jsonschema import build_json_schema
from typing import TypedDict


class TypedDictRequiredKeys(TypedDict):
    int: int
    float: float


build_json_schema(TypedDictRequiredKeys)
Traceback (most recent call last):
  File "main.py", line 11, in <module>
    build_json_schema(TypedDictRequiredKeys)
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/builder.py", line 45, in build_json_schema
    schema = get_schema(instance, context, with_dialect_uri=with_dialect_uri)
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/schema.py", line 258, in get_schema
    schema = schema_creator(instance, ctx)
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/schema.py", line 802, in on_collection
    return on_typed_dict(instance, ctx)
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/schema.py", line 666, in on_typed_dict
    properties={
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/schema.py", line 667, in <dictcomp>
    key: get_schema(instance.derive(type=annotations[key]), ctx)
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/schema.py", line 258, in get_schema
    schema = schema_creator(instance, ctx)
  File "/usr/lib/python3.10/site-packages/mashumaro/jsonschema/schema.py", line 720, in on_collection
    if not issubclass(instance.origin_type, typing.Collection):

instance.origin_type is ForwardRef('int')
https://github.com/Fatal1ty/mashumaro/blob/ab8242448631ab7a1ad2e437561377cd698a99e9/mashumaro/jsonschema/schema.py#L718C23-L718C43

  File "/usr/lib/python3.10/typing.py", line 1158, in __subclasscheck__
    return issubclass(cls, self.__origin__)
  File "/usr/lib/python3.10/abc.py", line 123, in __subclasscheck__
    return _abc_subclasscheck(cls, subclass)
TypeError: issubclass() arg 1 must be a class

Description

TypedDicts are not working with from __future__ import annotations.

Also, it's worth noting that adding this line on top of tests/test_jsonschema/test_jsonschema_generation.py breaks tests:

  • test_jsonschema_for_named_tuple_with_overridden_serialization_method
  • test_jsonschema_for_typeddict
  • test_overridden_serialization_method_with_return_annotation
  • test_dataclass_overridden_serialization_method
  • test_third_party_overridden_serialization_method
@Fatal1ty
Copy link
Owner

@kpodp0ra

Hi, thank you for opening this issue.

TypedDicts are not working with from future import annotations.

I managed to add support for ForwardRef in JSON Schema generation here, so your example will work as expected now.

Also, it's worth noting that adding this line on top of tests/test_jsonschema/test_jsonschema_generation.py breaks tests:

  • test_jsonschema_for_named_tuple_with_overridden_serialization_method
  • test_jsonschema_for_typeddict
  • test_overridden_serialization_method_with_return_annotation
  • test_dataclass_overridden_serialization_method
  • test_third_party_overridden_serialization_method

Thank you for pointing out. This is due to restrictions in PEP 563 implementation:

Annotations can only use names present in the module scope as postponed evaluation using local names is not reliable (with the sole exception of class-level names resolved by typing.get_type_hints()).

So, as long as you don't define the data types inside the function, everything will be fine. We could try to hack it by juggling f_locals of frame objects to support forward refs to local types, but I just don't see much need for it right now. In some cases it will work without hacks, but in others it won't. Do you need JSON Schema for local types?

@kpodp0ra
Copy link
Author

Confirm that #191 fixes all my codebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants