Commit fd85d226 authored by Stefan Behnel's avatar Stefan Behnel

Turn the copy of a read-only memory view always into a writable memory view.

Closes #2134.
parent 16664cfa
...@@ -484,18 +484,23 @@ def copy_c_or_fortran_cname(memview): ...@@ -484,18 +484,23 @@ def copy_c_or_fortran_cname(memview):
return "__pyx_memoryview_copy_slice_%s_%s" % ( return "__pyx_memoryview_copy_slice_%s_%s" % (
memview.specialization_suffix(), c_or_f) memview.specialization_suffix(), c_or_f)
def get_copy_new_utility(pos, from_memview, to_memview): def get_copy_new_utility(pos, from_memview, to_memview):
if from_memview.dtype != to_memview.dtype: if (from_memview.dtype != to_memview.dtype and
return error(pos, "dtypes must be the same!") not (from_memview.dtype.is_const and from_memview.dtype.const_base_type == to_memview.dtype)):
error(pos, "dtypes must be the same!")
return
if len(from_memview.axes) != len(to_memview.axes): if len(from_memview.axes) != len(to_memview.axes):
return error(pos, "number of dimensions must be same") error(pos, "number of dimensions must be same")
return
if not (to_memview.is_c_contig or to_memview.is_f_contig): if not (to_memview.is_c_contig or to_memview.is_f_contig):
return error(pos, "to_memview must be c or f contiguous.") error(pos, "to_memview must be c or f contiguous.")
return
for (access, packing) in from_memview.axes: for (access, packing) in from_memview.axes:
if access != 'direct': if access != 'direct':
return error( error(pos, "cannot handle 'full' or 'ptr' access at this time.")
pos, "cannot handle 'full' or 'ptr' access at this time.") return
if to_memview.is_c_contig: if to_memview.is_c_contig:
mode = 'c' mode = 'c'
...@@ -516,6 +521,7 @@ def get_copy_new_utility(pos, from_memview, to_memview): ...@@ -516,6 +521,7 @@ def get_copy_new_utility(pos, from_memview, to_memview):
dtype_is_object=int(to_memview.dtype.is_pyobject)), dtype_is_object=int(to_memview.dtype.is_pyobject)),
requires=[copy_contents_new_utility]) requires=[copy_contents_new_utility])
def get_axes_specs(env, axes): def get_axes_specs(env, axes):
''' '''
get_axes_specs(env, axes) -> list of (access, packing) specs for each axis. get_axes_specs(env, axes) -> list of (access, packing) specs for each axis.
......
...@@ -711,8 +711,12 @@ class MemoryViewSliceType(PyrexType): ...@@ -711,8 +711,12 @@ class MemoryViewSliceType(PyrexType):
to_axes_c = follow_dim * (ndim - 1) + contig_dim to_axes_c = follow_dim * (ndim - 1) + contig_dim
to_axes_f = contig_dim + follow_dim * (ndim -1) to_axes_f = contig_dim + follow_dim * (ndim -1)
to_memview_c = MemoryViewSliceType(self.dtype, to_axes_c) dtype = self.dtype
to_memview_f = MemoryViewSliceType(self.dtype, to_axes_f) if dtype.is_const:
dtype = dtype.const_base_type
to_memview_c = MemoryViewSliceType(dtype, to_axes_c)
to_memview_f = MemoryViewSliceType(dtype, to_axes_f)
for to_memview, cython_name in [(to_memview_c, "copy"), for to_memview, cython_name in [(to_memview_c, "copy"),
(to_memview_f, "copy_fortran")]: (to_memview_f, "copy_fortran")]:
......
...@@ -110,3 +110,17 @@ def test_assign_ro_to_rw(x): ...@@ -110,3 +110,17 @@ def test_assign_ro_to_rw(x):
cdef double[:] rw = np.empty_like(ro) cdef double[:] rw = np.empty_like(ro)
rw[:] = ro rw[:] = ro
return rw[2] return rw[2]
def test_copy():
"""
>>> test_copy()
(1.0, 2.0, 1.0, 1.0, 1.0, 2.0)
"""
cdef const double[:] ro = np.ones(3)
cdef const double[:] ro2 = ro.copy()
cdef double[:] rw = ro.copy()
cdef double[:] rw2 = ro2.copy()
rw[1] = 2
rw2[2] = 2
return rw[0], rw[1], rw[2], rw2[0], rw2[1], rw2[2]
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