On Mar 12, 2010, at 11:39 PM, Stefan Behnel wrote:
> Lisandro Dalcin, 12.03.2010 22:33:
>> See the testcase below. If the body of the except clause is empty,
>> 'e'
>> never gets assigned to the exception value, ie...
>>
>> """
>>>>> repr(e)
>> 'ValueError()'
>> """
>>
>> e = None
>> try:
>> raise ValueError
>> except ValueError, e:
>> #a = 1
>> pass
>>
>> Could any of you fix this in order I can properly implement and test
>> "except A as B" ?? The fix should be done in "Nodes.py", at
>> "generate_handling_code()" ... The obvious patch is the one below,
>> but
>> perhaps you can imagine a better way?
>>
>> diff -r 3932a0be3b6b Cython/Compiler/Nodes.py
>> --- a/Cython/Compiler/Nodes.py Thu Mar 11 18:57:06 2010 -0300
>> +++ b/Cython/Compiler/Nodes.py Fri Mar 12 18:30:43 2010 -0300
>> @@ -4497,14 +4497,6 @@
>> else:
>> code.putln("/*except:*/ {")
>>
>> - if not getattr(self.body, 'stats', True):
>> - # most simple case: no exception variable, empty body
>> (pass)
>> - # => reset the exception state, done
>> - code.putln("PyErr_Restore(0,0,0);")
>> - code.put_goto(end_label)
>> - code.putln("}")
>> - return
>> -
>> exc_vars = [code.funcstate.allocate_temp(py_object_type,
>> manage_ref=True)
>> for i in xrange(3)]
>
> Funny. I just tried this with Py3 and it gives me this:
>
>
> Python 3.1.1+ (r311:74480, Nov 2 2009, 15:45:00)
> [GCC 4.4.1] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> e = None
>>>> try: raise ValueError
> ... except ValueError as e: pass
> ...
>>>> e
> Traceback (most recent call last):
> File "<stdin>", line 1, in <module>
> NameError: name 'e' is not defined
>
>
> So you could argue that Cython is better behaved than Py3 here. ;)
>
> I files a bug report on Py3 for now.
>
> http://bugs.python.org/issue8130
>
> Anyway, given that keeping the variable inside of the except block
> is the
> expected behaviour in Py3, I think this should not be 'fixed'.
In the face of differing behavior Cython follows Python 2.x scoping
conventions, e.g. the same issue arises for list comprehensions. In
any case, it's bad that the empty except block behaves differently
than the non-empty one.
>> PS: Is this an instance of "premature optimization is the root of all
>> evil" ??
>
> I actually implemented it at the time because Python 3 was supposed to
> behave like this, and the reason for the change in Py3 was that
> exceptions
> (and their tracebacks, i.e. all impacted frames!) should never be kept
> alive any longer than strictly necessary. The official way to get the
> behaviour you want in Py3 is this:
>
> e = None
> try: raise ValueError
> except ValueError as err:
> e = err
>
> with 'err' not being defined outside of the except block.
The problem is this comment:
>> # most simple case: no exception variable, empty body (pass)
which is *not* what is being tested. Anyone opposed to
diff -r 587136bd1d75 Cython/Compiler/Nodes.py
--- a/Cython/Compiler/Nodes.py Sat Mar 13 08:24:13 2010 +0100
+++ b/Cython/Compiler/Nodes.py Sat Mar 13 00:24:33 2010 -0800
@@ -4497,7 +4497,8 @@
else:
code.putln("/*except:*/ {")
- if not getattr(self.body, 'stats', True):
+ if not getattr(self.body, 'stats', True) and
+ self.excinfo_target is None and self.target is None):
# most simple case: no exception variable, empty body
(pass)
# => reset the exception state, done
code.putln("PyErr_Restore(0,0,0);")
- Robert
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev