jcrist / msgspec

A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML
https://jcristharif.com/msgspec/
BSD 3-Clause "New" or "Revised" License
2.44k stars 75 forks source link

ForwardRef is not supported #676

Open jdglaser opened 6 months ago

jdglaser commented 6 months ago

Description

Running the latest version of msgspec (0.18.6) on Python 3.12.2.

I noticed that we are unable to define types that use ForwardRef to reference itself. For example, I can define a generic JSON data type like this

JSON = dict[str, "JSON"] | list["JSON"] | str | int | float | bool | None

class Foo(msgspec.Struct):
    json_data: "JSON"

The type checker (pyright 1.1.361) is happy with this, and in fact I can create instances of Foo using the json_data type and the type checker will properly enforce this nested ForwardRef type.

However, if I try to convert this with msgspec

print(msgspec.convert({"json_data": {"foo": "bar", "baz": {"foo": "bar"}}}, Foo))

I get the following error

Traceback (most recent call last):
  File "msgspec-playground/main.py", line 17, in <module>
    print(msgspec.convert({"json_data": {"foo": "bar", "baz": {"foo": "bar"}}}, Foo))
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: Type 'ForwardRef('JSON')' is not supported

Not sure if this is a known bug, but wanted to raise it to see if this is something msgspec could potentiall support, since Python 3.11+ supports ForwardRef types.