diff options
| -rw-r--r-- | numpy/core/src/multiarray/ctors.c | 5 | ||||
| -rw-r--r-- | numpy/core/tests/test_multiarray.py | 52 |
2 files changed, 39 insertions, 18 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 23a8dcea2..259ee9aac 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -2495,6 +2495,11 @@ PyArray_FromInterface(PyObject *origin) &PyArray_Type, dtype, n, dims, NULL, data, dataflags, NULL, base); + /* + * Ref to dtype was stolen by PyArray_NewFromDescrAndBase + * Prevent DECREFing dtype in fail codepath by setting to NULL + */ + dtype = NULL; if (ret == NULL) { goto fail; } diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index cdacdabbe..9460e4fc6 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -6999,12 +6999,11 @@ class TestArrayAttributeDeletion(object): assert_raises(AttributeError, delattr, a, s) -def test_array_interface(): - # Test scalar coercion within the array interface +class TestArrayInterface(): class Foo(object): def __init__(self, value): self.value = value - self.iface = {'typestr': '=f8'} + self.iface = {'typestr': 'f8'} def __float__(self): return float(self.value) @@ -7013,22 +7012,39 @@ def test_array_interface(): def __array_interface__(self): return self.iface + f = Foo(0.5) - assert_equal(np.array(f), 0.5) - assert_equal(np.array([f]), [0.5]) - assert_equal(np.array([f, f]), [0.5, 0.5]) - assert_equal(np.array(f).dtype, np.dtype('=f8')) - # Test various shape definitions - f.iface['shape'] = () - assert_equal(np.array(f), 0.5) - f.iface['shape'] = None - assert_raises(TypeError, np.array, f) - f.iface['shape'] = (1, 1) - assert_equal(np.array(f), [[0.5]]) - f.iface['shape'] = (2,) - assert_raises(ValueError, np.array, f) - - # test scalar with no shape + + @pytest.mark.parametrize('val, iface, expected', [ + (f, {}, 0.5), + ([f], {}, [0.5]), + ([f, f], {}, [0.5, 0.5]), + (f, {'shape': ()}, 0.5), + (f, {'shape': None}, TypeError), + (f, {'shape': (1, 1)}, [[0.5]]), + (f, {'shape': (2,)}, ValueError), + (f, {'strides': ()}, 0.5), + (f, {'strides': (2,)}, ValueError), + (f, {'strides': 16}, TypeError), + ]) + def test_scalar_interface(self, val, iface, expected): + # Test scalar coercion within the array interface + self.f.iface = {'typestr': 'f8'} + self.f.iface.update(iface) + if HAS_REFCOUNT: + pre_cnt = sys.getrefcount(np.dtype('f8')) + if isinstance(expected, type): + assert_raises(expected, np.array, val) + else: + result = np.array(val) + assert_equal(np.array(val), expected) + assert result.dtype == 'f8' + del result + if HAS_REFCOUNT: + post_cnt = sys.getrefcount(np.dtype('f8')) + assert_equal(pre_cnt, post_cnt) + +def test_interface_no_shape(): class ArrayLike(object): array = np.array(1) __array_interface__ = array.__array_interface__ |
