From a5674c1ddf07a5aff0883563f754994c455bfae7 Mon Sep 17 00:00:00 2001 From: Jim Crist-Harif Date: Thu, 4 Jan 2024 20:09:08 -0600 Subject: [PATCH] Fix bug with multiple generic inheritence Previously if the same generic base class appeared multiple times in a classes inheritence graph msgspec would error when trying to analyze the class. This PR fixes the bug and adds a test for the behavior. --- msgspec/_utils.py | 11 +++++------ tests/test_utils.py | 9 +++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) 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}