Commit 05f7a479 authored by da-woods's avatar da-woods Committed by GitHub

Make memoryviews work with cache_builtins=False (GH-3415)

Now they make their own tiny cache of the relevant exceptions at module initialization so they can still access these without the GIL.

closes https://github.com/cython/cython/issues/3406
parent e6723d4d
......@@ -8,8 +8,12 @@ cimport cython
# from cpython cimport ...
cdef extern from "Python.h":
ctypedef struct PyObject
int PyIndex_Check(object)
object PyLong_FromVoidPtr(void *)
PyObject *PyExc_IndexError
PyObject *PyExc_ValueError
PyObject *PyExc_MemoryError
cdef extern from "pythread.h":
ctypedef void *PyThread_type_lock
......@@ -94,9 +98,6 @@ cdef extern from "<stdlib.h>":
void free(void *) nogil
void *memcpy(void *dest, void *src, size_t n) nogil
#
### cython.array class
#
......@@ -829,13 +830,13 @@ cdef int slice_memviewslice(
if start < 0:
start += shape
if not 0 <= start < shape:
_err_dim(IndexError, "Index out of bounds (axis %d)", dim)
_err_dim(PyExc_IndexError, "Index out of bounds (axis %d)", dim)
else:
# index is a slice
negative_step = have_step != 0 and step < 0
if have_step and step == 0:
_err_dim(ValueError, "Step may not be zero (axis %d)", dim)
_err_dim(PyExc_ValueError, "Step may not be zero (axis %d)", dim)
# check our bounds and set defaults
if have_start:
......@@ -896,7 +897,7 @@ cdef int slice_memviewslice(
if new_ndim == 0:
dst.data = (<char **> dst.data)[0] + suboffset
else:
_err_dim(IndexError, "All dimensions preceding dimension %d "
_err_dim(PyExc_IndexError, "All dimensions preceding dimension %d "
"must be indexed and not sliced", dim)
else:
suboffset_dim[0] = new_ndim
......@@ -954,7 +955,7 @@ cdef int transpose_memslice({{memviewslice_name}} *memslice) nogil except 0:
shape[i], shape[j] = shape[j], shape[i]
if memslice.suboffsets[i] >= 0 or memslice.suboffsets[j] >= 0:
_err(ValueError, "Cannot transpose memoryview with indirect dimensions")
_err(PyExc_ValueError, "Cannot transpose memoryview with indirect dimensions")
return 1
......@@ -1221,7 +1222,7 @@ cdef void *copy_data_to_temp({{memviewslice_name}} *src,
result = malloc(size)
if not result:
_err(MemoryError, NULL)
_err(PyExc_MemoryError, NULL)
# tmpslice[0] = src
tmpslice.data = <char *> result
......@@ -1254,15 +1255,15 @@ cdef int _err_extents(int i, Py_ssize_t extent1,
(i, extent1, extent2))
@cname('__pyx_memoryview_err_dim')
cdef int _err_dim(object error, char *msg, int dim) except -1 with gil:
raise error(msg.decode('ascii') % dim)
cdef int _err_dim(PyObject *error, char *msg, int dim) except -1 with gil:
raise (<object>error)(msg.decode('ascii') % dim)
@cname('__pyx_memoryview_err')
cdef int _err(object error, char *msg) except -1 with gil:
cdef int _err(PyObject *error, char *msg) except -1 with gil:
if msg != NULL:
raise error(msg.decode('ascii'))
raise (<object>error)(msg.decode('ascii'))
else:
raise error
raise (<object>error)
@cname('__pyx_memoryview_copy_contents')
cdef int memoryview_copy_contents({{memviewslice_name}} src,
......@@ -1297,7 +1298,7 @@ cdef int memoryview_copy_contents({{memviewslice_name}} src,
_err_extents(i, dst.shape[i], src.shape[i])
if src.suboffsets[i] >= 0:
_err_dim(ValueError, "Dimension %d is not direct", i)
_err_dim(PyExc_ValueError, "Dimension %d is not direct", i)
if slices_overlap(&src, &dst, ndim, itemsize):
# slices overlap, copy to temp, copy temp to dst
......
......@@ -24,16 +24,16 @@ def foo(dtype_t[:] a, dtype_t_out[:, :] b):
_WARNINGS = """
22:10: 'cpdef_method' redeclared
33:10: 'cpdef_cname_method' redeclared
446:72: Argument evaluation order in C function call is undefined and may not be as expected
446:72: Argument evaluation order in C function call is undefined and may not be as expected
749:34: Argument evaluation order in C function call is undefined and may not be as expected
749:34: Argument evaluation order in C function call is undefined and may not be as expected
943:27: Ambiguous exception value, same as default return value: 0
943:27: Ambiguous exception value, same as default return value: 0
974:29: Ambiguous exception value, same as default return value: 0
974:29: Ambiguous exception value, same as default return value: 0
1002:46: Ambiguous exception value, same as default return value: 0
1002:46: Ambiguous exception value, same as default return value: 0
1092:29: Ambiguous exception value, same as default return value: 0
1092:29: Ambiguous exception value, same as default return value: 0
447:72: Argument evaluation order in C function call is undefined and may not be as expected
447:72: Argument evaluation order in C function call is undefined and may not be as expected
750:34: Argument evaluation order in C function call is undefined and may not be as expected
750:34: Argument evaluation order in C function call is undefined and may not be as expected
944:27: Ambiguous exception value, same as default return value: 0
944:27: Ambiguous exception value, same as default return value: 0
975:29: Ambiguous exception value, same as default return value: 0
975:29: Ambiguous exception value, same as default return value: 0
1003:46: Ambiguous exception value, same as default return value: 0
1003:46: Ambiguous exception value, same as default return value: 0
1093:29: Ambiguous exception value, same as default return value: 0
1093:29: Ambiguous exception value, same as default return value: 0
"""
PYTHON setup.py build_ext --inplace
################ setup.py #####################
from distutils.core import setup
from Cython.Build import cythonize
from Cython.Compiler import Options
Options.cache_builtins = False
setup(
ext_modules = cythonize("mview.pyx")
)
############### mview.pyx ################
# https://github.com/cython/cython/issues/3406
# Failure was at Cython compilation stage
def f(double [::1] x):
pass
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