else:
self.index = self.index.coerce_to_pyobject(env)
self.type = py_object_type
- self.gil_check(env)
self.is_temp = 1
else:
if self.base.type.is_ptr or self.base.type.is_array:
error(self.pos,
"Invalid index type '%s'" %
self.index.type)
+ self.gil_check(env)
gil_message = "Indexing Python object"
+ def gil_check(self, env):
+ if self.is_buffer_access and env.nogil:
+ if env.directives['boundscheck']:
+ error(self.pos, "Cannot check buffer index bounds without gil; use boundscheck(False) directive")
+ return
+ elif self.type.is_pyobject:
+ error(self.pos, "Cannot access buffer with object dtype without gil")
+ return
+ super(IndexNode, self).gil_check(env)
+
+
def check_const_addr(self):
self.base.check_const_addr()
self.index.check_const()
cimport e_bufaccess_pxd # was needed to provoke a bug involving ErrorType
+import cython
def f():
cdef object[e_bufaccess_pxd.T] buf
+def withnogil_access_fail():
+ cdef object[int] buf = None
+ with nogil:
+ buf[2] = 2
+
+@cython.boundscheck(False)
+def withnogil_access_ok():
+ cdef object[int] buf = None
+ with nogil:
+ buf[2] = 2 # No error should be triggered here
+
+@cython.boundscheck(False)
+def withnogil_access_fail_2():
+ cdef object[object] buf = None
+ with nogil:
+ buf[2] = 2 # Not OK as dtype is object
+
+def withnogil_acquire(x):
+ cdef object[int] buf
+ with nogil:
+ buf = x
+
_ERRORS = u"""
3:9: 'nothing' is not a type identifier
+10:11: Cannot check buffer index bounds without gil; use boundscheck(False) directive
+22:11: Cannot access buffer with object dtype without gil
+22:11: Assignment of Python object not allowed without gil
+27:12: Assignment of Python object not allowed without gil
"""
buf[0].imag += 2
print buf[0].real, buf[0].imag
+#
+# Nogil
+#
+@testcase
+@cython.boundscheck(False)
+def buffer_nogil():
+ """
+ >>> buffer_nogil()
+ 10
+ """
+ cdef object[int] buf = IntMockBuffer(None, [1,2,3])
+ with nogil:
+ buf[1] = 10
+ return buf[1]
+