[Cython] Class scope lookup order

Vitja Makarov vitja.makarov at gmail.com
Mon Aug 15 13:03:02 CEST 2011


2011/8/15 Stefan Behnel <stefan_ml at behnel.de>:
> Vitja Makarov, 15.08.2011 11:55:
>>
>> 2011/8/15 Stefan Behnel:
>>>
>>> Stefan Behnel, 15.08.2011 11:34:
>>>>
>>>> at least to me, the most surprising thing is this:
>>>>
>>>>  >>>  A = 1
>>>>  >>>  def foo(x):
>>>>  ...   A = x
>>>>  ...   class X:
>>>>  ...     a = A
>>>>  ...   return X
>>>>  ...
>>>>  >>>  foo(2).a
>>>>  2
>>>>  >>>  def foo(x):
>>>>  ...   A = x
>>>>  ...   class X:
>>>>  ...     A = A
>>>>  ...   return X
>>>>  ...
>>>>  >>>  foo(2).A
>>>>  1
>>>>
>>>> That looks pretty sick, but I would guess that the 'reasoning' behind
>>>> this
>>>> is that the second case contains an assignment to A inside of the class
>>>> namespace, and assignments make a variable local to a scope, in this
>>>> case,
>>>> the function scope.
>>>
>>> Argh, sorry, I interpreted the results the wrong way around.
>
> ... or rather used the right reasoning to draw the wrong conclusion. ;)
>
> Ok, so there's an assignment in the second case, which makes A local to the
> class scope, thus overriding the definition in the function scope. Now, when
> it's being looked up at runtime, it's not in the class locals, so the lookup
> falls through to the globals. In the first case, it's not defined in the
> class scope at all, so it's taken from the surrounding function scope
> directly (and statically).
>
>
>> I've tried emulate this behaviour in cython here:
>>
>>
>> https://github.com/vitek/cython/commit/26ec702fd93fb6dc2109a501b52130e5f775c793
>
> My feeling is that it should rather be a matter of static analysis to figure
> out which is meant, although I think your change mimics what CPython does. I
> guess this would fix #671, right?
>

Yes. And I use CF info in my commit.

>
>> Actually I think this is made to support assignments like A = A in class
>> scope.
>
> This behaviour wouldn't be strictly required for that goal. My guess is that
> it was just simpler to implement in CPython, because it has less special
> cases. Having to look up a name in a series of outer scopes in the case that
> it happens not to be defined in a class scope yet (although it is known to
> get defined therein at some point), or even remembering the right scope
> where it needs to get looked up, is trickier than just falling through to
> the globals.
>

It's documented here:

http://docs.python.org/reference/executionmodel.html#interaction-with-dynamic-features

"""
Names may be resolved in the local and global namespaces of the
caller. Free variables are not resolved in the nearest enclosing
namespace, but in the global namespace.
"""



-- 
vitja.


More information about the cython-devel mailing list