Commit c7265455 authored by Stefan Behnel's avatar Stefan Behnel

Disable auto-detection of read-only memory views (too unsafe) and acquire them...

Disable auto-detection of read-only memory views (too unsafe) and acquire them only as read-only if the memory view dtype is a "const" type.
parent 3531f69b
......@@ -15,10 +15,8 @@ Features added
* Type inference is now supported for Pythran compiled NumPy expressions.
Patch by Nils Braun. (Github issue #1954)
* Read-only buffers are automatically supported for memoryviews if it can be
determined at compile time that the code does not need write access.
They can also be allowed explicitly by adding the ``const`` modifier to their
declaration. (Github issues #1605, #1869)
* The ``const`` modifier can be applied to memoryview declarations to allow
read-only buffers as input. (Github issues #1605, #1869)
* When compiling with gcc, the module init function is now tuned for small
code size instead of whatever compile flags were provided externally.
......
......@@ -907,9 +907,12 @@ class MemoryViewSliceType(PyrexType):
def from_py_call_code(self, source_code, result_code, error_pos, code,
from_py_function=None, error_condition=None):
# NOTE: auto-detection of readonly buffers is disabled:
# writable = self.writable_needed or not self.dtype.is_const
writable = not self.dtype.is_const
return self._assign_from_py_code(
source_code, result_code, error_pos, code, from_py_function, error_condition,
extra_args=['PyBUF_WRITABLE' if self.writable_needed else '0'])
extra_args=['PyBUF_WRITABLE' if writable else '0'])
def create_to_py_utility_code(self, env):
self._dtype_to_py_func, self._dtype_from_py_func = self.dtype_object_conversion_funcs(env)
......@@ -937,25 +940,29 @@ class MemoryViewSliceType(PyrexType):
if self.dtype.is_pyobject:
utility_name = "MemviewObjectToObject"
else:
to_py = self.dtype.create_to_py_utility_code(env)
from_py = self.dtype.create_from_py_utility_code(env)
if not (to_py or from_py):
return "NULL", "NULL"
self.dtype.create_to_py_utility_code(env)
to_py_function = self.dtype.to_py_function
if not self.dtype.to_py_function:
get_function = "NULL"
from_py_function = None
if not self.dtype.is_const:
self.dtype.create_from_py_utility_code(env)
from_py_function = self.dtype.from_py_function
if not self.dtype.from_py_function:
if not (to_py_function or from_py_function):
return "NULL", "NULL"
if not to_py_function:
get_function = "NULL"
if not from_py_function:
set_function = "NULL"
utility_name = "MemviewDtypeToObject"
error_condition = (self.dtype.error_condition('value') or
'PyErr_Occurred()')
context.update(
to_py_function = self.dtype.to_py_function,
from_py_function = self.dtype.from_py_function,
dtype = self.dtype.empty_declaration_code(),
error_condition = error_condition,
to_py_function=to_py_function,
from_py_function=from_py_function,
dtype=self.dtype.empty_declaration_code(),
error_condition=error_condition,
)
utility = TempitaUtilityCode.load_cached(
......@@ -2456,7 +2463,7 @@ class CArrayType(CPointerBaseType):
def from_py_call_code(self, source_code, result_code, error_pos, code,
from_py_function=None, error_condition=None):
assert not error_condition
assert not error_condition, '%s: %s' % (error_pos, error_condition)
call_code = "%s(%s, %s, %s)" % (
from_py_function or self.from_py_function,
source_code, result_code, self.size)
......
......@@ -244,14 +244,14 @@ Note that this does not *require* the input to be read-only::
a = np.linspace(0, 10, num=50)
myslice = a
Writable buffers will still be accepted by ``const`` views, but read-only
buffers are not accepted for non-const, writable views.
Cython will also request a read-only view automatically if it can determine
at compile time that a writable buffer is not required. The support for
automatically distinguishing between buffer usage types, and the compile
time correctness checks for read-only views are expected to further improve
over time.
Writable buffers are still accepted by ``const`` views, but read-only
buffers are not accepted for non-const, writable views::
cdef double[:] myslice # a normal read-write memory view
a = np.linspace(0, 10, num=50)
a.setflags(write=False)
myslice = a # ERROR: requesting writable memory view from read-only buffer!
Comparison to the old buffer support
......
......@@ -9,9 +9,8 @@ def new_array():
ARRAY = new_array()
cdef getmax(double[:] x):
"""Example code, should work with both
ro and rw memoryviews"""
cdef getmax(const double[:] x):
"""Example code, should work with both ro and rw memoryviews"""
cdef double max_val = -float('inf')
for val in x:
if val > max_val:
......@@ -25,7 +24,7 @@ cdef update_array(double [:] x):
cdef getconst(const double [:] x):
"""Should only accept ro memoryviews"""
"""Should accept ro memoryviews"""
return x[0]
......
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