[Cython] cython-devel-tests-pyregr regression
Vitja Makarov
vitja.makarov at gmail.com
Thu Aug 23 07:42:05 CEST 2012
2012/8/23 Vitja Makarov <vitja.makarov at gmail.com>:
> 2012/8/23 Vitja Makarov <vitja.makarov at gmail.com>:
>> 2012/8/23 Stefan Behnel <stefan_ml at behnel.de>:
>>> Vitja Makarov, 23.08.2012 07:03:
>>>> 2012/8/23 Stefan Behnel <stefan_ml at behnel.de>:
>>>>> Vitja Makarov, 22.08.2012 22:34:
>>>>>> 2012/8/23 Stefan Behnel:
>>>>>>> Vitja Makarov, 22.08.2012 22:11:
>>>>>>>> I've found regression:
>>>>>>>>
>>>>>>>> https://sage.math.washington.edu:8091/hudson/job/cython-devel-tests-pyregr/
>>>>>>>
>>>>>>> Interesting. It's a Py2 list comprehension in a class body that's failing here:
>>>>>>>
>>>>>>> """
>>>>>>> class TestHelpSubparsersOrdering(HelpTestCase):
>>>>>>> subparsers_signatures = [Sig(name=name)
>>>>>>> for name in ('a', 'b', 'c', 'd', 'e')]
>>>>>>> """
>>>>>>>
>>>>>>> I wonder why "name" isn't declared as a variable yet at the point where it
>>>>>>> is being looked up in the function call.
>>>>>>
>>>>>> def lookup_relative(self, name, pos):
>>>>>> if name == "name":
>>>>>> print name
>>>>>> from ipdb import set_trace; set_trace()
>>>>>> entry = self.lookup_here(name)
>>>>>> if entry is not None and entry.pos[1:] <= pos[1:]: # Lookup fails here
>>>>>> return entry
>>>>>> if self.outer_scope:
>>>>>> return self.outer_scope.lookup_relative(name, pos)
>>>>>> return None
>>>>>>
>>>>>>
>>>>>> What is that comparison for?
>>>>>
>>>>> Ah, yes, it is wrong in this context. It was meant to prevent names defined
>>>>> further down in the class body from being considered assignments to the
>>>>> name being looked up. Class bodies are not function bodies, assignments in
>>>>> them do not make a name "local". As long as it's not assigned, it's not
>>>>> defined and must be looked up in the outer scope.
>>>>
>>>> Do you remember this ticket #671
>>>>
>>>> If there is assignment in the class body we first lookup in the class
>>>> dict and then in globals.
>>>>
>>>> B = 0
>>>> def foo():
>>>> B = 1
>>>> class Foo():
>>>> A = B
>>>> B = B
>>>> class Bar():
>>>> A = B
>>>> print Foo.A, Foo.B, Bar.A
>>>> foo()
>>>>
>>>> prints "0 0 1"
>>>
>>> In the case at hand, it's not an assignment but a method declaration. Maybe
>>> that makes a difference.
>>>
>>> In any case, this needs some more investigation than I did for my change. I
>>> think it can be rolled back completely.
>>>
>>>
>>>>> I think comprehensions are actually the only case where a name is used in
>>>>> the source before its declaration. It should work in all other cases.
>>>>>
>>>>> I had considered solving this problem with the flow control analysis
>>>>> information, but I can't see how that helps me to figure out if an entry is
>>>>> already assigned (i.e. declared) at a given point in the class body.
>>>>>
>>>>> Any idea?
>>>>
>>>> What would you do with maybe assigned case?
>>>
>>> Hmm, yes - I guess we can't solve the general case at compile time. That's
>>> unfortunate, though, because it prevents proper compile time optimisation
>>> of builtins in class bodies when their names are assigned at some point,
>>> e.g. with a ".type()" method or ".set()", as was the case here.
>>>
>>> Stefan
>>>
>>
>>
>>
>> This is NameNode related problem
>>
>> The following code would fail as well:
>> XXX = 123
>> class Foo(object):
>> t1 = XXX # XXX cf_is_null = True
>> t2 = XXX # XXX cf_is_null = False
>> XXX = 123
>>
>> CF assumes that after first apperence of NULL name it must be then set
>> otherwise exception must be raised.
>> NameNode code relays on CF here, so I think it mustn't. We must
>> allways check result of PyObject_GetItem() and if's NULL look at the
>> globals then.
>>
>> I'll try to fix it soon.
>>
>>
>
> I've reverted your commit and here is my fix:
> https://github.com/vitek/cython/commit/198f254f62360b61c895ba68be0f4dbe07444449
>
> Cause of different class scope lookup rules I think we can't fully
> trust CF here.
>
Another (maybe better) solution is to fix CF. It mustn't set
cf_maybe_null to False at class scope based on reference success.
--
vitja.
More information about the cython-devel
mailing list