Commit 59c8151f authored by Mark Florisson's avatar Mark Florisson

Initialize allocated cython.array buffer with object dtype to None

parent 06c0c96b
...@@ -476,7 +476,7 @@ def assign_scalar(dst, scalar, code): ...@@ -476,7 +476,7 @@ def assign_scalar(dst, scalar, code):
p = slice_iter_obj.start_loops() p = slice_iter_obj.start_loops()
if dtype.is_pyobject: if dtype.is_pyobject:
code.putln("Py_DECREF((PyObject *) %s);" % p) code.putln("Py_DECREF(*(PyObject **) %s);" % p)
code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p)) code.putln("*((%s *) %s) = __pyx_temp_scalar;" % (type_decl, p))
......
...@@ -13,6 +13,10 @@ cdef extern from "Python.h": ...@@ -13,6 +13,10 @@ cdef extern from "Python.h":
PyBUF_FORMAT PyBUF_FORMAT
PyBUF_WRITABLE PyBUF_WRITABLE
ctypedef struct PyObject
PyObject *Py_None
void Py_INCREF(PyObject *)
cdef extern from *: cdef extern from *:
object __pyx_memoryview_new(object obj, int flags, bint dtype_is_object) object __pyx_memoryview_new(object obj, int flags, bint dtype_is_object)
...@@ -45,6 +49,10 @@ cdef class array: ...@@ -45,6 +49,10 @@ cdef class array:
def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None, def __cinit__(array self, tuple shape, Py_ssize_t itemsize, format not None,
mode=u"c", bint allocate_buffer=True): mode=u"c", bint allocate_buffer=True):
cdef int idx
cdef Py_ssize_t i
cdef PyObject **p
self.ndim = len(shape) self.ndim = len(shape)
self.itemsize = itemsize self.itemsize = itemsize
...@@ -68,7 +76,6 @@ cdef class array: ...@@ -68,7 +76,6 @@ cdef class array:
free(self._strides) free(self._strides)
raise MemoryError("unable to allocate shape or strides.") raise MemoryError("unable to allocate shape or strides.")
cdef int idx
# cdef Py_ssize_t dim, stride # cdef Py_ssize_t dim, stride
idx = 0 idx = 0
for idx, dim in enumerate(shape): for idx, dim in enumerate(shape):
...@@ -96,12 +103,17 @@ cdef class array: ...@@ -96,12 +103,17 @@ cdef class array:
self.mode = mode self.mode = mode
self.free_data = allocate_buffer self.free_data = allocate_buffer
self.dtype_is_object = format == b'O'
if allocate_buffer: if allocate_buffer:
self.data = <char *>malloc(self.len) self.data = <char *>malloc(self.len)
if not self.data: if not self.data:
raise MemoryError("unable to allocate array data.") raise MemoryError("unable to allocate array data.")
self.dtype_is_object = format == b'O' if self.dtype_is_object:
p = <PyObject **> self.data
for i in range(self.len / itemsize):
p[i] = Py_None
Py_INCREF(Py_None)
def __getbuffer__(self, Py_buffer *info, int flags): def __getbuffer__(self, Py_buffer *info, int flags):
cdef int bufmode = -1 cdef int bufmode = -1
......
...@@ -1888,13 +1888,11 @@ class SingleObject(object): ...@@ -1888,13 +1888,11 @@ class SingleObject(object):
def __str__(self): def __str__(self):
return str(self.value) return str(self.value)
def __eq__(self, other):
return self.value == getattr(other, 'value', None) or self.value == other
cdef _get_empty_object_slice(fill=None): cdef _get_empty_object_slice(fill=None):
cdef cython.array a = cython.array((10,), sizeof(PyObject *), 'O') cdef cython.array a = cython.array((10,), sizeof(PyObject *), 'O')
cdef int i
for i in range(10):
(<PyObject **> a.data)[i] = <PyObject *> fill
Py_INCREF(fill)
assert a.dtype_is_object assert a.dtype_is_object
return a return a
...@@ -1976,7 +1974,6 @@ def test_scalar_slice_assignment(): ...@@ -1976,7 +1974,6 @@ def test_scalar_slice_assignment():
print print
_test_scalar_slice_assignment(<object> m, <object> m2) _test_scalar_slice_assignment(<object> m, <object> m2)
cdef _test_scalar_slice_assignment(slice_1d m, slice_2d m2): cdef _test_scalar_slice_assignment(slice_1d m, slice_2d m2):
cdef int i, j cdef int i, j
for i in range(10): for i in range(10):
...@@ -2034,3 +2031,15 @@ def test_contig_scalar_to_slice_assignment(): ...@@ -2034,3 +2031,15 @@ def test_contig_scalar_to_slice_assignment():
m[:, :] = 20 m[:, :] = 20
print m[0, 0], m[-1, -1], m[3, 2], m[4, 9] print m[0, 0], m[-1, -1], m[3, 2], m[4, 9]
@testcase
def test_dtype_object_scalar_assignment():
"""
>>> test_dtype_object_scalar_assignment()
"""
cdef object[:] m = cython.array((10,), sizeof(PyObject *), 'O')
m[:] = SingleObject(2)
assert m[0] == m[4] == m[-1] == 2
(<object> m)[:] = SingleObject(3)
assert m[0] == m[4] == m[-1] == 3
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