- Notifications
You must be signed in to change notification settings - Fork 124
Description
Description
If you try to make a generic class that inherits from one of the _SpecialGenericAlias types (such as Mapping), the type inference fails to work.
A minimal example below (Python 3.13, msgspec 0.20.0):
from collections.abc import Mapping from dataclasses import dataclass import msgspec @dataclass class Bar[T](Mapping[str, T]): data: dict[str, T] def __getitem__(self, x): return self.data[x] def __len__(self): return len(self.data) def __iter__(self): return iter(self.data) x: Bar[int] = Bar({"x": 3}) msgspec.msgpack.decode(msgspec.msgpack.encode(x), type=Bar[int])with traceback
Traceback (most recent call last): File "<censored>", line 31, in <module> msgspec.msgpack.decode(msgspec.msgpack.encode(x), type=Bar[int]) ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/opt/venv/lib/python3.13/site-packages/msgspec/_utils.py", line 252, in get_dataclass_info hints = get_class_annotations(obj) File "/opt/venv/lib/python3.13/site-packages/msgspec/_utils.py", line 149, in get_class_annotations mro, typevar_mappings = _get_class_mro_and_typevar_mappings(obj) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^ File "/opt/venv/lib/python3.13/site-packages/msgspec/_utils.py", line 126, in _get_class_mro_and_typevar_mappings inner(obj, {}) ~~~~~^^^^^^^^^ File "/opt/venv/lib/python3.13/site-packages/msgspec/_utils.py", line 124, in inner inner(b, new_scope) ~~~~~^^^^^^^^^^^^^^ File "/opt/venv/lib/python3.13/site-packages/msgspec/_utils.py", line 116, in inner params = cls.__parameters__ ^^^^^^^^^^^^^^^^^^ AttributeError: type object 'Mapping' has no attribute '__parameters__' I believe this is caused by the logic in inner(...) in the utils. For this, we look up __origin__ - however, in these specific cases, the types library has typing.Mapping as a typing._SpecialGenericAlias, which has different behaviour - it's __origin__ is not typing.Mapping, it's collections.abc.Mapping. This has no generic type parameters so inference fails.
This looks extremely tough to wade through so not sure what a good workaround is here - not a typing expert!
I'll note briefly that this behaviour goes away if it's not generic in inheritance, but it still fails if I use msgspec.Struct and a combined metaclass from StructMeta and ABCMeta so is not an artifact of dataclasses or anything, I think.