[Cython] cython-devel-tests-pyregr regression

Vitja Makarov vitja.makarov at gmail.com
Thu Aug 23 22:13:19 CEST 2012


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:42:
>>> 2012/8/23 Vitja Makarov:
>>>> 2012/8/23 Vitja Makarov:
>>>>> 2012/8/23 Stefan Behnel:
>>>>>> Vitja Makarov, 23.08.2012 07:03:
>>>>>>> 2012/8/23 Stefan Behnel:
>>>>>>>> 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'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.
>>
>> I've pushed these changes to the master for now. They are correct, even if
>> we decide to improve the control flow decisions here (which would only lead
>> to the same effect anyway).
>>
>
> Ok, I'll take a look later.
>

Here is fix from CF point of view:
https://github.com/vitek/cython/commit/cbd676c598a7ea0ba61262d46c1c733d362c68da

Let's wait for jenkins now.


-- 
vitja.


More information about the cython-devel mailing list