diff --git a/msgspec/_utils.py b/msgspec/_utils.py index 33d57ed0..ddf6f27c 100644 --- a/msgspec/_utils.py +++ b/msgspec/_utils.py @@ -74,13 +74,12 @@ def inner(c, scope): new_scope = {} else: cls = getattr(c, "__origin__", None) - if cls in (None, object, typing.Generic): + if cls in (None, object, typing.Generic) or cls in mapping: return - if cls not in mapping: - params = cls.__parameters__ - args = tuple(_apply_params(a, scope) for a in c.__args__) - assert len(params) == len(args) - mapping[cls] = new_scope = dict(zip(params, args)) + params = cls.__parameters__ + args = tuple(_apply_params(a, scope) for a in c.__args__) + assert len(params) == len(args) + mapping[cls] = new_scope = dict(zip(params, args)) if issubclass(cls, typing.Generic): bases = getattr(cls, "__orig_bases__", cls.__bases__) diff --git a/tests/test_utils.py b/tests/test_utils.py index dc24581e..83630c93 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -181,3 +181,12 @@ class Sub3(Sub[List[T]]): "a": List[List[int]], "b": List[int], } + + def test_generic_sub11(self): + class Sub(Base[int]): + y: float + + class Sub2(Sub, Base[int]): + z: str + + assert get_class_annotations(Sub2) == {"x": int, "y": float, "z": str}