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):
verify_direct_dimensions(dst)
code.putln(code.error_goto_if_neg(
"%s(%s, %s, %d, %d)" % (copy_src_to_dst_cname(),
src.result(), dst.result(),
src.type.ndim, dst.type.ndim),
"%s(%s, %s, %d, %d, %d)" % (copy_src_to_dst_cname(),
src.result(), dst.result(),
src.type.ndim, dst.type.ndim,
dst.type.dtype.is_pyobject),
dst.pos))
def copy_c_or_fortran_cname(memview):
......@@ -483,7 +484,8 @@ def get_copy_new_utility(pos, from_memview, to_memview):
dtype_decl=to_memview.dtype.declaration_code(''),
contig_flag=contig_flag,
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])
def get_axes_specs(env, axes):
......
......@@ -643,8 +643,9 @@ class MemoryViewSliceType(PyrexType):
to_py_func = "(PyObject *(*)(char *)) " + to_py_func
from_py_func = "(int (*)(char *, PyObject *)) " + from_py_func
tup = (obj.result(), self.ndim, to_py_func, from_py_func)
return "__pyx_memoryview_fromslice(&%s, %s, %s, %s);" % tup
tup = (obj.result(), self.ndim, to_py_func, from_py_func,
self.dtype.is_pyobject)
return "__pyx_memoryview_fromslice(&%s, %s, %s, %s, %d);" % tup
def dtype_object_conversion_funcs(self, env):
import MemoryView, Code
......
This diff is collapsed.
......@@ -162,7 +162,7 @@ static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj) {
{{memviewslice_name}} result = {{memslice_init}};
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}}];
int axes_specs[] = { {{axes_specs}} };
int retcode;
......@@ -464,13 +464,15 @@ static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
static {{memviewslice_name}}
__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
const char *mode, int ndim,
size_t sizeof_dtype, int contig_flag);
size_t sizeof_dtype, int contig_flag,
int dtype_is_object);
////////// MemviewSliceCopyTemplate //////////
static {{memviewslice_name}}
__pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
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
int i;
......@@ -515,7 +517,8 @@ __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
__Pyx_GOTREF(array_obj);
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))
goto fail;
......@@ -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))
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 no_fail;
......@@ -543,8 +547,9 @@ no_fail:
////////// CopyContentsUtility.proto /////////
#define {{func_cname}}(slice) \
__pyx_memoryview_copy_new_contig(&slice, "{{mode}}", {{ndim}}, \
sizeof({{dtype_decl}}), {{contig_flag}})
__pyx_memoryview_copy_new_contig(&slice, "{{mode}}", {{ndim}}, \
sizeof({{dtype_decl}}), {{contig_flag}}, \
{{dtype_is_object}})
////////// OverlappingSlices.proto //////////
static int __pyx_slices_overlap({{memviewslice_name}} *slice1,
......
......@@ -1880,3 +1880,64 @@ cdef _not_borrowed2(int[:] m):
print m[5]
if object():
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