Fix argument type annotation of defstruct()#1014
Conversation
Previously, defstruct() argument "fields" was annotated to be an iterable of tuples which contain "type" objects. However, defstruct also reads and understands unions of types, as also documented in the example at https://jcristharif.com/msgspec/api.html#msgspec.defstruct This patch fixes mypy complaining when passing a union.
|
Thanks for catching this @ypnos! You're right that the current annotation is too narrow - mypy shouldn't reject I think we can take this a bit further though. The runtime doesn't actually validate the type field at all - it just stores whatever you pass into
In fact the docstring example for Rather than enumerating each typing form (which is hard to keep complete), would you be open to annotating the type slot as fields: Iterable[str | tuple[str, Any] | tuple[str, Any, Any]]It's a single change, drops the It would also be great to extend Happy to help with either of those if it's easier - just let me know! |
As it is very hard to cover all cases of allowed type form annotations, use Any instead. This is in line with `dataclasses.make_dataclass`. PEP 747 could improve this situation in the future. Co-authored-by: Jim Crist-Harif <jcristharif@gmail.com>
|
Thank you @jcrist and @Siyet for looking into this and providing a suggestion on how to solve this best. I fixed it up with most relevant facts in the commit message. Would you like me to squash this into a single commit? I'm not sure I will find the time myself to add test cases for type form scenarios. |
Previously, defstruct() argument "fields" was annotated to be an iterable of tuples which contain "type" objects.
However, defstruct also reads and understands unions of types, as also documented in the example at https://jcristharif.com/msgspec/api.html#msgspec.defstruct
This patch fixes mypy complaining when passing a union.
Notes:
types.UnionTypewas introduced in Python 3.10, which is currently the minimum Python version for msgspec.types.UnionTypeis an alias fortyping.Uniontyping.Unionhere for Python <= 3.14 to support people spelling outUnion[int | str]instead ofint | str