summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2020-01-29 20:27:49 +0000
committerEric Wieser <wieser.eric@gmail.com>2020-06-17 11:26:30 +0100
commit78c01b7046a9cb9f4d28a3d7e1119ec5725e0f6b (patch)
tree0073940bf06f2d20406b08aaf77d1d310a509a6b
parente73c8e5479297f235b37fba91d6d0e8464be66a6 (diff)
downloadnumpy-78c01b7046a9cb9f4d28a3d7e1119ec5725e0f6b.tar.gz
BUG: Ensure PyArray_FromScalar always returns the requested dtype
Fixes gh-15467, where `np.array(np.float64(1), dtype=np.longdouble).dtype.type is np.longdouble` is `False` on windows.
-rw-r--r--numpy/core/src/multiarray/scalarapi.c9
-rw-r--r--numpy/core/tests/test_scalar_ctors.py34
2 files changed, 42 insertions, 1 deletions
diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c
index f3c440dc6..844c1d9cb 100644
--- a/numpy/core/src/multiarray/scalarapi.c
+++ b/numpy/core/src/multiarray/scalarapi.c
@@ -342,7 +342,14 @@ finish:
if (PyArray_EquivTypes(outcode, typecode)) {
if (!PyTypeNum_ISEXTENDED(typecode->type_num)
|| (outcode->elsize == typecode->elsize)) {
- Py_DECREF(typecode); Py_DECREF(outcode);
+ /*
+ * Since the type is equivalent, and we haven't handed the array
+ * to anyone yet, let's fix the dtype to be what was requested,
+ * even if it is equivalent to what was passed in.
+ */
+ Py_SETREF(((PyArrayObject_fields *)r)->descr, outcode);
+ Py_DECREF(typecode);
+
return (PyObject *)r;
}
}
diff --git a/numpy/core/tests/test_scalar_ctors.py b/numpy/core/tests/test_scalar_ctors.py
index 7645a0853..ec4735b8a 100644
--- a/numpy/core/tests/test_scalar_ctors.py
+++ b/numpy/core/tests/test_scalar_ctors.py
@@ -79,3 +79,37 @@ class TestFromInt:
def test_uint64_from_negative(self):
assert_equal(np.uint64(-2), np.uint64(18446744073709551614))
+
+
+int_types = [np.byte, np.short, np.intc, np.int_, np.longlong]
+uint_types = [np.ubyte, np.ushort, np.uintc, np.uint, np.ulonglong]
+float_types = [np.half, np.single, np.double, np.longdouble]
+cfloat_types = [np.csingle, np.cdouble, np.clongdouble]
+
+
+class TestArrayFromScalar:
+ """ gh-15467 """
+
+ def _do_test(self, t1, t2):
+ x = t1(2)
+ arr = np.array(x, dtype=t2)
+ # type should be preserved exactly
+ if t2 is None:
+ assert arr.dtype.type is t1
+ else:
+ assert arr.dtype.type is t2
+
+ @pytest.mark.parametrize('t1', int_types + uint_types)
+ @pytest.mark.parametrize('t2', int_types + uint_types + [None])
+ def test_integers(self, t1, t2):
+ return self._do_test(t1, t2)
+
+ @pytest.mark.parametrize('t1', float_types)
+ @pytest.mark.parametrize('t2', float_types + [None])
+ def test_reals(self, t1, t2):
+ return self._do_test(t1, t2)
+
+ @pytest.mark.parametrize('t1', cfloat_types)
+ @pytest.mark.parametrize('t2', cfloat_types + [None])
+ def test_complex(self, t1, t2):
+ return self._do_test(t1, t2)