From 1d7e600588f20081af999c7ab1d624f4259d2c12 Mon Sep 17 00:00:00 2001 From: Ronan Lamy Date: Wed, 17 Feb 2021 16:39:14 +0000 Subject: [PATCH 1/4] Update HPy --- pyproject.toml | 2 +- test_requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bb2de0018e42..af47761b95e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ requires = [ "setuptools<49.2.0", "wheel<=0.35.1", "Cython>=0.29.21,<3.0", # Note: keep in sync with tools/cythonize.py - "hpy.devel @ git+https://github.com/hpyproject/hpy.git@8e20b89116c2993188157c09a6070a64f8efbd82#egg=hpy.devel" + "hpy.devel @ git+https://github.com/hpyproject/hpy.git@5953dc7d4d8fd8c5179c75bded3ff514ffde4323#egg=hpy.devel" ] diff --git a/test_requirements.txt b/test_requirements.txt index 9ba1465b7d21..e5fac1842a6d 100644 --- a/test_requirements.txt +++ b/test_requirements.txt @@ -14,4 +14,4 @@ cffi mypy==0.790; platform_python_implementation != "PyPy" typing_extensions # HPy -git+https://github.com/hpyproject/hpy.git@8e20b89116c2993188157c09a6070a64f8efbd82#egg=hpy.devel +git+https://github.com/hpyproject/hpy.git@5953dc7d4d8fd8c5179c75bded3ff514ffde4323#egg=hpy.devel From 1fd8a7a4b854cd368bc3962c41422b43e861a938 Mon Sep 17 00:00:00 2001 From: Ronan Lamy Date: Wed, 17 Feb 2021 16:47:10 +0000 Subject: [PATCH 2/4] Use HPy to define the bf_getbuffer slot on ndarray That way, we stop relying on an undocumented CPython-specific hack to set it. --- numpy/core/src/multiarray/arrayobject.c | 6 ++++++ numpy/core/src/multiarray/buffer.c | 16 ++++++---------- numpy/core/src/multiarray/multiarraymodule.c | 1 - numpy/core/src/multiarray/npy_buffer.h | 3 ++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index 2052d252d373..4ec37507a70f 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -1822,9 +1822,15 @@ static PyType_Slot PyArray_Type_slots[] = { {0, NULL}, }; +static HPyDef *array_defines[] = { + &array_getbuffer, + NULL, +}; + NPY_NO_EXPORT HPyType_Spec PyArray_Type_spec = { .name = "numpy.ndarray", .basicsize = sizeof(PyArrayObject_fields), .flags = (HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_BASETYPE), + .defines = array_defines, .legacy_slots = PyArray_Type_slots, }; diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index 813850224714..1ae99cbe44cd 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -1,5 +1,6 @@ #define PY_SSIZE_T_CLEAN #include +#include "hpy.h" #include "structmember.h" #define NPY_NO_DEPRECATED_API NPY_API_VERSION @@ -747,12 +748,14 @@ _buffer_get_info(void **buffer_info_cache_ptr, PyObject *obj, int flags) /* * Retrieving buffers for ndarray */ +HPyDef_SLOT(array_getbuffer, array_getbuffer_impl, HPy_bf_getbuffer) static int -array_getbuffer(PyObject *obj, Py_buffer *view, int flags) +array_getbuffer_impl(HPyContext ctx, HPy h_obj, HPy_buffer *view, int flags) { PyArrayObject *self; _buffer_info_t *info = NULL; + PyObject *obj = HPy_AsPyObject(ctx, h_obj); self = (PyArrayObject*)obj; /* Check whether we can provide the wanted properties */ @@ -830,9 +833,9 @@ array_getbuffer(PyObject *obj, Py_buffer *view, int flags) else { view->strides = NULL; } - view->obj = (PyObject*)self; + view->obj = HPy_Dup(ctx, h_obj); + Py_DECREF(obj); - Py_INCREF(self); return 0; fail: @@ -885,13 +888,6 @@ void_getbuffer(PyObject *self, Py_buffer *view, int flags) } -/*************************************************************************/ - -NPY_NO_EXPORT PyBufferProcs array_as_buffer = { - (getbufferproc)array_getbuffer, - (releasebufferproc)0, -}; - /************************************************************************* * Convert PEP 3118 format string to PyArray_Descr diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c index a95dc9e4a66a..bfce563fad08 100644 --- a/numpy/core/src/multiarray/multiarraymodule.c +++ b/numpy/core/src/multiarray/multiarraymodule.c @@ -4598,7 +4598,6 @@ static HPy init__multiarray_umath_impl(HPyContext ctx) { goto err; } _PyArray_Type_p = (PyTypeObject*)HPy_AsPyObject(ctx, h_array_type); - PyArray_Type.tp_as_buffer = &array_as_buffer; PyArray_Type.tp_weaklistoffset = offsetof(PyArrayObject_fields, weakreflist); HPy_Close(ctx, h_array_type); diff --git a/numpy/core/src/multiarray/npy_buffer.h b/numpy/core/src/multiarray/npy_buffer.h index d10f1a020446..b43b1ee606ca 100644 --- a/numpy/core/src/multiarray/npy_buffer.h +++ b/numpy/core/src/multiarray/npy_buffer.h @@ -1,7 +1,8 @@ #ifndef _NPY_PRIVATE_BUFFER_H_ #define _NPY_PRIVATE_BUFFER_H_ +#include "hpy.h" -extern NPY_NO_EXPORT PyBufferProcs array_as_buffer; +extern NPY_NO_EXPORT HPyDef array_getbuffer; NPY_NO_EXPORT int _buffer_info_free(void *buffer_info, PyObject *obj); From ec67a479fda9658325ddc1ded6e481b0b9f1472c Mon Sep 17 00:00:00 2001 From: Ronan Lamy Date: Thu, 18 Feb 2021 18:37:28 +0000 Subject: [PATCH 3/4] Avoid refleak on the failure path --- numpy/core/src/multiarray/buffer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index 1ae99cbe44cd..55ae73aa8b5c 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -839,6 +839,7 @@ array_getbuffer_impl(HPyContext ctx, HPy h_obj, HPy_buffer *view, int flags) return 0; fail: + Py_DECREF(obj); return -1; } From 43c69ee70aae1bc9515d44c80fd20ed49d35ed9c Mon Sep 17 00:00:00 2001 From: Ronan Lamy Date: Thu, 18 Feb 2021 18:50:25 +0000 Subject: [PATCH 4/4] Use HPy exceptions --- numpy/core/src/multiarray/buffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index 55ae73aa8b5c..fdd2a6daa6dd 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -761,23 +761,23 @@ array_getbuffer_impl(HPyContext ctx, HPy h_obj, HPy_buffer *view, int flags) /* Check whether we can provide the wanted properties */ if ((flags & PyBUF_C_CONTIGUOUS) == PyBUF_C_CONTIGUOUS && !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) { - PyErr_SetString(PyExc_ValueError, "ndarray is not C-contiguous"); + HPyErr_SetString(ctx, ctx->h_ValueError, "ndarray is not C-contiguous"); goto fail; } if ((flags & PyBUF_F_CONTIGUOUS) == PyBUF_F_CONTIGUOUS && !PyArray_CHKFLAGS(self, NPY_ARRAY_F_CONTIGUOUS)) { - PyErr_SetString(PyExc_ValueError, "ndarray is not Fortran contiguous"); + HPyErr_SetString(ctx, ctx->h_ValueError, "ndarray is not Fortran contiguous"); goto fail; } if ((flags & PyBUF_ANY_CONTIGUOUS) == PyBUF_ANY_CONTIGUOUS && !PyArray_ISONESEGMENT(self)) { - PyErr_SetString(PyExc_ValueError, "ndarray is not contiguous"); + HPyErr_SetString(ctx, ctx->h_ValueError, "ndarray is not contiguous"); goto fail; } if ((flags & PyBUF_STRIDES) != PyBUF_STRIDES && !PyArray_CHKFLAGS(self, NPY_ARRAY_C_CONTIGUOUS)) { /* Non-strided N-dim buffers must be C-contiguous */ - PyErr_SetString(PyExc_ValueError, "ndarray is not C-contiguous"); + HPyErr_SetString(ctx, ctx->h_ValueError, "ndarray is not C-contiguous"); goto fail; } if ((flags & PyBUF_WRITEABLE) == PyBUF_WRITEABLE) { @@ -787,7 +787,7 @@ array_getbuffer_impl(HPyContext ctx, HPy h_obj, HPy_buffer *view, int flags) } if (view == NULL) { - PyErr_SetString(PyExc_ValueError, "NULL view in getbuffer"); + HPyErr_SetString(ctx, ctx->h_ValueError, "NULL view in getbuffer"); goto fail; }