summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/dtypemeta.c31
-rw-r--r--numpy/core/tests/test_array_coercion.py16
2 files changed, 44 insertions, 3 deletions
diff --git a/numpy/core/src/multiarray/dtypemeta.c b/numpy/core/src/multiarray/dtypemeta.c
index 531f746d8..dbe5ba476 100644
--- a/numpy/core/src/multiarray/dtypemeta.c
+++ b/numpy/core/src/multiarray/dtypemeta.c
@@ -204,8 +204,32 @@ nonparametric_default_descr(PyArray_DTypeMeta *cls)
}
+/* Ensure a copy of the singleton (just in case we do adapt it somewhere) */
static PyArray_Descr *
-flexible_default_descr(PyArray_DTypeMeta *cls)
+datetime_and_timedelta_default_descr(PyArray_DTypeMeta *cls)
+{
+ return PyArray_DescrNew(cls->singleton);
+}
+
+
+static PyArray_Descr *
+void_default_descr(PyArray_DTypeMeta *cls)
+{
+ PyArray_Descr *res = PyArray_DescrNew(cls->singleton);
+ if (res == NULL) {
+ return NULL;
+ }
+ /*
+ * The legacy behaviour for `np.array([], dtype="V")` is to use "V8".
+ * This is because `[]` uses `float64` as dtype, and then that is used
+ * for the size of the requested void.
+ */
+ res->elsize = 8;
+ return res;
+}
+
+static PyArray_Descr *
+string_and_unicode_default_descr(PyArray_DTypeMeta *cls)
{
PyArray_Descr *res = PyArray_DescrNewFromType(cls->type_num);
if (res == NULL) {
@@ -534,7 +558,7 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
else if (PyTypeNum_ISDATETIME(descr->type_num)) {
/* Datetimes are flexible, but were not considered previously */
dtype_class->parametric = NPY_TRUE;
- dtype_class->default_descr = flexible_default_descr;
+ dtype_class->default_descr = datetime_and_timedelta_default_descr;
dtype_class->discover_descr_from_pyobject = (
discover_datetime_and_timedelta_from_pyobject);
dtype_class->common_dtype = datetime_common_dtype;
@@ -545,13 +569,14 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
}
else if (PyTypeNum_ISFLEXIBLE(descr->type_num)) {
dtype_class->parametric = NPY_TRUE;
- dtype_class->default_descr = flexible_default_descr;
if (descr->type_num == NPY_VOID) {
+ dtype_class->default_descr = void_default_descr;
dtype_class->discover_descr_from_pyobject = (
void_discover_descr_from_pyobject);
dtype_class->common_instance = void_common_instance;
}
else {
+ dtype_class->default_descr = string_and_unicode_default_descr;
dtype_class->is_known_scalar_type = string_known_scalar_types;
dtype_class->discover_descr_from_pyobject = (
string_discover_descr_from_pyobject);
diff --git a/numpy/core/tests/test_array_coercion.py b/numpy/core/tests/test_array_coercion.py
index a6c8cc8b2..e0480c7bf 100644
--- a/numpy/core/tests/test_array_coercion.py
+++ b/numpy/core/tests/test_array_coercion.py
@@ -324,6 +324,22 @@ class TestScalarDiscovery:
ass[()] = scalar
assert_array_equal(ass, cast)
+ @pytest.mark.parametrize("dtype_char", np.typecodes["All"])
+ def test_default_dtype_instance(self, dtype_char):
+ if dtype_char in "SU":
+ dtype = np.dtype(dtype_char + "1")
+ elif dtype_char == "V":
+ # Legacy behaviour was to use V8. The reason was float64 being the
+ # default dtype and that having 8 bytes.
+ dtype = np.dtype("V8")
+ else:
+ dtype = np.dtype(dtype_char)
+
+ discovered_dtype, _ = _discover_array_parameters([], type(dtype))
+
+ assert discovered_dtype == dtype
+ assert discovered_dtype.itemsize == dtype.itemsize
+
class TestTimeScalars:
@pytest.mark.parametrize("dtype", [np.int64, np.float32])