From efd1e759131ce68abc8bdc4bcd9577572678f705 Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Sat, 9 Mar 2013 09:43:00 +0100 Subject: [PATCH] raise NameError instead of KeyError when del-ing a non-existing name inside of a Python class body --- Cython/Compiler/ExprNodes.py | 17 ++++++++++++----- tests/run/py_classbody.py | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index 924918e..f5c8beb 100755 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1945,13 +1945,20 @@ class NameNode(AtomicExprNode): elif self.entry.is_pyclass_attr: namespace = self.entry.scope.namespace_cname interned_cname = code.intern_identifier(self.entry.name) - del_code = 'PyObject_DelItem(%s, %s)' % (namespace, interned_cname) if ignore_nonexisting: - code.putln('if (unlikely(%s < 0)) { if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) PyErr_Clear(); else %s }' % ( - del_code, - code.error_goto(self.pos))) + key_error_code = 'PyErr_Clear(); else' else: - code.put_error_if_neg(self.pos, del_code) + # minor hack: fake a NameError on KeyError + key_error_code = ( + '{ PyErr_Clear(); PyErr_Format(PyExc_NameError, "name \'%%s\' is not defined", "%s"); }' % + self.entry.name) + code.putln( + 'if (unlikely(PyObject_DelItem(%s, %s) < 0)) {' + ' if (likely(PyErr_ExceptionMatches(PyExc_KeyError))) %s' + ' %s ' + '}' % (namespace, interned_cname, + key_error_code, + code.error_goto(self.pos))) elif self.entry.is_pyglobal: code.globalstate.use_utility_code( UtilityCode.load_cached("PyObjectSetAttrStr", "ObjectHandling.c")) diff --git a/tests/run/py_classbody.py b/tests/run/py_classbody.py index cd8e950..55f3c12 100644 --- a/tests/run/py_classbody.py +++ b/tests/run/py_classbody.py @@ -57,3 +57,21 @@ class ForLoopInPyClass(object): for m in range(2): pass + + +def del_in_class(x): + """ + >>> del_in_class(True) + no error + >>> del_in_class(False) + NameError + """ + try: + class Test(object): + if x: + attr = 1 + del attr + except NameError: + print("NameError") + else: + print("no error") -- 2.7.4