On 16/01/21 9:38 am, Guido van Rossum wrote:
> On Fri, Jan 15, 2021 at 10:53 AM Larry Hastings <larry@hastings.org
> <mailto:larry@hastings.org>> wrote:
>
> class OuterCls:
> class InnerCls:
> def method(a:OuterCls.InnerCls=None): pass
>
> We've turned the local reference into a global reference, and we
> already know globals work fine.
[Above was what Larry wrote, the rest is me. I guess Greg's mailer is having trouble with the GMail-style quoting. :-( ]
> I think this is going too far. A static method defined in InnerCls does
> not see InnerCls (even after the class definitions are complete). E.g.
> ```
> class Outer:
> class Inner:
> @staticmethod
> def foo(): return Inner
> ```
> If you then call Outer.Inner.foo() you get "NameError: name 'Inner' is
> not defined".
[Greg]
I'm not so sure about that. Conceptually, annotations are evaluated
in the environment existing when the class scope is being constructed.
The fact that we're moving them into a closure is an implementation
detail that I don't think should be exposed.
Yeah, that wasn't very clear, and I'm not 100% sure I got it right. But consider this:
```
class Outer:
foo = 1
class Inner:
print(foo)
```
This gives "NameError: name 'foo' is not defined". And here there is no forward reference involved, and foo lives in the exactly the same scope/namespace as Inner.
The reason for the NameError is that class scopes don't participate in the closure game (an intentional design quirk to avoid methods referencing unqualified class variables).
So I still think that Larry's example shouldn't (have to) work.
(I agree with Greg on the 'zebra' example.)