Commit fcc76de6 authored by Stefan Behnel's avatar Stefan Behnel

Implement len(memoryview) and allow its usage in nogil sections.

Closes #1733
parent f68f694a
...@@ -2429,6 +2429,14 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2429,6 +2429,14 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
node.pos, "__Pyx_Py_UNICODE_strlen", self.Pyx_Py_UNICODE_strlen_func_type, node.pos, "__Pyx_Py_UNICODE_strlen", self.Pyx_Py_UNICODE_strlen_func_type,
args = [arg], args = [arg],
is_temp = node.is_temp) is_temp = node.is_temp)
elif arg.type.is_memoryviewslice:
func_type = PyrexTypes.CFuncType(
PyrexTypes.c_size_t_type, [
PyrexTypes.CFuncTypeArg("memoryviewslice", arg.type, None)
], nogil=True)
new_node = ExprNodes.PythonCapiCallNode(
node.pos, "__Pyx_MemoryView_Len", func_type,
args=[arg], is_temp=node.is_temp)
elif arg.type.is_pyobject: elif arg.type.is_pyobject:
cfunc_name = self._map_to_capi_len_function(arg.type) cfunc_name = self._map_to_capi_len_function(arg.type)
if cfunc_name is None: if cfunc_name is None:
...@@ -2442,8 +2450,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin, ...@@ -2442,8 +2450,7 @@ class OptimizeBuiltinCalls(Visitor.NodeRefCleanupMixin,
"object of type 'NoneType' has no len()") "object of type 'NoneType' has no len()")
new_node = ExprNodes.PythonCapiCallNode( new_node = ExprNodes.PythonCapiCallNode(
node.pos, cfunc_name, self.PyObject_Size_func_type, node.pos, cfunc_name, self.PyObject_Size_func_type,
args = [arg], args=[arg], is_temp=node.is_temp)
is_temp = node.is_temp)
elif arg.type.is_unicode_char: elif arg.type.is_unicode_char:
return ExprNodes.IntNode(node.pos, value='1', constant_result=1, return ExprNodes.IntNode(node.pos, value='1', constant_result=1,
type=node.type) type=node.type)
......
...@@ -11,6 +11,9 @@ typedef struct { ...@@ -11,6 +11,9 @@ typedef struct {
Py_ssize_t suboffsets[{{max_dims}}]; Py_ssize_t suboffsets[{{max_dims}}];
} {{memviewslice_name}}; } {{memviewslice_name}};
// used for "len(memviewslice)"
#define __Pyx_MemoryView_Len(m) (m.shape[0])
/////////// Atomics.proto ///////////// /////////// Atomics.proto /////////////
......
...@@ -279,6 +279,13 @@ def two_dee(): ...@@ -279,6 +279,13 @@ def two_dee():
assert len(arr) == 2 assert len(arr) == 2
try:
_ = len(mv1)
except UnboundLocalError:
pass
else:
assert False, "UnboundLocalError not raised for uninitialised memory view"
cdef long *arr_data cdef long *arr_data
arr_data = <long*>arr.data arr_data = <long*>arr.data
......
...@@ -1677,7 +1677,7 @@ cdef int cdef_nogil(int[:, :] a) nogil except 0: ...@@ -1677,7 +1677,7 @@ cdef int cdef_nogil(int[:, :] a) nogil except 0:
for j in range(b.shape[1]): for j in range(b.shape[1]):
b[i, j] = -b[i, j] b[i, j] = -b[i, j]
return 1 return len(a)
@testcase @testcase
def test_nogil(): def test_nogil():
...@@ -1690,10 +1690,15 @@ def test_nogil(): ...@@ -1690,10 +1690,15 @@ def test_nogil():
released A released A
""" """
_a = IntMockBuffer("A", range(4 * 9), shape=(4, 9)) _a = IntMockBuffer("A", range(4 * 9), shape=(4, 9))
cdef_nogil(_a) assert cdef_nogil(_a) == 4
cdef int[:, :] a = _a cdef int[:, :] a = _a
print a[2, 7] print a[2, 7]
cdef int length
with nogil:
length = cdef_nogil(a)
assert length == 4
@testcase @testcase
def test_convert_slicenode_to_indexnode(): def test_convert_slicenode_to_indexnode():
""" """
......
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