8000 Merge pull request #10860 from pv/pypyfix-npy-title-key · numpy/numpy@105bdfd · GitHub
[go: up one dir, main page]

Skip to content

Commit 105bdfd

Browse files
authored
Merge pull request #10860 from pv/pypyfix-npy-title-key
BUG: core: fix NPY_TITLE_KEY macro on pypy
2 parents 635559f + 18fd6a4 commit 105bdfd

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

numpy/core/include/numpy/ndarrayobject.h

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,36 @@ PyArray_DiscardWritebackIfCopy(PyArrayObject *arr)
232232
dict.
233233
*/
234234

235-
#define NPY_TITLE_KEY(key, value) ((PyTuple_GET_SIZE((value))==3) && \
236-
(PyTuple_GET_ITEM((value), 2) == (key)))
235+
static NPY_INLINE int
236+
NPY_TITLE_KEY_check(PyObject *key, PyObject *value)
237+
{
238+
PyObject *title;
239+
if (PyTuple_GET_SIZE(value) != 3) {
240+
return 0;
241+
}
242+
title = PyTuple_GET_ITEM(value, 2);
243+
if (key == title) {
244+
return 1;
245+
}
246+
#ifdef PYPY_VERSION
247+
/*
248+
* On PyPy, dictionary keys do not always preserve object identity.
249+
* Fall back to comparison by value.
250+
*/
251+
if (PyUnicode_Check(title) && PyUnicode_Check(key)) {
252+
return PyUnicode_Compare(title, key) == 0 ? 1 : 0;
253+
}
254+
#if PY_VERSION_HEX < 0x03000000
255+
if (PyString_Check(title) && PyString_Check(key)) {
256+
return PyObject_Compare(title, key) == 0 ? 1 : 0;
257+
}
258+
#endif
259+
#endif
260+
return 0;
261+
}
237262

263+
/* Macro, for backward compat with "if NPY_TITLE_KEY(key, value) { ..." */
264+
#define NPY_TITLE_KEY(key, value) (NPY_TITLE_KEY_check((key), (value)))
238265

239266
#define DEPRECATE(msg) PyErr_WarnEx(PyExc_DeprecationWarning,msg,1)
240267
#define DEPRECATE_FUTUREWARNING(msg) PyErr_WarnEx(PyExc_FutureWarning,msg,1)

numpy/core/tests/test_regression.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2332,3 +2332,13 @@ def test_void_item_memview(self):
23322332
#va[0] = b'\xff\xff\xff\xff'
23332333
#del va
23342334
#assert_equal(x, b'\x00\x00\x00\x00')
2335+
2336+
def test_structarray_title(self):
2337+
# The following used to segfault on pypy, due to NPY_TITLE_KEY
2338+
# not working properly and resulting to double-decref of the
2339+
# structured array field items:
2340+
# See: https://bitbucket.org/pypy/pypy/issues/2789
2341+
for j in range(5):
2342+
structure = np.array([1], dtype=[(('x', 'X'), np.object_)])
2343+
structure[0]['x'] = np.array([2])
2344+
gc.collect()

0 commit comments

Comments
 (0)
0