From: Dag Sverre Seljebotn Date: Thu, 25 Sep 2008 16:33:27 +0000 (+0200) Subject: nonecheck directive for buffer accesses X-Git-Tag: 0.9.9.2.beta~83^2 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=0e71f50a863e199992746e6caf7a23a3aecfa7f9;p=cython.git nonecheck directive for buffer accesses --- diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index cd9a5a46..2c7aaf44 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -1498,6 +1498,8 @@ class IndexNode(ExprNode): def generate_result_code(self, code): if self.is_buffer_access: + if code.globalstate.directives['nonecheck']: + self.put_nonecheck(code) ptrcode = self.buffer_lookup_code(code) code.putln("%s = *%s;" % ( self.result(), @@ -1541,6 +1543,8 @@ class IndexNode(ExprNode): def generate_buffer_setitem_code(self, rhs, code, op=""): # Used from generate_assignment_code and InPlaceAssignmentNode + if code.globalstate.directives['nonecheck']: + self.put_nonecheck(code) ptrexpr = self.buffer_lookup_code(code) if self.buffer_type.dtype.is_pyobject: # Must manage refcounts. Decref what is already there @@ -1607,6 +1611,13 @@ class IndexNode(ExprNode): options=code.globalstate.directives, pos=self.pos, code=code) + def put_nonecheck(self, code): + code.globalstate.use_utility_code(raise_noneindex_error_utility_code) + code.putln("if (%s) {" % code.unlikely("%s == Py_None") % self.base.result_as(PyrexTypes.py_object_type)) + code.putln("__Pyx_RaiseNoneIndexingError();") + code.putln(code.error_goto(self.pos)) + code.putln("}") + class SliceIndexNode(ExprNode): # 2-element slice indexing # @@ -4587,3 +4598,12 @@ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) { PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", attrname); } """] + +raise_noneindex_error_utility_code = [ +""" +static INLINE void __Pyx_RaiseNoneIndexingError(); +""", """ +static INLINE void __Pyx_RaiseNoneIndexingError() { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is unsubscriptable"); +} +"""] diff --git a/tests/run/nonecheck.pyx b/tests/run/nonecheck.pyx index 7645acd0..79ba6f10 100644 --- a/tests/run/nonecheck.pyx +++ b/tests/run/nonecheck.pyx @@ -32,6 +32,16 @@ Traceback (most recent call last): ... AttributeError: 'NoneType' object has no attribute 'a' +>>> check_buffer_get(None) +Traceback (most recent call last): + ... +TypeError: 'NoneType' object is unsubscriptable + +>>> check_buffer_set(None) +Traceback (most recent call last): + ... +TypeError: 'NoneType' object is unsubscriptable + """ cimport cython @@ -70,3 +80,11 @@ def check_and_assign(MyClass var): var = None print var.a +@cython.nonecheck(True) +def check_buffer_get(object[int] buf): + return buf[0] + +@cython.nonecheck(True) +def check_buffer_set(object[int] buf): + buf[0] = 1 +