Commit 3693a7b8 authored by Mark Florisson's avatar Mark Florisson

Support copying/slice assigning with dtype object

parent 056e3310
...@@ -441,9 +441,10 @@ def copy_broadcast_memview_src_to_dst(src, dst, code): ...@@ -441,9 +441,10 @@ def copy_broadcast_memview_src_to_dst(src, dst, code):
verify_direct_dimensions(dst) verify_direct_dimensions(dst)
code.putln(code.error_goto_if_neg( code.putln(code.error_goto_if_neg(
"%s(%s, %s, %d, %d)" % (copy_src_to_dst_cname(), "%s(%s, %s, %d, %d, %d)" % (copy_src_to_dst_cname(),
src.result(), dst.result(), src.result(), dst.result(),
src.type.ndim, dst.type.ndim), src.type.ndim, dst.type.ndim,
dst.type.dtype.is_pyobject),
dst.pos)) dst.pos))
def copy_c_or_fortran_cname(memview): def copy_c_or_fortran_cname(memview):
...@@ -483,7 +484,8 @@ def get_copy_new_utility(pos, from_memview, to_memview): ...@@ -483,7 +484,8 @@ def get_copy_new_utility(pos, from_memview, to_memview):
dtype_decl=to_memview.dtype.declaration_code(''), dtype_decl=to_memview.dtype.declaration_code(''),
contig_flag=contig_flag, contig_flag=contig_flag,
ndim=to_memview.ndim, ndim=to_memview.ndim,
func_cname=copy_c_or_fortran_cname(to_memview)), func_cname=copy_c_or_fortran_cname(to_memview),
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):
......
...@@ -643,8 +643,9 @@ class MemoryViewSliceType(PyrexType): ...@@ -643,8 +643,9 @@ class MemoryViewSliceType(PyrexType):
to_py_func = "(PyObject *(*)(char *)) " + to_py_func to_py_func = "(PyObject *(*)(char *)) " + to_py_func
from_py_func = "(int (*)(char *, PyObject *)) " + from_py_func from_py_func = "(int (*)(char *, PyObject *)) " + from_py_func
tup = (obj.result(), self.ndim, to_py_func, from_py_func) tup = (obj.result(), self.ndim, to_py_func, from_py_func,
return "__pyx_memoryview_fromslice(&%s, %s, %s, %s);" % tup self.dtype.is_pyobject)
return "__pyx_memoryview_fromslice(&%s, %s, %s, %s, %d);" % tup
def dtype_object_conversion_funcs(self, env): def dtype_object_conversion_funcs(self, env):
import MemoryView, Code import MemoryView, Code
......
This diff is collapsed.
...@@ -162,7 +162,7 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj) { ...@@ -162,7 +162,7 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj) {
{{memviewslice_name}} result = {{memslice_init}}; {{memviewslice_name}} result = {{memslice_init}};
struct __pyx_memoryview_obj *memview = \ struct __pyx_memoryview_obj *memview = \
(struct __pyx_memoryview_obj *) __pyx_memoryview_new(obj, {{buf_flag}}); (struct __pyx_memoryview_obj *) __pyx_memoryview_new(obj, {{buf_flag}}, 0);
__Pyx_BufFmt_StackElem stack[{{struct_nesting_depth}}]; __Pyx_BufFmt_StackElem stack[{{struct_nesting_depth}}];
int axes_specs[] = { {{axes_specs}} }; int axes_specs[] = { {{axes_specs}} };
int retcode; int retcode;
...@@ -464,13 +464,15 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice, ...@@ -464,13 +464,15 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
static {{memviewslice_name}} static {{memviewslice_name}}
__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
const char *mode, int ndim, const char *mode, int ndim,
size_t sizeof_dtype, int contig_flag); size_t sizeof_dtype, int contig_flag,
int dtype_is_object);
////////// MemviewSliceCopyTemplate ////////// ////////// MemviewSliceCopyTemplate //////////
static {{memviewslice_name}} static {{memviewslice_name}}
__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
const char *mode, int ndim, const char *mode, int ndim,
size_t sizeof_dtype, int contig_flag) size_t sizeof_dtype, int contig_flag,
int dtype_is_object)
{ {
__Pyx_RefNannyDeclarations __Pyx_RefNannyDeclarations
int i; int i;
...@@ -515,7 +517,8 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, ...@@ -515,7 +517,8 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
__Pyx_GOTREF(array_obj); __Pyx_GOTREF(array_obj);
memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new( memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
(PyObject *) array_obj, contig_flag); (PyObject *) array_obj, contig_flag,
dtype_is_object);
if (unlikely(!memview_obj)) if (unlikely(!memview_obj))
goto fail; goto fail;
...@@ -523,7 +526,8 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs, ...@@ -523,7 +526,8 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs) < 0)) if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs) < 0))
goto fail; goto fail;
if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim) < 0)) if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
dtype_is_object) < 0))
goto fail; goto fail;
goto no_fail; goto no_fail;
...@@ -544,7 +548,8 @@ no_fail: ...@@ -544,7 +548,8 @@ no_fail:
////////// CopyContentsUtility.proto ///////// ////////// CopyContentsUtility.proto /////////
#define {{func_cname}}(slice) \ #define {{func_cname}}(slice) \
__pyx_memoryview_copy_new_contig(&slice, "{{mode}}", {{ndim}}, \ __pyx_memoryview_copy_new_contig(&slice, "{{mode}}", {{ndim}}, \
sizeof({{dtype_decl}}), {{contig_flag}}) sizeof({{dtype_decl}}), {{contig_flag}}, \
{{dtype_is_object}})
////////// OverlappingSlices.proto ////////// ////////// OverlappingSlices.proto //////////
static int __pyx_slices_overlap({{memviewslice_name}} *slice1, static int __pyx_slices_overlap({{memviewslice_name}} *slice1,
......
...@@ -1880,3 +1880,64 @@ cdef _not_borrowed2(int[:] m): ...@@ -1880,3 +1880,64 @@ cdef _not_borrowed2(int[:] m):
print m[5] print m[5]
if object(): if object():
m = carray m = carray
class SingleObject(object):
def __init__(self, value):
self.value = value
def __str__(self):
return str(self.value)
@testcase
def test_object_dtype_copying():
"""
>>> test_object_dtype_copying()
True
0
1
2
3
4
5
6
7
8
9
3 5
2 5
"""
cdef int i
none_refcount = get_refcount(None)
cdef cython.array a1 = cython.array((10,), sizeof(PyObject *), 'O')
cdef cython.array a2 = cython.array((10,), sizeof(PyObject *), 'O')
print a1.dtype_is_object
cdef object[:] m1 = a1
cdef object[:] m2 = a2
for i in range(10):
# Initialize to None first
(<PyObject **> a1.data)[i] = <PyObject *> None
Py_INCREF(None)
(<PyObject **> a2.data)[i] = <PyObject *> None
Py_INCREF(None)
# now set a unique object
m1[i] = SingleObject(i)
m2[...] = m1
del a1, a2, m1
for i in range(10):
print m2[i]
obj = m2[5]
print get_refcount(obj), obj
del m2
print get_refcount(obj), obj
assert none_refcount == get_refcount(None)
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