8000 WIP: Dirty way to accept dict views · seberg/numpy@9809763 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9809763

Browse files
committed
WIP: Dirty way to accept dict views
This is probably not right, but shows that it is OK to accept them in principle. We may want to accept only Sequence, in which case python would have to register it. This also cannot be done on older pythons where the fixed order is not a language feature (also fill in that this is actually a language feature).
1 parent 66c6793 commit 9809763

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

numpy/core/src/multiarray/common.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ _array_find_python_scalar_type(PyObject *op)
7676
return NULL;
7777
}
7878

79+
7980
/*
8081
* These constants are used to signal that the recursive dtype determination in
8182
* PyArray_DTypeFromObject encountered a string type, and that the recursive
@@ -429,7 +430,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims,
429430
* be treated as objects, and they expect numpy to treat it as an object if
430431
* __len__ is not defined.
431432
*/
432-
if (maxdims == 0 || !PySequence_Check(obj) || PySequence_Size(obj) < 0) {
433+
if (maxdims == 0 || !NPySequence_Check(obj) || PySequence_Size(obj) < 0) {
433434
/* clear any PySequence_Size error which corrupts further calls */
434435
PyErr_Clear();
435436

numpy/core/src/multiarray/common.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#define NPY_BEGIN_THREADS_NDITER(iter)
2020
#endif
2121

22+
2223
/*
2324
* Recursively examines the object to determine an appropriate dtype
2425
* to use for converting to an ndarray.
@@ -129,6 +130,25 @@ check_and_adjust_index(npy_intp *index, npy_intp max_item, int axis,
129130
return 0;
130131
}
131132

133+
134+
135+
static NPY_INLINE int
136+
NPySequence_Check(PyObject *obj) {
137+
static PyObject *mappingview = NULL;
138+
139+
if (mappingview == NULL) {
140+
PyObject *mod = PyImport_ImportModule("collections.abc");
141+
142+
if (mod != NULL) {
143+
mappingview = PyObject_GetAttrString(mod, "MappingView");
144+
Py_DECREF(mod);
145+
}
146+
}
147+
/* Cannot raise an error here, should be written differently :) */
148+
return (PySequence_Check(obj) || PyObject_IsInstance(obj, mappingview));
149+
}
150+
151+
132152
/*
133153
* Returns -1 and sets an exception if *axis is an invalid axis for
134154
* an array of dimension ndim, otherwise adjusts it in place to be

numpy/core/src/multiarray/ctors.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
typedef int (*next_element)(void **, void *, PyArray_Descr *, void *);
4444
typedef int (*skip_separator)(void **, const char *, void *);
4545

46+
4647
static int
4748
fromstr_next_element(char **s, void *dptr, PyArray_Descr *dtype,
4849
const char *end)
@@ -593,7 +594,7 @@ setArrayFromSequence(PyArrayObject *a, PyObject *s,
593594
NPY_NO_EXPORT int
594595
PyArray_AssignFromSequence(PyArrayObject *self, PyObject *v)
595596
{
596-
if (!PySequence_Check(v)) {
597+
if (!NPySequence_Check(v)) {
597598
PyErr_SetString(PyExc_ValueError,
598599
"assignment from non-sequence");
599600
return -1;
@@ -721,7 +722,7 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it,
721722
}
722723

723724
/* obj is not a Sequence */
724-
if (!PySequence_Check(obj) ||
725+
if (!NPySequence_Check(obj) ||
725726
PySequence_Length(obj) < 0) {
726727
*maxndim = 0;
727728
PyErr_Clear();
@@ -1782,7 +1783,7 @@ PyArray_GetArrayParamsFromObject(PyObject *op,
17821783
}
17831784

17841785
/* Try to treat op as a list of lists or array-like objects. */
1785-
if (!writeable && PySequence_Check(op)) {
1786+
if (!writeable && NPySequence_Check(op)) {
17861787
int check_it, stop_at_string, stop_at_tuple, is_object;
17871788
int type_num, type;
17881789

0 commit comments

Comments
 (0)
0