diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2020-01-29 20:27:49 +0000 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2020-06-17 11:26:30 +0100 |
commit | 78c01b7046a9cb9f4d28a3d7e1119ec5725e0f6b (patch) | |
tree | 0073940bf06f2d20406b08aaf77d1d310a509a6b | |
parent | e73c8e5479297f235b37fba91d6d0e8464be66a6 (diff) | |
download | numpy-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.c | 9 | ||||
-rw-r--r-- | numpy/core/tests/test_scalar_ctors.py | 34 |
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) |