Ah, I see. The fact that B is generic doesn't even matter -- this would also not work:

class A:
    class B: ...
    def method[T](self, arg: B, arg2: T) -> T: ...

because this is effectively translated to something like this:

class A:
    class B: ...
    def _helper():
        T = TypeVar("T")
        def method(self, arg: B, arg2: T) -> T: ...
        return method
    method = _helper()

and the current scoping rules work in such a way that B cannot be seen inside _helper(). Rewriting B a A.B doesn't work either, since A doesn't appear in the global scope until after the class body has executed.

The only solution I can think of would be to define a new kind of scope that has the desired semantics: variable references will first search in that scope (so T is found) and then in its parent scope (so B is found), even if the parent is a class. After that it will follow the regular scoping rules: if the whole thing lives inside a function, that function's scope is visible, but no further class scopes are visible, and of course at the end we have the global and builtin scopes.



On Wed, Jun 22, 2022 at 10:11 PM Eric Traut <eric@traut.com> wrote:
> Do you have an example of such a breaking case that's not using a walrus?

Yes, it breaks for generics declared within a class body if they reference other symbols declared within that class body.

Here are examples of a generic method, generic class, and generic type alias declared within a class body.
```python
class A:
   # This succeeds because it doesn't reference any other symbols
   # within the class A scope.
   class B[T]: ...

   # This fails because B cannot be accessed in the expression "B[T]"
   # if evaluated within an inner scope.
   def method[T](self, b: B[T], c: T): ...

   # This fails because B cannot be accessed in the expression "B[T]"
   # if evaluated within an inner scope.
   class C[T](B[T]): ...

   # This fails because C cannot be accessed in the expression "C[T]"
   # if evaluated within an inner scope.
   type MyAlias[T] = C[T]
```

The problem here is that class scopes don't support cell variables, so there's no way for a variable declared within a class body to be part of an inner scope's closure. All such variables are accessible only within the class scope. For this reason, I don't think it will work to introduce a new scope.
_______________________________________________
Typing-sig mailing list -- typing-sig@python.org
To unsubscribe send an email to typing-sig-leave@python.org
https://mail.python.org/mailman3/lists/typing-sig.python.org/
Member address: guido@python.org


--
--Guido van Rossum (python.org/~guido)
Pronouns: he/him (why is my pronoun here?)