Yeah, I explored the idea of name mangling, but I couldn't figure out how to make this work with `eval`, which is needed for `typing.get_type_hints()`. ```python def foo[T](x: "T") -> "list[T]": ... get_type_hints(foo) # This would crash because T isn't available. ``` I'm thinking that we need to add a dict of all active type parameters and include this dict as an attribute (e.g. `__type_params__`) for a generic class, function, or type alias. Then `get_type_hints` could access `__type_params__` and merge the type parameter symbols into the locals dictionary before calling `eval`. This way, when it evaluates `list[T]`, it will be able to resolve the name `T` correctly. ```python class Foo[T]: def bar[S](self, a: "T", b: "S") -> "S": ... print(Foo.__type_params__) # { "T": ~T } print(Foo.bar.__type_params__) # { "T": ~T, "S": ~S } print(get_type_hints(Foo.bar)) # { "a": ~T, "b": ~S, "return": ~S } ``` What do you think of that? I may have also come up with a way to revive the idea of using an extra scope. If the extra scope is introduced within a class body (the problematic case I discussed above), any symbols that are local to the class body but required by the inner scope could be passed in as explicit arguments. They don't need to be cell variables if we assume they are read-only within the inner scope. ```python class Parent: class Child1[T]: ... class Child2[T](Child1[T]): ... ``` Would effectively be translated to: ```python class Parent: def __temp1(T): class Child1: ... return Child1 Child1 = __temp1(TypeVar("T")) def __temp2(T, Child1): class Child2(Child1): ... return Child2 Child2 = __temp2(TypeVar("T"), Child1) # Child1 is passed as an explicit argument ``` Thoughts?