From 0dc36206be2e0822da0d78ac1332298c2745f841 Mon Sep 17 00:00:00 2001 From: "Michael J. Sullivan" Date: Wed, 7 Jan 2026 14:20:18 -0800 Subject: [PATCH] Add a test of evaluating a type with a link in its attrs I was poking around at #13, thinking about to what extent the various data structures there can be unified, and noticed that no tests failed if I got rid of `seen`! That seemed wrong, so I wrote some tests to catch those cases. (Without seen, we blow the stack.) Note that in these cases (of classes), not only do we want to not blow the stack, but we would like the recursively referenced type to be identical to the top-level one. (Whereas I think for *type aliases*, I think that is not what we want, since it probably wouldn't pretty print correctly?) --- tests/test_type_dir.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/test_type_dir.py b/tests/test_type_dir.py index c364513..5744611 100644 --- a/tests/test_type_dir.py +++ b/tests/test_type_dir.py @@ -154,6 +154,37 @@ class Final(Mine, Ordinary, Wrapper[float], AnotherBase[float], Last[int]): ] +# Subtyping this forces real type evaluation +class Eval[T]: + pass + + +class Loop(Eval[int]): + loop: Loop + + +class Foo(Eval[int]): + bar: Bar + + +class Bar(Eval[float]): + foo: Foo + + +def test_type_dir_link_1(): + d = eval_typing(Loop) + loop = d.__annotations__["loop"] + assert loop is d + assert loop is not Foo + + +def test_type_dir_link_2(): + d = eval_typing(Foo) + loop = d.__annotations__["bar"].__annotations__["foo"] + assert loop is d + assert loop is not Foo + + def test_type_dir_1(): d = eval_typing(Final)