Commit 0e71f50a authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

nonecheck directive for buffer accesses

parent a5e1aea2
...@@ -1498,6 +1498,8 @@ class IndexNode(ExprNode): ...@@ -1498,6 +1498,8 @@ class IndexNode(ExprNode):
def generate_result_code(self, code): def generate_result_code(self, code):
if self.is_buffer_access: if self.is_buffer_access:
if code.globalstate.directives['nonecheck']:
self.put_nonecheck(code)
ptrcode = self.buffer_lookup_code(code) ptrcode = self.buffer_lookup_code(code)
code.putln("%s = *%s;" % ( code.putln("%s = *%s;" % (
self.result(), self.result(),
...@@ -1541,6 +1543,8 @@ class IndexNode(ExprNode): ...@@ -1541,6 +1543,8 @@ class IndexNode(ExprNode):
def generate_buffer_setitem_code(self, rhs, code, op=""): def generate_buffer_setitem_code(self, rhs, code, op=""):
# Used from generate_assignment_code and InPlaceAssignmentNode # Used from generate_assignment_code and InPlaceAssignmentNode
if code.globalstate.directives['nonecheck']:
self.put_nonecheck(code)
ptrexpr = self.buffer_lookup_code(code) ptrexpr = self.buffer_lookup_code(code)
if self.buffer_type.dtype.is_pyobject: if self.buffer_type.dtype.is_pyobject:
# Must manage refcounts. Decref what is already there # Must manage refcounts. Decref what is already there
...@@ -1607,6 +1611,13 @@ class IndexNode(ExprNode): ...@@ -1607,6 +1611,13 @@ class IndexNode(ExprNode):
options=code.globalstate.directives, options=code.globalstate.directives,
pos=self.pos, code=code) 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): class SliceIndexNode(ExprNode):
# 2-element slice indexing # 2-element slice indexing
# #
...@@ -4587,3 +4598,12 @@ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) { ...@@ -4587,3 +4598,12 @@ static INLINE void __Pyx_RaiseNoneAttributeError(char* attrname) {
PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%s'", 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");
}
"""]
...@@ -32,6 +32,16 @@ Traceback (most recent call last): ...@@ -32,6 +32,16 @@ Traceback (most recent call last):
... ...
AttributeError: 'NoneType' object has no attribute 'a' 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 cimport cython
...@@ -70,3 +80,11 @@ def check_and_assign(MyClass var): ...@@ -70,3 +80,11 @@ def check_and_assign(MyClass var):
var = None var = None
print var.a 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment