From 5668a791b3541e75ae62bae0c8013e9cf9d38d59 Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Fri, 3 Jan 2020 14:54:05 -0800 Subject: [PATCH 1/2] MAINT: Cleaning up more PY_VERSION_HEX --- numpy/core/include/numpy/ndarraytypes.h | 19 ++---- numpy/core/include/numpy/npy_3kcompat.h | 45 +------------ numpy/core/include/numpy/npy_common.h | 10 --- numpy/core/src/multiarray/common.c | 8 --- numpy/core/src/multiarray/number.c | 5 +- numpy/core/src/multiarray/scalarapi.c | 75 --------------------- numpy/core/src/multiarray/scalartypes.c.src | 6 -- numpy/core/src/multiarray/typeinfo.c | 6 +- numpy/core/src/umath/funcs.inc.src | 4 +- numpy/f2py/src/fortranobject.c | 25 ------- 10 files changed, 10 insertions(+), 193 deletions(-) diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h index ad98d562b78c..bec6fcf309c3 100644 --- a/numpy/core/include/numpy/ndarraytypes.h +++ b/numpy/core/include/numpy/ndarraytypes.h @@ -353,21 +353,12 @@ struct NpyAuxData_tag { #define NPY_USE_PYMEM 1 + #if NPY_USE_PYMEM == 1 - /* numpy sometimes calls PyArray_malloc() with the GIL released. On Python - 3.3 and older, it was safe to call PyMem_Malloc() with the GIL released. - On Python 3.4 and newer, it's better to use PyMem_RawMalloc() to be able - to use tracemalloc. On Python 3.6, calling PyMem_Malloc() with the GIL - released is now a fatal error in debug mode. */ -# if PY_VERSION_HEX >= 0x03040000 -# define PyArray_malloc PyMem_RawMalloc -# define PyArray_free PyMem_RawFree -# define PyArray_realloc PyMem_RawRealloc -# else -# define PyArray_malloc PyMem_Malloc -# define PyArray_free PyMem_Free -# define PyArray_realloc PyMem_Realloc -# endif +/* use the Raw versions which are safe to call with the GIL released */ +#define PyArray_malloc PyMem_RawMalloc +#define PyArray_free PyMem_RawFree +#define PyArray_realloc PyMem_RawRealloc #else #define PyArray_malloc malloc #define PyArray_free free diff --git a/numpy/core/include/numpy/npy_3kcompat.h b/numpy/core/include/numpy/npy_3kcompat.h index 6fe53caa1d81..dbb5bd506619 100644 --- a/numpy/core/include/numpy/npy_3kcompat.h +++ b/numpy/core/include/numpy/npy_3kcompat.h @@ -60,13 +60,7 @@ static NPY_INLINE int PyInt_Check(PyObject *op) { PySlice_GetIndicesEx((PySliceObject *)op, nop, start, end, step, slicelength) #endif -/* <2.7.11 and <3.4.4 have the wrong argument type for Py_EnterRecursiveCall */ -#if (PY_VERSION_HEX < 0x02070B00) || \ - ((0x03000000 <= PY_VERSION_HEX) && (PY_VERSION_HEX < 0x03040400)) - #define Npy_EnterRecursiveCall(x) Py_EnterRecursiveCall((char *)(x)) -#else - #define Npy_EnterRecursiveCall(x) Py_EnterRecursiveCall(x) -#endif +#define Npy_EnterRecursiveCall(x) Py_EnterRecursiveCall(x) /* Py_SETREF was added in 3.5.2, and only if Py_LIMITED_API is absent */ #if PY_VERSION_HEX < 0x03050200 @@ -488,8 +482,6 @@ PyObject_Cmp(PyObject *i1, PyObject *i2, int *cmp) * The main job here is to get rid of the improved error handling * of PyCapsules. It's a shame... */ -#if PY_VERSION_HEX >= 0x03000000 - static NPY_INLINE PyObject * NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *)) { @@ -534,41 +526,6 @@ NpyCapsule_Check(PyObject *ptr) return PyCapsule_CheckExact(ptr); } -#else - -static NPY_INLINE PyObject * -NpyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *)) -{ - return PyCObject_FromVoidPtr(ptr, dtor); -} - -static NPY_INLINE PyObject * -NpyCapsule_FromVoidPtrAndDesc(void *ptr, void* context, - void (*dtor)(void *, void *)) -{ - return PyCObject_FromVoidPtrAndDesc(ptr, context, dtor); -} - -static NPY_INLINE void * -NpyCapsule_AsVoidPtr(PyObject *ptr) -{ - return PyCObject_AsVoidPtr(ptr); -} - -static NPY_INLINE void * -NpyCapsule_GetDesc(PyObject *obj) -{ - return PyCObject_GetDesc(obj); -} - -static NPY_INLINE int -NpyCapsule_Check(PyObject *ptr) -{ - return PyCObject_Check(ptr); -} - -#endif - #ifdef __cplusplus } #endif diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h index 27b83f7b5749..c2e755958164 100644 --- a/numpy/core/include/numpy/npy_common.h +++ b/numpy/core/include/numpy/npy_common.h @@ -369,18 +369,8 @@ typedef long npy_long; typedef float npy_float; typedef double npy_double; -/* - * Hash value compatibility. - * As of Python 3.2 hash values are of type Py_hash_t. - * Previous versions use C long. - */ -#if PY_VERSION_HEX < 0x03020000 -typedef long npy_hash_t; -#define NPY_SIZEOF_HASH_T NPY_SIZEOF_LONG -#else typedef Py_hash_t npy_hash_t; #define NPY_SIZEOF_HASH_T NPY_SIZEOF_INTP -#endif /* * Disabling C99 complex usage: a lot of C code in numpy/scipy rely on being diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c index 141bc2fd62e7..11139c99fc10 100644 --- a/numpy/core/src/multiarray/common.c +++ b/numpy/core/src/multiarray/common.c @@ -166,11 +166,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, goto fail; } #if defined(NPY_PY3K) - #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); - #else - itemsize = PyUnicode_GET_SIZE(temp); - #endif #else itemsize = PyString_GET_SIZE(temp); #endif @@ -222,11 +218,7 @@ PyArray_DTypeFromObjectHelper(PyObject *obj, int maxdims, goto fail; } #if defined(NPY_PY3K) - #if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(temp); - #else - itemsize = PyUnicode_GET_SIZE(temp); - #endif #else itemsize = PyString_GET_SIZE(temp); #endif diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c index dabc866ffb78..bbcf57197635 100644 --- a/numpy/core/src/multiarray/number.c +++ b/numpy/core/src/multiarray/number.c @@ -381,7 +381,6 @@ array_divmod(PyArrayObject *m1, PyObject *m2) return PyArray_GenericBinaryFunction(m1, m2, n_ops.divmod); } -#if PY_VERSION_HEX >= 0x03050000 /* Need this to be version dependent on account of the slot check */ static PyObject * array_matrix_multiply(PyArrayObject *m1, PyObject *m2) @@ -399,7 +398,6 @@ array_inplace_matrix_multiply( "Use 'a = a @ b' instead of 'a @= b'."); return NULL; } -#endif /* * Determine if object is a scalar and if so, convert the object @@ -1062,8 +1060,7 @@ NPY_NO_EXPORT PyNumberMethods array_as_number = { (binaryfunc)array_inplace_floor_divide, /*nb_inplace_floor_divide*/ (binaryfunc)array_inplace_true_divide, /*nb_inplace_true_divide*/ (unaryfunc)array_index, /*nb_index */ -#if PY_VERSION_HEX >= 0x03050000 + (binaryfunc)array_matrix_multiply, /*nb_matrix_multiply*/ (binaryfunc)array_inplace_matrix_multiply, /*nb_inplace_matrix_multiply*/ -#endif }; diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c index b669a3e76477..ecbf0218fbc6 100644 --- a/numpy/core/src/multiarray/scalarapi.c +++ b/numpy/core/src/multiarray/scalarapi.c @@ -656,7 +656,6 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) itemsize = (((itemsize - 1) >> 2) + 1) << 2; } } -#if PY_VERSION_HEX >= 0x03030000 if (type_num == NPY_UNICODE) { PyObject *u, *args; int byteorder; @@ -684,7 +683,6 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) Py_DECREF(args); return obj; } -#endif if (type->tp_itemsize != 0) { /* String type */ obj = type->tp_alloc(type, itemsize); @@ -716,79 +714,6 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) memcpy(destptr, data, itemsize); return obj; } -#if PY_VERSION_HEX < 0x03030000 - else if (type_num == NPY_UNICODE) { - /* tp_alloc inherited from Python PyBaseObject_Type */ - PyUnicodeObject *uni = (PyUnicodeObject*)obj; - size_t length = itemsize >> 2; - Py_UNICODE *dst; -#ifndef Py_UNICODE_WIDE - char *buffer; - Py_UNICODE *tmp; - int alloc = 0; - - length *= 2; -#endif - /* Set uni->str so that object can be deallocated on failure */ - uni->str = NULL; - uni->defenc = NULL; - uni->hash = -1; - dst = PyObject_MALLOC(sizeof(Py_UNICODE) * (length + 1)); - if (dst == NULL) { - Py_DECREF(obj); - PyErr_NoMemory(); - return NULL; - } -#ifdef Py_UNICODE_WIDE - memcpy(dst, data, itemsize); - if (swap) { - byte_swap_vector(dst, length, 4); - } - uni->str = dst; - uni->str[length] = 0; - uni->length = length; -#else - /* need aligned data buffer */ - if ((swap) || ((((npy_intp)data) % descr->alignment) != 0)) { - buffer = malloc(itemsize); - if (buffer == NULL) { - PyObject_FREE(dst); - Py_DECREF(obj); - PyErr_NoMemory(); - } - alloc = 1; - memcpy(buffer, data, itemsize); - if (swap) { - byte_swap_vector(buffer, itemsize >> 2, 4); - } - } - else { - buffer = data; - } - - /* - * Allocated enough for 2-characters per itemsize. - * Now convert from the data-buffer - */ - length = PyUCS2Buffer_FromUCS4(dst, - (npy_ucs4 *)buffer, itemsize >> 2); - if (alloc) { - free(buffer); - } - /* Resize the unicode result */ - tmp = PyObject_REALLOC(dst, sizeof(Py_UNICODE)*(length + 1)); - if (tmp == NULL) { - PyObject_FREE(dst); - Py_DECREF(obj); - return NULL; - } - uni->str = tmp; - uni->str[length] = 0; - uni->length = length; -#endif - return obj; - } -#endif /* PY_VERSION_HEX < 0x03030000 */ else { PyVoidScalarObject *vobj = (PyVoidScalarObject *)obj; vobj->base = NULL; diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index 4cef01f89c16..0710268c98cc 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -1152,10 +1152,8 @@ static PyNumberMethods gentype_as_number = { 0, /*nb_inplace_floor_divide*/ 0, /*nb_inplace_true_divide*/ (unaryfunc)NULL, /*nb_index*/ -#if PY_VERSION_HEX >= 0x03050000 0, /*np_matmul*/ 0, /*np_inplace_matmul*/ -#endif }; @@ -2877,11 +2875,7 @@ finish: *((npy_@name@ *)dest) = *((npy_@name@ *)src); #elif @default@ == 1 /* unicode and strings */ if (itemsize == 0) { /* unicode */ -#if PY_VERSION_HEX >= 0x03030000 itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj); -#else - itemsize = ((PyUnicodeObject *)robj)->length * sizeof(Py_UNICODE); -#endif } memcpy(dest, src, itemsize); /* @default@ == 2 won't get here */ diff --git a/numpy/core/src/multiarray/typeinfo.c b/numpy/core/src/multiarray/typeinfo.c index 14c4f27cbdce..1fbdc6c417f3 100644 --- a/numpy/core/src/multiarray/typeinfo.c +++ b/numpy/core/src/multiarray/typeinfo.c @@ -104,10 +104,8 @@ PyArray_typeinforanged( return entry; } -/* Python version only needed for backport to 2.7 */ -#if (PY_VERSION_HEX < 0x03040000) \ - || (defined(PYPY_VERSION_NUM) && (PYPY_VERSION_NUM < 0x07020000)) - +/* Python version needed for older PyPy */ +#if (defined(PYPY_VERSION_NUM) && (PYPY_VERSION_NUM < 0x07020000)) static int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { PyStructSequence_InitType(type, desc); diff --git a/numpy/core/src/umath/funcs.inc.src b/numpy/core/src/umath/funcs.inc.src index 9c59cc8fbbdd..4c0a86c1dbdc 100644 --- a/numpy/core/src/umath/funcs.inc.src +++ b/numpy/core/src/umath/funcs.inc.src @@ -197,8 +197,7 @@ npy_ObjectGCD(PyObject *i1, PyObject *i2) { PyObject *gcd = NULL; - /* use math.gcd if available, and valid on the provided types */ -#if PY_VERSION_HEX >= 0x03050000 + /* use math.gcd if valid on the provided types */ { static PyObject *math_gcd_func = NULL; @@ -213,7 +212,6 @@ npy_ObjectGCD(PyObject *i1, PyObject *i2) /* silence errors, and fall back on pure-python gcd */ PyErr_Clear(); } -#endif /* otherwise, use our internal one, written in python */ { diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c index 456e64893ddc..81fc50f2ee90 100644 --- a/numpy/f2py/src/fortranobject.c +++ b/numpy/f2py/src/fortranobject.c @@ -1017,8 +1017,6 @@ int copy_ND_array(const PyArrayObject *arr, PyArrayObject *out) /* Compatibility functions for Python >= 3.0 */ /*********************************************/ -#if PY_VERSION_HEX >= 0x03000000 - PyObject * F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(PyObject *)) { @@ -1045,29 +1043,6 @@ F2PyCapsule_Check(PyObject *ptr) return PyCapsule_CheckExact(ptr); } -#else - -PyObject * -F2PyCapsule_FromVoidPtr(void *ptr, void (*dtor)(void *)) -{ - return PyCObject_FromVoidPtr(ptr, dtor); -} - -void * -F2PyCapsule_AsVoidPtr(PyObject *ptr) -{ - return PyCObject_AsVoidPtr(ptr); -} - -int -F2PyCapsule_Check(PyObject *ptr) -{ - return PyCObject_Check(ptr); -} - -#endif - - #ifdef __cplusplus } #endif From a8d1da81bb49f266471b67475da33088901fd3c9 Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Sat, 4 Jan 2020 13:29:40 -0800 Subject: [PATCH 2/2] DOC: Add release notes for Py3K cleanups. --- doc/release/upcoming_changes/15233.highlight.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 doc/release/upcoming_changes/15233.highlight.rst diff --git a/doc/release/upcoming_changes/15233.highlight.rst b/doc/release/upcoming_changes/15233.highlight.rst new file mode 100644 index 000000000000..df96ee87198b --- /dev/null +++ b/doc/release/upcoming_changes/15233.highlight.rst @@ -0,0 +1,4 @@ +* Code compatibility with Python versions < 3.5 (including Python 2) was + dropped from both the python and C code. The shims in numpy.compat will + remain to support third-party packages, but they may be deprecated in a + future release.