From 129fe22dafd519229e326fca6849151f9c686807 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sun, 16 Dec 2018 16:16:19 -0800 Subject: BUG: Do not duplicate dtype objects when asked to keep the same dtype If we're setting newtype to oldtype, we already know that oldtype is attached to an array, so should be considered sized. --- numpy/core/src/multiarray/ctors.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy') diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 23a8dcea2..f77e414da 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -2024,7 +2024,7 @@ PyArray_FromArray(PyArrayObject *arr, PyArray_Descr *newtype, int flags) newtype = oldtype; Py_INCREF(oldtype); } - if (PyDataType_ISUNSIZED(newtype)) { + else if (PyDataType_ISUNSIZED(newtype)) { PyArray_DESCR_REPLACE(newtype); if (newtype == NULL) { return NULL; -- cgit v1.2.1 From e03283dda358db50e21c4f230c0d2d9d9174a002 Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Sun, 16 Dec 2018 16:25:54 -0800 Subject: BUG: Ensure that arr.ctypes works on arrays with overlapping fields These would previously fail in `from_buffer`, since these arrays cannot be used with the buffer protocol. --- numpy/core/_internal.py | 39 +++++++++++++++++++++++++++++-------- numpy/core/tests/test_multiarray.py | 9 +++++++++ 2 files changed, 40 insertions(+), 8 deletions(-) (limited to 'numpy') diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py index 4b5fda65c..a5742983c 100644 --- a/numpy/core/_internal.py +++ b/numpy/core/_internal.py @@ -244,21 +244,44 @@ class _missing_ctypes(object): self.value = ptr +class _unsafe_first_element_pointer(object): + """ + Helper to allow viewing an array as a ctypes pointer to the first element + + This avoids: + * dealing with strides + * `.view` rejecting object-containing arrays + * `memoryview` not supporting overlapping fields + """ + def __init__(self, arr): + self.base = arr + + @property + def __array_interface__(self): + i = dict( + shape=(), + typestr='|V0', + data=(self.base.__array_interface__['data'][0], False), + strides=(), + version=3, + ) + return i + def _get_void_ptr(arr): """ Get a `ctypes.c_void_p` to arr.data, that keeps a reference to the array """ import numpy as np - # don't let subclasses interfere - arr = arr.view(ndarray) - # collapse the array to point to at most 1 element, so it become contiguous - arr = arr[np.s_[:1,] * arr.ndim + np.s_[...,]] - # then convert to ctypes now that we've reduced it to a simple, empty, array - arr.flags.writeable = True - arr = (ctypes.c_char * 0).from_buffer(arr) + # convert to a 0d array that has a data pointer referrign to the start + # of arr. This holds a reference to arr. + simple_arr = np.asarray(_unsafe_first_element_pointer(arr)) + + # create a `char[0]` using the same memory. + c_arr = (ctypes.c_char * 0).from_buffer(simple_arr) + # finally cast to void* - return ctypes.cast(ctypes.pointer(arr), ctypes.c_void_p) + return ctypes.cast(ctypes.pointer(c_arr), ctypes.c_void_p) class _ctypes(object): diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 171b2ad7f..fa21018ec 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -7480,6 +7480,14 @@ class TestCTypes(object): np.array([1, 2, 3]), np.array([['one', 'two'], ['three', 'four']]), np.array((1, 2), dtype='i4,i4'), + np.zeros((2,), dtype= + np.dtype(dict( + formats=[' Date: Sun, 16 Dec 2018 20:27:55 -0800 Subject: BUG: Fix regression in _missing_ctypes.cast that is not tested in CI --- numpy/core/_internal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'numpy') diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py index a5742983c..523a9f502 100644 --- a/numpy/core/_internal.py +++ b/numpy/core/_internal.py @@ -237,7 +237,7 @@ _getintp_ctype.cache = None class _missing_ctypes(object): def cast(self, num, obj): - return obj.value + return num.value class c_void_p(object): def __init__(self, ptr): -- cgit v1.2.1