diff options
| author | Pauli Virtanen <pav@iki.fi> | 2018-04-07 23:37:20 +0200 |
|---|---|---|
| committer | Pauli Virtanen <pav@iki.fi> | 2018-04-08 17:34:02 +0200 |
| commit | 18fd6a43f57ebd8b38b29cc800677932bbfe51cd (patch) | |
| tree | b8e82d441dc2f8fb0623c04a36360b416879430b /numpy/core/include | |
| parent | b8e8a6ee1f032474a0119fa0c0a6dfb51355abd6 (diff) | |
| download | numpy-18fd6a43f57ebd8b38b29cc800677932bbfe51cd.tar.gz | |
BUG: core: fix NPY_TITLE_KEY macro on pypy
On Pypy, dictionary keys do not necessarily preserve object identity.
This however was assumed by the NPY_TITLE_KEY macro, which relies on
descriptor.c:568 using the same 'title' object both as a dictionary key
as an entry in the tuple inserted.
Since the items in the field dict are unique, value identity is however
sufficient for the NPY_TITLE_KEY macro. On PyPy, fix the macro by
comparing values instead.
Diffstat (limited to 'numpy/core/include')
| -rw-r--r-- | numpy/core/include/numpy/ndarrayobject.h | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/numpy/core/include/numpy/ndarrayobject.h b/numpy/core/include/numpy/ndarrayobject.h index 4e63868f3..ec0fd1ee9 100644 --- a/numpy/core/include/numpy/ndarrayobject.h +++ b/numpy/core/include/numpy/ndarrayobject.h @@ -232,9 +232,36 @@ PyArray_DiscardWritebackIfCopy(PyArrayObject *arr) dict. */ -#define NPY_TITLE_KEY(key, value) ((PyTuple_GET_SIZE((value))==3) && \ - (PyTuple_GET_ITEM((value), 2) == (key))) +static NPY_INLINE int +NPY_TITLE_KEY_check(PyObject *key, PyObject *value) +{ + PyObject *title; + if (PyTuple_GET_SIZE(value) != 3) { + return 0; + } + title = PyTuple_GET_ITEM(value, 2); + if (key == title) { + return 1; + } +#ifdef PYPY_VERSION + /* + * On PyPy, dictionary keys do not always preserve object identity. + * Fall back to comparison by value. + */ + if (PyUnicode_Check(title) && PyUnicode_Check(key)) { + return PyUnicode_Compare(title, key) == 0 ? 1 : 0; + } +#if PY_VERSION_HEX < 0x03000000 + if (PyString_Check(title) && PyString_Check(key)) { + return PyObject_Compare(title, key) == 0 ? 1 : 0; + } +#endif +#endif + return 0; +} +/* Macro, for backward compat with "if NPY_TITLE_KEY(key, value) { ..." */ +#define NPY_TITLE_KEY(key, value) (NPY_TITLE_KEY_check((key), (value))) #define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1) #define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1) |
