From 0100e09a318800de5071a8345eba99a99bbde205 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Fri, 14 Jan 2022 11:48:37 -0700 Subject: [PATCH 01/30] REL: prepare 1.22.x for further development --- doc/source/release.rst | 1 + doc/source/release/1.22.2-notes.rst | 10 ++++++++++ pavement.py | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 doc/source/release/1.22.2-notes.rst diff --git a/doc/source/release.rst b/doc/source/release.rst index e90521be5c5b..621471f7ee04 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -5,6 +5,7 @@ Release notes .. toctree:: :maxdepth: 3 + 1.22.2 1.22.1 1.22.0 1.21.4 diff --git a/doc/source/release/1.22.2-notes.rst b/doc/source/release/1.22.2-notes.rst new file mode 100644 index 000000000000..52da4c1312f7 --- /dev/null +++ b/doc/source/release/1.22.2-notes.rst @@ -0,0 +1,10 @@ +.. currentmodule:: numpy + +========================== +NumPy 1.22.2 Release Notes +========================== + +The NumPy 1.22.2 is maintenance release that fixes bugs discovered after the +1.22.1 release. Notable fixes are: + +The Python versions supported for this release are 3.8-3.10. diff --git a/pavement.py b/pavement.py index 3533e420a558..6fea333369b4 100644 --- a/pavement.py +++ b/pavement.py @@ -38,7 +38,7 @@ #----------------------------------- # Path to the release notes -RELEASE_NOTES = 'doc/source/release/1.22.1-notes.rst' +RELEASE_NOTES = 'doc/source/release/1.22.2-notes.rst' #------------------------------------------------------- From d60a3be5fbd4df04f30bc4d31cee16051dc63f37 Mon Sep 17 00:00:00 2001 From: "Andrew J. Hesford" Date: Sat, 1 Jan 2022 10:48:33 -0500 Subject: [PATCH 02/30] BLD: Add NPY_DISABLE_SVML env var to opt out of SVML --- numpy/core/setup.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/numpy/core/setup.py b/numpy/core/setup.py index a5f423d8fe4f..7eb08132e2b2 100644 --- a/numpy/core/setup.py +++ b/numpy/core/setup.py @@ -24,6 +24,11 @@ NPY_RELAXED_STRIDES_DEBUG = (os.environ.get('NPY_RELAXED_STRIDES_DEBUG', "0") != "0") NPY_RELAXED_STRIDES_DEBUG = NPY_RELAXED_STRIDES_DEBUG and NPY_RELAXED_STRIDES_CHECKING +# Set NPY_DISABLE_SVML=1 in the environment to disable the vendored SVML +# library. This option only has significance on a Linux x86_64 host and is most +# useful to avoid improperly requiring SVML when cross compiling. +NPY_DISABLE_SVML = (os.environ.get('NPY_DISABLE_SVML', "0") == "1") + # XXX: ugly, we use a class to avoid calling twice some expensive functions in # config.h/numpyconfig.h. I don't see a better way because distutils force # config.h generation inside an Extension class, and as such sharing @@ -68,6 +73,8 @@ def can_link_svml(): """SVML library is supported only on x86_64 architecture and currently only on linux """ + if NPY_DISABLE_SVML: + return False machine = platform.machine() system = platform.system() return "x86_64" in machine and system == "Linux" From 62ff4f85e3294ff0e59aa743ec3e1614fc06d0be Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 13 Jan 2022 13:19:31 -0500 Subject: [PATCH 03/30] BUG: Fix build of third-party extensions with Py_LIMITED_API The type `vectorcallfunc` is not defined by Python's limited API. Guard its use with a `#ifdef` so that third-party extensions that use the Numpy C API will build with Py_LIMITED_API defined. This fixes a regression introduced in #20315. --- numpy/core/include/numpy/ufuncobject.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h index 1d7050bbe5a3..bb0633100795 100644 --- a/numpy/core/include/numpy/ufuncobject.h +++ b/numpy/core/include/numpy/ufuncobject.h @@ -173,7 +173,11 @@ typedef struct _tagPyUFuncObject { * but this was never implemented. (This is also why the above * selector is called the "legacy" selector.) */ - vectorcallfunc vectorcall; + #ifndef Py_LIMITED_API + vectorcallfunc vectorcall; + #else + void *vectorcall; + #endif /* Was previously the `PyUFunc_MaskedInnerLoopSelectionFunc` */ void *_always_null_previously_masked_innerloop_selector; From e78f607767c3cce4d5d24d4cc27597fe20bbca69 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 13 Jan 2022 13:09:23 -0500 Subject: [PATCH 04/30] TST: Test building third party C extensions with Py_LIMITED_API Fixes #13784. --- .../core/tests/examples/example_limited_api.c | 22 +++++++++++++++++++ numpy/core/tests/examples/setup.py | 12 ++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 numpy/core/tests/examples/example_limited_api.c diff --git a/numpy/core/tests/examples/example_limited_api.c b/numpy/core/tests/examples/example_limited_api.c new file mode 100644 index 000000000000..e811800b4241 --- /dev/null +++ b/numpy/core/tests/examples/example_limited_api.c @@ -0,0 +1,22 @@ +/* + * Test that third-party extensions that use the Numpy C API can be built with + * the limited Python C API (see https://docs.python.org/3/c-api/stable.html). + */ + +#define Py_LIMITED_API 0x03060000 + +#include +#include +#include + +static PyModuleDef moduledef = { + .m_base = PyModuleDef_HEAD_INIT, + .m_name = "example_limited_api" +}; + +PyMODINIT_FUNC PyInit_example_limited_api(void) +{ + import_array(); + import_umath(); + return PyModule_Create(&moduledef); +} diff --git a/numpy/core/tests/examples/setup.py b/numpy/core/tests/examples/setup.py index 6e34aa7787ad..6ec0b41972e0 100644 --- a/numpy/core/tests/examples/setup.py +++ b/numpy/core/tests/examples/setup.py @@ -9,16 +9,24 @@ from setuptools.extension import Extension import os +include_dirs = [np.get_include()] macros = [("NPY_NO_DEPRECATED_API", 0)] checks = Extension( "checks", sources=[os.path.join('.', "checks.pyx")], - include_dirs=[np.get_include()], + include_dirs=include_dirs, define_macros=macros, ) -extensions = [checks] +example_limited_api = Extension( + "example_limited_api", + sources=[os.path.join('.', "example_limited_api.c")], + include_dirs=include_dirs, + define_macros=macros, +) + +extensions = [checks, example_limited_api] setup( ext_modules=cythonize(extensions) From 593b1b28b685a79838f88ff9932a0cfb1859a910 Mon Sep 17 00:00:00 2001 From: Leo Singer Date: Thu, 13 Jan 2022 20:47:50 -0500 Subject: [PATCH 05/30] TST: Split example package, skip limited API test for debug --- .../tests/examples/{ => cython}/checks.pyx | 0 .../core/tests/examples/{ => cython}/setup.py | 12 +----- .../limited_api.c} | 9 +--- .../core/tests/examples/limited_api/setup.py | 22 ++++++++++ numpy/core/tests/test_cython.py | 2 +- numpy/core/tests/test_limited_api.py | 41 +++++++++++++++++++ 6 files changed, 68 insertions(+), 18 deletions(-) rename numpy/core/tests/examples/{ => cython}/checks.pyx (100%) rename numpy/core/tests/examples/{ => cython}/setup.py (60%) rename numpy/core/tests/examples/{example_limited_api.c => limited_api/limited_api.c} (52%) create mode 100644 numpy/core/tests/examples/limited_api/setup.py create mode 100644 numpy/core/tests/test_limited_api.py diff --git a/numpy/core/tests/examples/checks.pyx b/numpy/core/tests/examples/cython/checks.pyx similarity index 100% rename from numpy/core/tests/examples/checks.pyx rename to numpy/core/tests/examples/cython/checks.pyx diff --git a/numpy/core/tests/examples/setup.py b/numpy/core/tests/examples/cython/setup.py similarity index 60% rename from numpy/core/tests/examples/setup.py rename to numpy/core/tests/examples/cython/setup.py index 6ec0b41972e0..6e34aa7787ad 100644 --- a/numpy/core/tests/examples/setup.py +++ b/numpy/core/tests/examples/cython/setup.py @@ -9,24 +9,16 @@ from setuptools.extension import Extension import os -include_dirs = [np.get_include()] macros = [("NPY_NO_DEPRECATED_API", 0)] checks = Extension( "checks", sources=[os.path.join('.', "checks.pyx")], - include_dirs=include_dirs, + include_dirs=[np.get_include()], define_macros=macros, ) -example_limited_api = Extension( - "example_limited_api", - sources=[os.path.join('.', "example_limited_api.c")], - include_dirs=include_dirs, - define_macros=macros, -) - -extensions = [checks, example_limited_api] +extensions = [checks] setup( ext_modules=cythonize(extensions) diff --git a/numpy/core/tests/examples/example_limited_api.c b/numpy/core/tests/examples/limited_api/limited_api.c similarity index 52% rename from numpy/core/tests/examples/example_limited_api.c rename to numpy/core/tests/examples/limited_api/limited_api.c index e811800b4241..698c54c57706 100644 --- a/numpy/core/tests/examples/example_limited_api.c +++ b/numpy/core/tests/examples/limited_api/limited_api.c @@ -1,8 +1,3 @@ -/* - * Test that third-party extensions that use the Numpy C API can be built with - * the limited Python C API (see https://docs.python.org/3/c-api/stable.html). - */ - #define Py_LIMITED_API 0x03060000 #include @@ -11,10 +6,10 @@ static PyModuleDef moduledef = { .m_base = PyModuleDef_HEAD_INIT, - .m_name = "example_limited_api" + .m_name = "limited_api" }; -PyMODINIT_FUNC PyInit_example_limited_api(void) +PyMODINIT_FUNC PyInit_limited_api(void) { import_array(); import_umath(); diff --git a/numpy/core/tests/examples/limited_api/setup.py b/numpy/core/tests/examples/limited_api/setup.py new file mode 100644 index 000000000000..18747dc80896 --- /dev/null +++ b/numpy/core/tests/examples/limited_api/setup.py @@ -0,0 +1,22 @@ +""" +Build an example package using the limited Python C API. +""" + +import numpy as np +from setuptools import setup, Extension +import os + +macros = [("NPY_NO_DEPRECATED_API", 0), ("Py_LIMITED_API", "0x03060000")] + +limited_api = Extension( + "limited_api", + sources=[os.path.join('.', "limited_api.c")], + include_dirs=[np.get_include()], + define_macros=macros, +) + +extensions = [limited_api] + +setup( + ext_modules=extensions +) diff --git a/numpy/core/tests/test_cython.py b/numpy/core/tests/test_cython.py index a1f09d0fef12..9896de0ec29f 100644 --- a/numpy/core/tests/test_cython.py +++ b/numpy/core/tests/test_cython.py @@ -32,7 +32,7 @@ def install_temp(request, tmp_path): # Based in part on test_cython from random.tests.test_extending here = os.path.dirname(__file__) - ext_dir = os.path.join(here, "examples") + ext_dir = os.path.join(here, "examples", "cython") cytest = str(tmp_path / "cytest") diff --git a/numpy/core/tests/test_limited_api.py b/numpy/core/tests/test_limited_api.py new file mode 100644 index 000000000000..0bb543d593ae --- /dev/null +++ b/numpy/core/tests/test_limited_api.py @@ -0,0 +1,41 @@ +import os +import shutil +import subprocess +import sys +import sysconfig +import pytest + + +@pytest.mark.xfail( + sysconfig.get_config_var("Py_DEBUG"), + reason=( + "Py_LIMITED_API is incompatible with Py_DEBUG, Py_TRACE_REFS, " + "and Py_REF_DEBUG" + ), +) +def test_limited_api(tmp_path): + """Test building a third-party C extension with the limited API.""" + # Based in part on test_cython from random.tests.test_extending + + here = os.path.dirname(__file__) + ext_dir = os.path.join(here, "examples", "limited_api") + + cytest = str(tmp_path / "limited_api") + + shutil.copytree(ext_dir, cytest) + # build the examples and "install" them into a temporary directory + + install_log = str(tmp_path / "tmp_install_log.txt") + subprocess.check_call( + [ + sys.executable, + "setup.py", + "build", + "install", + "--prefix", str(tmp_path / "installdir"), + "--single-version-externally-managed", + "--record", + install_log, + ], + cwd=cytest, + ) From ec6961edcb4a2c008910978e18ca31031eee857f Mon Sep 17 00:00:00 2001 From: Bas van Beek <43369155+BvB93@users.noreply.github.com> Date: Sat, 15 Jan 2022 18:03:26 +0100 Subject: [PATCH 06/30] TYP: Fix pyright being unable to infer the `real` and `imag` output type --- numpy/__init__.pyi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 01cd0c875c84..3f80eaa79dc1 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -1458,13 +1458,13 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]): def size(self) -> int: ... @property def real( - self: NDArray[_SupportsReal[_ScalarType]], # type: ignore[type-var] + self: ndarray[_ShapeType, dtype[_SupportsReal[_ScalarType]]], # type: ignore[type-var] ) -> ndarray[_ShapeType, _dtype[_ScalarType]]: ... @real.setter def real(self, value: ArrayLike) -> None: ... @property def imag( - self: NDArray[_SupportsImag[_ScalarType]], # type: ignore[type-var] + self: ndarray[_ShapeType, dtype[_SupportsImag[_ScalarType]]], # type: ignore[type-var] ) -> ndarray[_ShapeType, _dtype[_ScalarType]]: ... @imag.setter def imag(self, value: ArrayLike) -> None: ... From 84940f6c716263074432d9f75b57db8603f419e0 Mon Sep 17 00:00:00 2001 From: Hood Chatham Date: Sun, 16 Jan 2022 09:38:29 -0800 Subject: [PATCH 07/30] BUG: Fix comparator function signatures The comparator functions are expected to have signature int f(void *, void*, PyArrayObject *). Some of the comparators drop the third argument because they don't use them. Because the comparators are unused, with most architectures this works fine. However, calling a function pointer that has been cast to have a different number of arguments is undefined in the C specification. With web assembly targets, it crashes at runtime. This fixes the comparators defined in arraytypes.c.src to all take three arguments. See also related work: 258ce2523ffad99be69afbd421d540086cb6bf61 23c05e6f1b392f80f749dbb4668b5e7b52aef014 --- numpy/core/src/multiarray/arraytypes.c.src | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src index 71808cc48aa3..71401c60e8d0 100644 --- a/numpy/core/src/multiarray/arraytypes.c.src +++ b/numpy/core/src/multiarray/arraytypes.c.src @@ -2849,7 +2849,7 @@ static int #define LT(a,b) ((a) < (b) || ((b) != (b) && (a) ==(a))) static int -@TYPE@_compare(@type@ *pa, @type@ *pb) +@TYPE@_compare(@type@ *pa, @type@ *pb, PyArrayObject *NPY_UNUSED(ap)) { const @type@ a = *pa; const @type@ b = *pb; @@ -2869,7 +2869,7 @@ static int static int -C@TYPE@_compare(@type@ *pa, @type@ *pb) +C@TYPE@_compare(@type@ *pa, @type@ *pb, PyArrayObject *NPY_UNUSED(ap)) { const @type@ ar = pa[0]; const @type@ ai = pa[1]; @@ -2924,7 +2924,7 @@ C@TYPE@_compare(@type@ *pa, @type@ *pb) */ static int -@TYPE@_compare(@type@ *pa, @type@ *pb) +@TYPE@_compare(@type@ *pa, @type@ *pb, PyArrayObject *NPY_UNUSED(ap)) { const @type@ a = *pa; const @type@ b = *pb; From 5d4acac9946f66d025d67bf37086e2f612659b6a Mon Sep 17 00:00:00 2001 From: bwoodsend Date: Sun, 16 Jan 2022 16:13:31 +0000 Subject: [PATCH 08/30] BUG: Avoid importing numpy.distutils on import numpy.testing (#20769) Move the offending imports into the functions that use them so that numpy.distutils is only loaded if those functions are required. --- numpy/testing/_private/extbuild.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/testing/_private/extbuild.py b/numpy/testing/_private/extbuild.py index 20bf3dceac02..fc39163953d9 100644 --- a/numpy/testing/_private/extbuild.py +++ b/numpy/testing/_private/extbuild.py @@ -8,8 +8,6 @@ import pathlib import sys import sysconfig -from numpy.distutils.ccompiler import new_compiler -from distutils.errors import CompileError __all__ = ['build_and_import_extension', 'compile_extension_module'] @@ -53,6 +51,7 @@ def build_and_import_extension( >>> assert not mod.test_bytes(u'abc') >>> assert mod.test_bytes(b'abc') """ + from distutils.errors import CompileError body = prologue + _make_methods(functions, modname) init = """PyObject *mod = PyModule_Create(&moduledef); @@ -221,6 +220,7 @@ def _c_compile(cfile, outputfilename, include_dirs=[], libraries=[], def build(cfile, outputfilename, compile_extra, link_extra, include_dirs, libraries, library_dirs): "cd into the directory where the cfile is, use distutils to build" + from numpy.distutils.ccompiler import new_compiler compiler = new_compiler(force=1, verbose=2) compiler.customize('') From 740c6ecdfff887cd9d8f72eaa88d8998bfe50048 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Tue, 18 Jan 2022 08:37:43 +0100 Subject: [PATCH 09/30] MAINT: remove outdated mingw32 fseek support `_fseeki64` and `_ftelli64` have been present in mingw-w64 for a long time, see https://github.com/mingw-w64/mingw-w64/commit/d66350ea60d043a8992ada752040fc4ea48537c3 This fixes an annoying build warning in the SciPy Meson build: ``` C:\hostedtoolcache\windows\Python\3.9.9\x64\lib\site-packages\numpy\core\include/numpy/npy_common.h:185:20: warning: 'int _fseeki64(FILE*, long long int, int)' redeclared without dllimport attribute after being referenced with dll linkage 185 | extern int __cdecl _fseeki64(FILE *, long long, int); | ^~~~~~~~~ C:\hostedtoolcache\windows\Python\3.9.9\x64\lib\site-packages\numpy\core\include/numpy/npy_common.h:186:26: warning: 'long long int _ftelli64(FILE*)' redeclared without dllimport attribute after being referenced with dll linkage 186 | extern long long __cdecl _ftelli64(FILE *); | ^~~~~~~~~ ``` It's only happening for Pythran extensions, because Pythran uses `fseek`. The cause is otherwise unrelated to Pythran though, it's `npy_common.h` redefining something that's in mingw-w64. --- numpy/core/include/numpy/npy_common.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h index 88794ca07e36..1d6234e20e0f 100644 --- a/numpy/core/include/numpy/npy_common.h +++ b/numpy/core/include/numpy/npy_common.h @@ -180,12 +180,6 @@ defined(__MINGW32__) || defined(__MINGW64__) #include -/* mingw based on 3.4.5 has lseek but not ftell/fseek */ -#if defined(__MINGW32__) || defined(__MINGW64__) -extern int __cdecl _fseeki64(FILE *, long long, int); -extern long long __cdecl _ftelli64(FILE *); -#endif - #define npy_fseek _fseeki64 #define npy_ftell _ftelli64 #define npy_lseek _lseeki64 From b5bcf5efba1497b86d27d64392b015fa1617a46c Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Sun, 23 Jan 2022 19:01:22 +0100 Subject: [PATCH 10/30] BUG: fix f2py's define for threading when building with Mingw Closes https://github.com/rgommers/scipy/issues/125 This is a follow-up of gh-18910 (included in 1.20.3 and 1.21.0), which looks incorrect. This fixes warnings like these when building SciPy with Mingw-w64: ``` [94/1557] Compiling C object scipy/linalg/_flapack.cp39-win_amd64.pyd.p/meson-generated_..__flapackmodule.c.obj In file included from C:\hostedtoolcache\windows\Python\3.9.9\x64\lib\site-packages\numpy\core\include/numpy/ndarraytypes.h:4, from C:\hostedtoolcache\windows\Python\3.9.9\x64\lib\site-packages\numpy\core\include/numpy/ndarrayobject.h:12, from C:\hostedtoolcache\windows\Python\3.9.9\x64\lib\site-packages\numpy\core\include/numpy/arrayobject.h:4, from C:\hostedtoolcache\windows\Python\3.9.9\x64\lib\site-packages\numpy\f2py\src/fortranobject.h:13, from scipy/linalg/_flapackmodule.c:16: scipy/linalg/_flapackmodule.c:1248:1: warning: 'thread' attribute directive ignored [-Wattributes] 1248 | static F2PY_THREAD_LOCAL_DECL cb_cselect_in_gees__user__routines_t *_active_cb_cselect_in_gees__user__routines = NULL; | ^~~~~~ scipy/linalg/_flapackmodule.c:1410:1: warning: 'thread' attribute directive ignored [-Wattributes] 1410 | static F2PY_THREAD_LOCAL_DECL cb_zselect_in_gees__user__routines_t *_active_cb_zselect_in_gees__user__routines = NULL; | ^~~~~~ scipy/linalg/_flapackmodule.c:1572:1: warning: 'thread' attribute directive ignored [-Wattributes] 1572 | static F2PY_THREAD_LOCAL_DECL cb_sselect_in_gees__user__routines_t *_active_cb_sselect_in_gees__user__routines = NULL; | ^~~~~~ scipy/linalg/_flapackmodule.c:1738:1: warning: 'thread' attribute directive ignored [-Wattributes] 1738 | static F2PY_THREAD_LOCAL_DECL cb_dselect_in_gees__user__routines_t *_active_cb_dselect_in_gees__user__routines = NULL; | ^~~~~~ ... ``` Also fixes gh-19437, where `__STDC_NO_THREADS__` should be defined but isn't (this seems to be more common, e.g. one can reports for ICC about this). --- numpy/f2py/cfuncs.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/numpy/f2py/cfuncs.py b/numpy/f2py/cfuncs.py index 528c4adeee77..bdd27adaf4c6 100644 --- a/numpy/f2py/cfuncs.py +++ b/numpy/f2py/cfuncs.py @@ -572,18 +572,20 @@ """ cppmacros["F2PY_THREAD_LOCAL_DECL"] = """\ #ifndef F2PY_THREAD_LOCAL_DECL -#if defined(_MSC_VER) \\ - || defined(_WIN32) || defined(_WIN64) \\ - || defined(__MINGW32__) || defined(__MINGW64__) +#if defined(_MSC_VER) #define F2PY_THREAD_LOCAL_DECL __declspec(thread) +#elif defined(__MINGW32__) || defined(__MINGW64__) +#define F2PY_THREAD_LOCAL_DECL __thread #elif defined(__STDC_VERSION__) \\ && (__STDC_VERSION__ >= 201112L) \\ && !defined(__STDC_NO_THREADS__) \\ - && (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12)) + && (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12)) \\ + && !defined(__OpenBSD__) /* __STDC_NO_THREADS__ was first defined in a maintenance release of glibc 2.12, see https://lists.gnu.org/archive/html/commit-hurd/2012-07/msg00180.html, so `!defined(__STDC_NO_THREADS__)` may give false positive for the existence - of `threads.h` when using an older release of glibc 2.12 */ + of `threads.h` when using an older release of glibc 2.12 + See gh-19437 for details on OpenBSD */ #include #define F2PY_THREAD_LOCAL_DECL thread_local #elif defined(__GNUC__) \\ From da485218c2be842f9d09e299ba9d71227418fe23 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Mon, 24 Jan 2022 12:30:21 +0100 Subject: [PATCH 11/30] BUG: distutils: fix building mixed C/Fortran extensions In SciPy we had a couple of cases where we build a Python extension with C source files but linked against static libraries built from Fortran code. Those should be using the Fortran linker, but this was broken in 1.22.0 by gh-19713 (the PR that introduced C++ in NumPy). This fixes a few issues in the `build_ext` command, and documents better what is going on there. Should close SciPy issues 8325 and 15414. --- numpy/distutils/command/build_ext.py | 30 +++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py index 7040a241167c..36a62eb1a06f 100644 --- a/numpy/distutils/command/build_ext.py +++ b/numpy/distutils/command/build_ext.py @@ -231,20 +231,36 @@ def report(copt): l = ext.language or self.compiler.detect_language(ext.sources) if l: ext_languages.add(l) + # reset language attribute for choosing proper linker + # + # When we build extensions with multiple languages, we have to + # choose a linker. The rules here are: + # 1. if there is Fortran code, always prefer the Fortran linker, + # 2. otherwise prefer C++ over C, + # 3. Users can force a particular linker by using + # `language='c'` # or 'c++', 'f90', 'f77' + # in their config.add_extension() calls. if 'c++' in ext_languages: ext_language = 'c++' - elif 'f90' in ext_languages: + else: + ext_language = 'c' # default + + has_fortran = False + if 'f90' in ext_languages: ext_language = 'f90' + has_fortran = True elif 'f77' in ext_languages: ext_language = 'f77' - else: - ext_language = 'c' # default - if l and l != ext_language and ext.language: - log.warn('resetting extension %r language from %r to %r.' % - (ext.name, l, ext_language)) - if not ext.language: + has_fortran = True + + if not ext.language or has_fortran: + if l and l != ext_language and ext.language: + log.warn('resetting extension %r language from %r to %r.' % + (ext.name, l, ext_language)) + ext.language = ext_language + # global language all_languages.update(ext_languages) From bb7c67c3667b077e29387427299236cd76beb532 Mon Sep 17 00:00:00 2001 From: Mukulika Date: Sun, 23 Jan 2022 13:16:31 +0530 Subject: [PATCH 12/30] DOC,TST: Fix Pandas code example as per new release --- doc/source/user/absolute_beginners.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/user/absolute_beginners.rst b/doc/source/user/absolute_beginners.rst index 27e9e1f638c3..90012da1c510 100644 --- a/doc/source/user/absolute_beginners.rst +++ b/doc/source/user/absolute_beginners.rst @@ -1589,7 +1589,7 @@ If you created this array "a" :: .. for doctests The continuous integration truncates dataframe display without this setting. - >>> pd.set_option('max_columns', 10) + >>> pd.set_option('display.max_columns', 10) You could create a Pandas dataframe :: From 8c7484707da6b12f14f5fcd5a74e4909b1a8b559 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Thu, 27 Jan 2022 17:47:55 -0700 Subject: [PATCH 13/30] TYP: Relax the return-type of np.vectorize (#20908) * MAINT: Relax the return-type of `np.vectorize` * DOC: Add a note regarding a potential future mypy plugin for dealing with literal signatures Co-authored-by: Bas van Beek <43369155+BvB93@users.noreply.github.com> --- numpy/__init__.pyi | 4 +++- numpy/typing/tests/data/reveal/lib_function_base.pyi | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 3f80eaa79dc1..c6f59c4ca716 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -3679,6 +3679,8 @@ class memmap(ndarray[_ShapeType, _DType_co]): ) -> Any: ... def flush(self) -> None: ... +# TODO: Add a mypy plugin for managing functions whose output type is dependant +# on the literal value of some sort of signature (e.g. `einsum` and `vectorize`) class vectorize: pyfunc: Callable[..., Any] cache: bool @@ -3695,7 +3697,7 @@ class vectorize: cache: bool = ..., signature: None | str = ..., ) -> None: ... - def __call__(self, *args: Any, **kwargs: Any) -> NDArray[Any]: ... + def __call__(self, *args: Any, **kwargs: Any) -> Any: ... class poly1d: @property diff --git a/numpy/typing/tests/data/reveal/lib_function_base.pyi b/numpy/typing/tests/data/reveal/lib_function_base.pyi index c559eb295893..eebe9fbfdc70 100644 --- a/numpy/typing/tests/data/reveal/lib_function_base.pyi +++ b/numpy/typing/tests/data/reveal/lib_function_base.pyi @@ -26,7 +26,7 @@ reveal_type(vectorized_func.signature) # E: Union[None, builtins.str] reveal_type(vectorized_func.otypes) # E: Union[None, builtins.str] reveal_type(vectorized_func.excluded) # E: set[Union[builtins.int, builtins.str]] reveal_type(vectorized_func.__doc__) # E: Union[None, builtins.str] -reveal_type(vectorized_func([1])) # E: ndarray[Any, dtype[Any]] +reveal_type(vectorized_func([1])) # E: Any reveal_type(np.vectorize(int)) # E: vectorize reveal_type(np.vectorize( # E: vectorize int, otypes="i", doc="doc", excluded=(), cache=True, signature=None From 07f0ee75927dceabc1c396985cd2865458d20ac9 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Thu, 27 Jan 2022 13:42:47 +0100 Subject: [PATCH 14/30] MAINT: Allow `flatiter.__getitem__` to accept 1-tuples --- numpy/__init__.pyi | 5 +++-- numpy/typing/tests/data/reveal/flatiter.pyi | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index c6f59c4ca716..75879711eb47 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -950,11 +950,12 @@ class flatiter(Generic[_NdArraySubClass]): @overload def __getitem__( self: flatiter[ndarray[Any, dtype[_ScalarType]]], - key: Union[int, integer], + key: int | integer | tuple[int | integer], ) -> _ScalarType: ... @overload def __getitem__( - self, key: Union[_ArrayLikeInt, slice, ellipsis], + self, + key: _ArrayLikeInt | slice | ellipsis | tuple[_ArrayLikeInt | slice | ellipsis], ) -> _NdArraySubClass: ... @overload def __array__(self: flatiter[ndarray[Any, _DType]], dtype: None = ..., /) -> ndarray[Any, _DType]: ... diff --git a/numpy/typing/tests/data/reveal/flatiter.pyi b/numpy/typing/tests/data/reveal/flatiter.pyi index ef89acb58a2a..61e8a3e91347 100644 --- a/numpy/typing/tests/data/reveal/flatiter.pyi +++ b/numpy/typing/tests/data/reveal/flatiter.pyi @@ -13,5 +13,7 @@ reveal_type(a[0]) # E: str_ reveal_type(a[[0, 1, 2]]) # E: ndarray[Any, dtype[str_]] reveal_type(a[...]) # E: ndarray[Any, dtype[str_]] reveal_type(a[:]) # E: ndarray[Any, dtype[str_]] +reveal_type(a[(...,)]) # E: ndarray[Any, dtype[str_]] +reveal_type(a[(0,)]) # E: str_ reveal_type(a.__array__()) # E: ndarray[Any, dtype[str_]] reveal_type(a.__array__(np.dtype(np.float64))) # E: ndarray[Any, dtype[{float64}]] From a528e854c048430d1807b18d4645980486f06cd9 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Thu, 27 Jan 2022 13:50:56 +0100 Subject: [PATCH 15/30] MAINT: Add annotations for `flatiter.__setitem__` --- numpy/__init__.pyi | 9 +++++++++ numpy/typing/tests/data/reveal/flatiter.pyi | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index 75879711eb47..672fd1945681 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -957,6 +957,15 @@ class flatiter(Generic[_NdArraySubClass]): self, key: _ArrayLikeInt | slice | ellipsis | tuple[_ArrayLikeInt | slice | ellipsis], ) -> _NdArraySubClass: ... + # TODO: `__setitem__` operates via `unsafe` casting rules, and can + # thus accept any type accepted by the relevant underlying `np.generic` + # constructor. + # This means that `value` must in reality be a supertype of `npt.ArrayLike`. + def __setitem__( + self, + key: _ArrayLikeInt | slice | ellipsis | tuple[_ArrayLikeInt | slice | ellipsis], + value: Any, + ) -> None: ... @overload def __array__(self: flatiter[ndarray[Any, _DType]], dtype: None = ..., /) -> ndarray[Any, _DType]: ... @overload diff --git a/numpy/typing/tests/data/reveal/flatiter.pyi b/numpy/typing/tests/data/reveal/flatiter.pyi index 61e8a3e91347..9e7d6e5452d1 100644 --- a/numpy/typing/tests/data/reveal/flatiter.pyi +++ b/numpy/typing/tests/data/reveal/flatiter.pyi @@ -17,3 +17,7 @@ reveal_type(a[(...,)]) # E: ndarray[Any, dtype[str_]] reveal_type(a[(0,)]) # E: str_ reveal_type(a.__array__()) # E: ndarray[Any, dtype[str_]] reveal_type(a.__array__(np.dtype(np.float64))) # E: ndarray[Any, dtype[{float64}]] +a[0] = "a" +a[:5] = "a" +a[...] = "a" +a[(...,)] = "a" From 3585a6e089d23ddea4de8f7f80451363599deeed Mon Sep 17 00:00:00 2001 From: Janus Heide Date: Thu, 27 Jan 2022 18:10:37 +0100 Subject: [PATCH 16/30] added missing where typehints in fromnumeric.pyi --- numpy/core/fromnumeric.pyi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/numpy/core/fromnumeric.pyi b/numpy/core/fromnumeric.pyi index 3cbe1d5c5ce2..c8ef5d53d97a 100644 --- a/numpy/core/fromnumeric.pyi +++ b/numpy/core/fromnumeric.pyi @@ -246,6 +246,7 @@ def all( axis: None = ..., out: None = ..., keepdims: Literal[False] = ..., + where: _ArrayLikeBool_co = ..., ) -> bool_: ... @overload def all( @@ -253,6 +254,7 @@ def all( axis: Optional[_ShapeLike] = ..., out: Optional[ndarray] = ..., keepdims: bool = ..., + where: _ArrayLikeBool_co = ..., ) -> Any: ... @overload @@ -261,6 +263,7 @@ def any( axis: None = ..., out: None = ..., keepdims: Literal[False] = ..., + where: _ArrayLikeBool_co = ..., ) -> bool_: ... @overload def any( @@ -268,6 +271,7 @@ def any( axis: Optional[_ShapeLike] = ..., out: Optional[ndarray] = ..., keepdims: bool = ..., + where: _ArrayLikeBool_co = ..., ) -> Any: ... def cumsum( @@ -342,6 +346,7 @@ def mean( dtype: DTypeLike = ..., out: Optional[ndarray] = ..., keepdims: bool = ..., + where: _ArrayLikeBool_co = ..., ) -> Any: ... def std( @@ -351,6 +356,7 @@ def std( out: Optional[ndarray] = ..., ddof: int = ..., keepdims: bool = ..., + where: _ArrayLikeBool_co = ..., ) -> Any: ... def var( @@ -360,4 +366,5 @@ def var( out: Optional[ndarray] = ..., ddof: int = ..., keepdims: bool = ..., + where: _ArrayLikeBool_co = ..., ) -> Any: ... From 71bd34192e9c259ec4ff72061ee9f98ba4544607 Mon Sep 17 00:00:00 2001 From: Janus Date: Fri, 28 Jan 2022 08:12:47 +0100 Subject: [PATCH 17/30] Update numpy/core/fromnumeric.pyi Co-authored-by: Bas van Beek <43369155+BvB93@users.noreply.github.com> --- numpy/core/fromnumeric.pyi | 1 + 1 file changed, 1 insertion(+) diff --git a/numpy/core/fromnumeric.pyi b/numpy/core/fromnumeric.pyi index c8ef5d53d97a..0f0c0e8dd70e 100644 --- a/numpy/core/fromnumeric.pyi +++ b/numpy/core/fromnumeric.pyi @@ -246,6 +246,7 @@ def all( axis: None = ..., out: None = ..., keepdims: Literal[False] = ..., + *, where: _ArrayLikeBool_co = ..., ) -> bool_: ... @overload From 1e1739f467724a6891c896fd4ef0c5b613cd4e60 Mon Sep 17 00:00:00 2001 From: Janus Heide Date: Fri, 28 Jan 2022 09:01:01 +0100 Subject: [PATCH 18/30] consistency between keyword only where arguments --- numpy/core/fromnumeric.pyi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/numpy/core/fromnumeric.pyi b/numpy/core/fromnumeric.pyi index 0f0c0e8dd70e..4a5e50503fe0 100644 --- a/numpy/core/fromnumeric.pyi +++ b/numpy/core/fromnumeric.pyi @@ -255,6 +255,7 @@ def all( axis: Optional[_ShapeLike] = ..., out: Optional[ndarray] = ..., keepdims: bool = ..., + *, where: _ArrayLikeBool_co = ..., ) -> Any: ... @@ -264,6 +265,7 @@ def any( axis: None = ..., out: None = ..., keepdims: Literal[False] = ..., + *, where: _ArrayLikeBool_co = ..., ) -> bool_: ... @overload @@ -272,6 +274,7 @@ def any( axis: Optional[_ShapeLike] = ..., out: Optional[ndarray] = ..., keepdims: bool = ..., + *, where: _ArrayLikeBool_co = ..., ) -> Any: ... @@ -347,6 +350,7 @@ def mean( dtype: DTypeLike = ..., out: Optional[ndarray] = ..., keepdims: bool = ..., + *, where: _ArrayLikeBool_co = ..., ) -> Any: ... @@ -357,6 +361,7 @@ def std( out: Optional[ndarray] = ..., ddof: int = ..., keepdims: bool = ..., + *, where: _ArrayLikeBool_co = ..., ) -> Any: ... @@ -367,5 +372,6 @@ def var( out: Optional[ndarray] = ..., ddof: int = ..., keepdims: bool = ..., + *, where: _ArrayLikeBool_co = ..., ) -> Any: ... From b48b73b427d0926736bac62fac27d519df4c25d9 Mon Sep 17 00:00:00 2001 From: Janus Heide Date: Fri, 28 Jan 2022 09:06:13 +0100 Subject: [PATCH 19/30] added where typehints to __init__.pyi --- numpy/__init__.pyi | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi index c6f59c4ca716..0684f477c716 100644 --- a/numpy/__init__.pyi +++ b/numpy/__init__.pyi @@ -1030,6 +1030,8 @@ class _ArrayOrScalarCommon: axis: None = ..., out: None = ..., keepdims: L[False] = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> bool_: ... @overload def all( @@ -1037,6 +1039,8 @@ class _ArrayOrScalarCommon: axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> Any: ... @overload def all( @@ -1044,6 +1048,8 @@ class _ArrayOrScalarCommon: axis: Optional[_ShapeLike] = ..., out: _NdArraySubClass = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> _NdArraySubClass: ... @overload @@ -1052,6 +1058,8 @@ class _ArrayOrScalarCommon: axis: None = ..., out: None = ..., keepdims: L[False] = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> bool_: ... @overload def any( @@ -1059,6 +1067,8 @@ class _ArrayOrScalarCommon: axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> Any: ... @overload def any( @@ -1066,6 +1076,8 @@ class _ArrayOrScalarCommon: axis: Optional[_ShapeLike] = ..., out: _NdArraySubClass = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> _NdArraySubClass: ... @overload @@ -1248,6 +1260,8 @@ class _ArrayOrScalarCommon: dtype: DTypeLike = ..., out: None = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> Any: ... @overload def mean( @@ -1256,6 +1270,8 @@ class _ArrayOrScalarCommon: dtype: DTypeLike = ..., out: _NdArraySubClass = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> _NdArraySubClass: ... @overload @@ -1339,6 +1355,8 @@ class _ArrayOrScalarCommon: out: None = ..., ddof: int = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> Any: ... @overload def std( @@ -1348,6 +1366,8 @@ class _ArrayOrScalarCommon: out: _NdArraySubClass = ..., ddof: int = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> _NdArraySubClass: ... @overload @@ -1379,6 +1399,8 @@ class _ArrayOrScalarCommon: out: None = ..., ddof: int = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> Any: ... @overload def var( @@ -1388,6 +1410,8 @@ class _ArrayOrScalarCommon: out: _NdArraySubClass = ..., ddof: int = ..., keepdims: bool = ..., + *, + where: _ArrayLikeBool_co = ..., ) -> _NdArraySubClass: ... _DType = TypeVar("_DType", bound=dtype[Any]) From 3f83722e974c36fc4720b757c2ebeb35fa67dae7 Mon Sep 17 00:00:00 2001 From: serge-sans-paille Date: Fri, 28 Jan 2022 19:45:38 +0100 Subject: [PATCH 20/30] Fix build_ext interaction with non numpy extensions Numpy extensions define the extra_cxx_compile_args and extra_c_compile_args filed, but distutils extensions don't. Take that into account when populating build_extension. Should fix #20928 --- numpy/distutils/command/build_ext.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py index 36a62eb1a06f..8b568c1596de 100644 --- a/numpy/distutils/command/build_ext.py +++ b/numpy/distutils/command/build_ext.py @@ -393,8 +393,8 @@ def build_extension(self, ext): log.info("building '%s' extension", ext.name) extra_args = ext.extra_compile_args or [] - extra_cflags = ext.extra_c_compile_args or [] - extra_cxxflags = ext.extra_cxx_compile_args or [] + extra_cflags = getattr(ext, 'extra_c_compile_args', None) or [] + extra_cxxflags = getattr(ext, 'extra_cxx_compile_args', None) or [] macros = ext.define_macros[:] for undef in ext.undef_macros: From af98814b97c1a85767d03fdf8ff509a3ff5a6777 Mon Sep 17 00:00:00 2001 From: Niyas Sait Date: Fri, 28 Jan 2022 14:26:13 +0000 Subject: [PATCH 21/30] Fixes #20930 Do not use __popcnt and variants for windows/arm64 target --- numpy/core/src/npymath/npy_math_internal.h.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/core/src/npymath/npy_math_internal.h.src b/numpy/core/src/npymath/npy_math_internal.h.src index 15d35637fb04..d43dcae9b64e 100644 --- a/numpy/core/src/npymath/npy_math_internal.h.src +++ b/numpy/core/src/npymath/npy_math_internal.h.src @@ -887,7 +887,7 @@ npy_popcountu@c@(npy_@type@ a) /* use built-in popcount if present, else use our implementation */ #if (defined(__clang__) || defined(__GNUC__)) && NPY_BITSOF_@STYPE@ >= 32 return __builtin_popcount@c@(a); -#elif defined(_MSC_VER) && NPY_BITSOF_@STYPE@ >= 16 +#elif defined(_MSC_VER) && NPY_BITSOF_@STYPE@ >= 16 && !defined(_M_ARM64) /* no builtin __popcnt64 for 32 bits */ #if defined(_WIN64) || (defined(_WIN32) && NPY_BITSOF_@STYPE@ != 64) return TO_BITS_LEN(__popcnt)(a); From e3afb6d372e1c0fafef2374e4d25f3717d68b3ad Mon Sep 17 00:00:00 2001 From: Niyas Sait Date: Fri, 28 Jan 2022 16:12:54 +0000 Subject: [PATCH 22/30] Extend fix for ARM32 --- numpy/core/src/npymath/npy_math_internal.h.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/numpy/core/src/npymath/npy_math_internal.h.src b/numpy/core/src/npymath/npy_math_internal.h.src index d43dcae9b64e..0364aabb1a9b 100644 --- a/numpy/core/src/npymath/npy_math_internal.h.src +++ b/numpy/core/src/npymath/npy_math_internal.h.src @@ -887,7 +887,7 @@ npy_popcountu@c@(npy_@type@ a) /* use built-in popcount if present, else use our implementation */ #if (defined(__clang__) || defined(__GNUC__)) && NPY_BITSOF_@STYPE@ >= 32 return __builtin_popcount@c@(a); -#elif defined(_MSC_VER) && NPY_BITSOF_@STYPE@ >= 16 && !defined(_M_ARM64) +#elif defined(_MSC_VER) && NPY_BITSOF_@STYPE@ >= 16 && !defined(_M_ARM64) && !defined(_M_ARM) /* no builtin __popcnt64 for 32 bits */ #if defined(_WIN64) || (defined(_WIN32) && NPY_BITSOF_@STYPE@ != 64) return TO_BITS_LEN(__popcnt)(a); From 9d4c486029cfd8ab1325456a3e2b922e9b528fbf Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Sat, 29 Jan 2022 12:33:06 -0700 Subject: [PATCH 23/30] REL: Prepare for the NumPy 1.22.2 release. - Create 1.22.2-changelog.rst. - Update 1.22.2-notes.rst. - Update .mailmap. --- .mailmap | 8 ++++-- doc/changelog/1.22.2-changelog.rst | 38 +++++++++++++++++++++++++ doc/source/release/1.22.2-notes.rst | 44 +++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 doc/changelog/1.22.2-changelog.rst diff --git a/.mailmap b/.mailmap index 862e3d63cdb7..d3f8dba95b96 100644 --- a/.mailmap +++ b/.mailmap @@ -111,12 +111,13 @@ Bharat Raghunathan Bob Eldering Brent Brewington Brett R Murphy -Brigitta Sipocz Brian Soto -Brian Soto Brian Soto +Brian Soto +Brigitta Sipocz Bryan Van de Ven Bryan Van de Ven Bryan Van de Ven Bryan Van de Ven +Brénainn Woodsend Bui Duc Minh <41239569+Mibu287@users.noreply.github.com> Carl Kleffner Carl Leake @@ -231,12 +232,13 @@ Jack J. Woehr Jaime Fernandez Jaime Fernandez Jaime Fernandez -Jamie Macey Jakob Jakobson Jakob Jakobson <43045863+jakobjakobson13@users.noreply.github.com> James Bourbeau James Webber +Jamie Macey Jan Schlüter +Janus Heide Jarrod Millman Jarrod Millman Jason Grout Jason King diff --git a/doc/changelog/1.22.2-changelog.rst b/doc/changelog/1.22.2-changelog.rst new file mode 100644 index 000000000000..89ff3e9623ae --- /dev/null +++ b/doc/changelog/1.22.2-changelog.rst @@ -0,0 +1,38 @@ + +Contributors +============ + +A total of 11 people contributed to this release. People with a "+" by their +names contributed a patch for the first time. + +* Andrew J. Hesford + +* Bas van Beek +* Brénainn Woodsend + +* Charles Harris +* Hood Chatham +* Janus Heide + +* Leo Singer +* Mukulika Pahari +* Niyas Sait +* Ralf Gommers +* Serge Guelton + +Pull requests merged +==================== + +A total of 14 pull requests were merged for this release. + +* `#20842 `__: BLD: Add NPY_DISABLE_SVML env var to opt out of SVML +* `#20843 `__: BUG: Fix build of third party extensions with Py_LIMITED_API +* `#20844 `__: TYP: Fix pyright being unable to infer the ``real`` and ``imag``... +* `#20845 `__: BUG: Fix comparator function signatures +* `#20906 `__: BUG: Avoid importing ``numpy.distutils`` on import numpy.testing +* `#20907 `__: MAINT: remove outdated mingw32 fseek support +* `#20908 `__: TYP: Relax the return type of ``np.vectorize`` +* `#20909 `__: BUG: fix f2py's define for threading when building with Mingw +* `#20910 `__: BUG: distutils: fix building mixed C/Fortran extensions +* `#20912 `__: DOC,TST: Fix Pandas code example as per new release +* `#20935 `__: TYP, MAINT: Add annotations for ``flatiter.__setitem__`` +* `#20936 `__: MAINT, TYP: Added missing where typehints in ``fromnumeric.pyi`` +* `#20937 `__: BUG: Fix build_ext interaction with non numpy extensions +* `#20938 `__: BUG: Fix missing intrinsics for windows/arm64 target diff --git a/doc/source/release/1.22.2-notes.rst b/doc/source/release/1.22.2-notes.rst index 52da4c1312f7..913d4fec1f79 100644 --- a/doc/source/release/1.22.2-notes.rst +++ b/doc/source/release/1.22.2-notes.rst @@ -7,4 +7,48 @@ NumPy 1.22.2 Release Notes The NumPy 1.22.2 is maintenance release that fixes bugs discovered after the 1.22.1 release. Notable fixes are: +- Several build related fixes for downstream projects and other platforms. +- Various Annotation fixes/additions. +- Numpy wheels for Windows will use the 1.41 tool chain, fixing downstream link + problems for projects using NumPy provided libraries on Windows. + The Python versions supported for this release are 3.8-3.10. + +Contributors +============ + +A total of 11 people contributed to this release. People with a "+" by their +names contributed a patch for the first time. + +* Andrew J. Hesford + +* Bas van Beek +* Brénainn Woodsend + +* Charles Harris +* Hood Chatham +* Janus Heide + +* Leo Singer +* Mukulika Pahari +* Niyas Sait +* Ralf Gommers +* Serge Guelton + +Pull requests merged +==================== + +A total of 14 pull requests were merged for this release. + +* `#20842 `__: BLD: Add NPY_DISABLE_SVML env var to opt out of SVML +* `#20843 `__: BUG: Fix build of third party extensions with Py_LIMITED_API +* `#20844 `__: TYP: Fix pyright being unable to infer the ``real`` and ``imag``... +* `#20845 `__: BUG: Fix comparator function signatures +* `#20906 `__: BUG: Avoid importing ``numpy.distutils`` on import numpy.testing +* `#20907 `__: MAINT: remove outdated mingw32 fseek support +* `#20908 `__: TYP: Relax the return type of ``np.vectorize`` +* `#20909 `__: BUG: fix f2py's define for threading when building with Mingw +* `#20910 `__: BUG: distutils: fix building mixed C/Fortran extensions +* `#20912 `__: DOC,TST: Fix Pandas code example as per new release +* `#20935 `__: TYP, MAINT: Add annotations for ``flatiter.__setitem__`` +* `#20936 `__: MAINT, TYP: Added missing where type hints in ``fromnumeric.pyi`` +* `#20937 `__: BUG: Fix build_ext interaction with non numpy extensions +* `#20938 `__: BUG: Fix missing intrinsics for windows/arm64 target + From 8dc2c49b5d754c6fc8478cf59e06668213973af8 Mon Sep 17 00:00:00 2001 From: Ralf Gommers Date: Tue, 1 Feb 2022 18:26:34 +0100 Subject: [PATCH 24/30] MAINT: f2py: don't generate code that triggers `-Wsometimes-uninitialized` (#20940) * MAINT: f2py: don't generate code that triggers `-Wsometimes-uninitialized` Warnings look like: ``` scipy/linalg/_flapackmodule.c:2200:9: warning: variable 'return_value' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized] if (capi_j>capi_i) ^~~~~~~~~~~~~ scipy/linalg/_flapackmodule.c:2217:12: note: uninitialized use occurs here return return_value; ^~~~~~~~~~~~ scipy/linalg/_flapackmodule.c:2200:5: note: remove the 'if' if its condition is always true if (capi_j>capi_i) ^~~~~~~~~~~~~~~~~~ scipy/linalg/_flapackmodule.c:2099:21: note: initialize the variable 'return_value' to silence this warning int return_value; ^ = 0 ``` Also: - Initialize complex return value. - Warn on non-void callback returning None. - Use brackets in if-else block. This makes the code more readable. Co-authored-by: Pearu Peterson --- numpy/f2py/cb_rules.py | 67 ++++++++++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/numpy/f2py/cb_rules.py b/numpy/f2py/cb_rules.py index 4848233d43a5..c2d7faaad9bf 100644 --- a/numpy/f2py/cb_rules.py +++ b/numpy/f2py/cb_rules.py @@ -230,12 +230,21 @@ def #argname#(#docsignature#): return #docreturn#\\n\\ 'latexdocstrcbs': '\\noindent Call-back functions:', 'routnote': {hasnote: '--- #note#', l_not(hasnote): ''}, }, { # Function - 'decl': ' #ctype# return_value;', - 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'}, - ' if (capi_j>capi_i)\n GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n");', - {debugcapi: - ' fprintf(stderr,"#showvalueformat#.\\n",return_value);'} - ], + 'decl': ' #ctype# return_value = 0;', + 'frompyobj': [ + {debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'}, + '''\ + if (capi_j>capi_i) { + GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#, + "#ctype#_from_pyobj failed in converting return_value of" + " call-back function #name# to C #ctype#\\n"); + } else { + fprintf(stderr,"Warning: call-back function #name# did not provide" + " return value (index=%d, type=#ctype#)\\n",capi_i); + }''', + {debugcapi: + ' fprintf(stderr,"#showvalueformat#.\\n",return_value);'} + ], 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'GETSCALARFROMPYTUPLE'], 'return': ' return return_value;', '_check': l_and(isfunction, l_not(isstringfunction), l_not(iscomplexfunction)) @@ -245,12 +254,18 @@ def #argname#(#docsignature#): return #docreturn#\\n\\ 'args': '#ctype# return_value,int return_value_len', 'args_nm': 'return_value,&return_value_len', 'args_td': '#ctype# ,int', - 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting return_value->\\"");'}, - """ if (capi_j>capi_i) - GETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len);""", - {debugcapi: - ' fprintf(stderr,"#showvalueformat#\\".\\n",return_value);'} - ], + 'frompyobj': [ + {debugcapi: ' CFUNCSMESS("cb:Getting return_value->\\"");'}, + """\ + if (capi_j>capi_i) { + GETSTRFROMPYTUPLE(capi_return,capi_i++,return_value,return_value_len); + } else { + fprintf(stderr,"Warning: call-back function #name# did not provide" + " return value (index=%d, type=#ctype#)\\n",capi_i); + }""", + {debugcapi: + ' fprintf(stderr,"#showvalueformat#\\".\\n",return_value);'} + ], 'need': ['#ctype#_from_pyobj', {debugcapi: 'CFUNCSMESS'}, 'string.h', 'GETSTRFROMPYTUPLE'], 'return': 'return;', @@ -274,27 +289,35 @@ def #argname#(#docsignature#): return #docreturn#\\n\\ """, 'decl': """ #ifdef F2PY_CB_RETURNCOMPLEX - #ctype# return_value; + #ctype# return_value = {0, 0}; #endif """, - 'frompyobj': [{debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'}, - """\ - if (capi_j>capi_i) + 'frompyobj': [ + {debugcapi: ' CFUNCSMESS("cb:Getting return_value->");'}, + """\ + if (capi_j>capi_i) { #ifdef F2PY_CB_RETURNCOMPLEX - GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\"); + GETSCALARFROMPYTUPLE(capi_return,capi_i++,&return_value,#ctype#, + \"#ctype#_from_pyobj failed in converting return_value of call-back\" + \" function #name# to C #ctype#\\n\"); #else - GETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#,\"#ctype#_from_pyobj failed in converting return_value of call-back function #name# to C #ctype#\\n\"); + GETSCALARFROMPYTUPLE(capi_return,capi_i++,return_value,#ctype#, + \"#ctype#_from_pyobj failed in converting return_value of call-back\" + \" function #name# to C #ctype#\\n\"); #endif -""", - {debugcapi: """ + } else { + fprintf(stderr, + \"Warning: call-back function #name# did not provide\" + \" return value (index=%d, type=#ctype#)\\n\",capi_i); + }""", + {debugcapi: """\ #ifdef F2PY_CB_RETURNCOMPLEX fprintf(stderr,\"#showvalueformat#.\\n\",(return_value).r,(return_value).i); #else fprintf(stderr,\"#showvalueformat#.\\n\",(*return_value).r,(*return_value).i); #endif - """} - ], + ], 'return': """ #ifdef F2PY_CB_RETURNCOMPLEX return return_value; From 2d05278eb79711b019eaa75f4684545ae1d4596c Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Mon, 31 Jan 2022 12:38:08 -0600 Subject: [PATCH 25/30] BUG: Fix incorrect return type in reduce without initial value The return type should not be integer of course (why doesn't C warn about this?). Closes gh-20921 --- numpy/core/src/umath/reduction.c | 2 +- numpy/core/tests/test_ufunc.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/numpy/core/src/umath/reduction.c b/numpy/core/src/umath/reduction.c index 8cb44d4338a7..06709b4f36fd 100644 --- a/numpy/core/src/umath/reduction.c +++ b/numpy/core/src/umath/reduction.c @@ -68,7 +68,7 @@ count_axes(int ndim, const npy_bool *axis_flags) * Returns -1 if an error occurred, and otherwise the reduce arrays size, * which is the number of elements already initialized. */ -NPY_NO_EXPORT int +static npy_intp PyArray_CopyInitialReduceValues( PyArrayObject *result, PyArrayObject *operand, const npy_bool *axis_flags, const char *funcname, diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py index 1e0829f0d927..5328acea863a 100644 --- a/numpy/core/tests/test_ufunc.py +++ b/numpy/core/tests/test_ufunc.py @@ -14,6 +14,7 @@ assert_almost_equal, assert_array_almost_equal, assert_no_warnings, assert_allclose, HAS_REFCOUNT, suppress_warnings ) +from numpy.testing._private.utils import requires_memory from numpy.compat import pickle @@ -1555,6 +1556,17 @@ def check_identityless_reduction(self, a): [[0, 1, 1], [1, 1, 1]]) assert_equal(np.minimum.reduce(a, axis=()), a) + @requires_memory(6 * 1024**3) + def test_identityless_reduction_huge_array(self): + # Regression test for gh-20921 (copying identity incorrectly failed) + arr = np.zeros((2, 2**31), 'uint8') + arr[:, 0] = [1, 3] + arr[:, -1] = [4, 1] + res = np.maximum.reduce(arr, axis=0) + del arr + assert res[0] == 3 + assert res[-1] == 4 + def test_identityless_reduction_corder(self): a = np.empty((2, 3, 4), order='C') self.check_identityless_reduction(a) From 7f17bf75a6e6ff7595ce96c5cdf7de1ab0f17c8f Mon Sep 17 00:00:00 2001 From: Matti Picus Date: Wed, 2 Feb 2022 22:46:17 +0200 Subject: [PATCH 26/30] ENH: review return values for PyArray_DescrNew (#20960) * ENH: review return value from PyArray_DescrNew* calls * BUG: remove unused variable * BUG: typo * Update numpy/core/src/multiarray/methods.c Co-authored-by: Sebastian Berg * Update numpy/core/src/multiarray/methods.c Co-authored-by: Sebastian Berg * Update numpy/core/src/multiarray/getset.c Co-authored-by: Sebastian Berg * Update numpy/core/src/multiarray/methods.c Co-authored-by: Sebastian Berg * fixes from review * Update numpy/core/src/umath/ufunc_type_resolution.c Co-authored-by: Sebastian Berg * move check to internal function * remove check * Remove unnecessary dealloc The dealloc is now part of the Py_DECREF(ret) and handled there. Doing it here would decref it twice. * MAINT: Remove custom error message (and small cleanup) It is probably not good to call PyObject_GetIter() if dtype is NULL and an error is already in progress... (If we check for it, lets try to do it right.) * Fixup DescrNewFromType `DescrNewFromType` cannot fail in most cases, but if it does, DescrNew does not accept NULL as input. Co-authored-by: Sebastian Berg --- .../src/multiarray/_multiarray_tests.c.src | 4 +-- numpy/core/src/multiarray/arrayobject.c | 3 ++ numpy/core/src/multiarray/buffer.c | 6 ++++ numpy/core/src/multiarray/ctors.c | 24 ++++++++++++++- numpy/core/src/multiarray/descriptor.c | 30 ++++++++++++++----- numpy/core/src/multiarray/dtypemeta.c | 8 +++++ numpy/core/src/multiarray/getset.c | 13 ++++---- numpy/core/src/multiarray/methods.c | 17 +++++++++++ numpy/core/src/multiarray/nditer_constr.c | 11 ++++--- numpy/core/src/multiarray/scalarapi.c | 3 ++ numpy/core/src/multiarray/scalartypes.c.src | 10 +++++-- 11 files changed, 104 insertions(+), 25 deletions(-) diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src index 9486b7cffa5b..b7a8b08495f9 100644 --- a/numpy/core/src/multiarray/_multiarray_tests.c.src +++ b/numpy/core/src/multiarray/_multiarray_tests.c.src @@ -643,14 +643,12 @@ static PyObject * fromstring_null_term_c_api(PyObject *dummy, PyObject *byte_obj) { char *string; - PyArray_Descr *descr; string = PyBytes_AsString(byte_obj); if (string == NULL) { return NULL; } - descr = PyArray_DescrNewFromType(NPY_FLOAT64); - return PyArray_FromString(string, -1, descr, -1, " "); + return PyArray_FromString(string, -1, NULL, -1, " "); } diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c index f99de2a39b4f..292523bbc26d 100644 --- a/numpy/core/src/multiarray/arrayobject.c +++ b/numpy/core/src/multiarray/arrayobject.c @@ -1005,6 +1005,9 @@ _strings_richcompare(PyArrayObject *self, PyArrayObject *other, int cmp_op, if (PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(other)) { /* Cast `other` to the same byte order as `self` (both unicode here) */ PyArray_Descr* unicode = PyArray_DescrNew(PyArray_DESCR(self)); + if (unicode == NULL) { + return NULL; + } unicode->elsize = PyArray_DESCR(other)->elsize; PyObject *new = PyArray_FromAny((PyObject *)other, unicode, 0, 0, 0, NULL); diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index d10122c4f190..d14f87abb843 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -1048,12 +1048,18 @@ _descriptor_from_pep3118_format_fast(char const *s, PyObject **result) } descr = PyArray_DescrFromType(type_num); + if (descr == NULL) { + return 0; + } if (byte_order == '=') { *result = (PyObject*)descr; } else { *result = (PyObject*)PyArray_DescrNewByteorder(descr, byte_order); Py_DECREF(descr); + if (result == NULL) { + return 0; + } } return 1; diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 78003306afe9..2535569a68f6 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -668,6 +668,9 @@ PyArray_NewFromDescr_int( PyArrayObject_fields *fa; npy_intp nbytes; + if (descr == NULL) { + return NULL; + } if (nd > NPY_MAXDIMS || nd < 0) { PyErr_Format(PyExc_ValueError, "number of dimensions must be within [0, %d]", NPY_MAXDIMS); @@ -1115,6 +1118,9 @@ PyArray_New( return NULL; } PyArray_DESCR_REPLACE(descr); + if (descr == NULL) { + return NULL; + } descr->elsize = itemsize; } new = PyArray_NewFromDescr(subtype, descr, nd, dims, strides, @@ -1140,6 +1146,9 @@ _dtype_from_buffer_3118(PyObject *memoryview) * terminate. */ descr = PyArray_DescrNewFromType(NPY_STRING); + if (descr == NULL) { + return NULL; + } descr->elsize = view->itemsize; } return descr; @@ -3583,6 +3592,10 @@ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep) PyArrayObject *ret; size_t nread = 0; + if (dtype == NULL) { + return NULL; + } + if (PyDataType_REFCHK(dtype)) { PyErr_SetString(PyExc_ValueError, "Cannot read into object array"); @@ -3650,6 +3663,9 @@ PyArray_FromBuffer(PyObject *buf, PyArray_Descr *type, int itemsize; int writeable = 1; + if (type == NULL) { + return NULL; + } if (PyDataType_REFCHK(type)) { PyErr_SetString(PyExc_ValueError, @@ -3857,14 +3873,20 @@ NPY_NO_EXPORT PyObject * PyArray_FromIter(PyObject *obj, PyArray_Descr *dtype, npy_intp count) { PyObject *value; - PyObject *iter = PyObject_GetIter(obj); + PyObject *iter = NULL; PyArrayObject *ret = NULL; npy_intp i, elsize, elcount; char *item, *new_data; + if (dtype == NULL) { + return NULL; + } + + iter = PyObject_GetIter(obj); if (iter == NULL) { goto done; } + if (PyDataType_ISUNSIZED(dtype)) { PyErr_SetString(PyExc_ValueError, "Must specify length when using variable-size data-type."); diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 0c539053c9e7..a5cb6a9fcad0 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -1381,6 +1381,9 @@ PyArray_DescrNewFromType(int type_num) PyArray_Descr *new; old = PyArray_DescrFromType(type_num); + if (old == NULL) { + return NULL; + } new = PyArray_DescrNew(old); Py_DECREF(old); return new; @@ -2341,7 +2344,7 @@ arraydescr_new(PyTypeObject *subtype, } PyObject *odescr, *metadata=NULL; - PyArray_Descr *descr, *conv; + PyArray_Descr *conv; npy_bool align = NPY_FALSE; npy_bool copy = NPY_FALSE; npy_bool copied = NPY_FALSE; @@ -2363,9 +2366,10 @@ arraydescr_new(PyTypeObject *subtype, /* Get a new copy of it unless it's already a copy */ if (copy && conv->fields == Py_None) { - descr = PyArray_DescrNew(conv); - Py_DECREF(conv); - conv = descr; + PyArray_DESCR_REPLACE(conv); + if (conv == NULL) { + return NULL; + } copied = NPY_TRUE; } @@ -2375,10 +2379,11 @@ arraydescr_new(PyTypeObject *subtype, * underlying dictionary */ if (!copied) { + PyArray_DESCR_REPLACE(conv); + if (conv == NULL) { + return NULL; + } copied = NPY_TRUE; - descr = PyArray_DescrNew(conv); - Py_DECREF(conv); - conv = descr; } if ((conv->metadata != NULL)) { /* @@ -3047,6 +3052,9 @@ PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) char endian; new = PyArray_DescrNew(self); + if (new == NULL) { + return NULL; + } endian = new->byteorder; if (endian != NPY_IGNORE) { if (newendian == NPY_SWAP) { @@ -3073,6 +3081,10 @@ PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) int len, i; newfields = PyDict_New(); + if (newfields == NULL) { + Py_DECREF(new); + return NULL; + } /* make new dictionary with replaced PyArray_Descr Objects */ while (PyDict_Next(self->fields, &pos, &key, &value)) { if (NPY_TITLE_KEY(key, value)) { @@ -3114,6 +3126,10 @@ PyArray_DescrNewByteorder(PyArray_Descr *self, char newendian) Py_DECREF(new->subarray->base); new->subarray->base = PyArray_DescrNewByteorder( self->subarray->base, newendian); + if (new->subarray->base == NULL) { + Py_DECREF(new); + return NULL; + } } return new; } diff --git a/numpy/core/src/multiarray/dtypemeta.c b/numpy/core/src/multiarray/dtypemeta.c index cd489d5e7c9d..53f38e8e8b1a 100644 --- a/numpy/core/src/multiarray/dtypemeta.c +++ b/numpy/core/src/multiarray/dtypemeta.c @@ -153,6 +153,9 @@ string_discover_descr_from_pyobject( "string to large to store inside array."); } PyArray_Descr *res = PyArray_DescrNewFromType(cls->type_num); + if (res == NULL) { + return NULL; + } res->elsize = (int)itemsize; return res; } @@ -171,10 +174,15 @@ void_discover_descr_from_pyobject( } if (PyBytes_Check(obj)) { PyArray_Descr *descr = PyArray_DescrNewFromType(NPY_VOID); + if (descr == NULL) { + return NULL; + } Py_ssize_t itemsize = PyBytes_Size(obj); if (itemsize > NPY_MAX_INT) { PyErr_SetString(PyExc_TypeError, "byte-like to large to store inside array."); + Py_DECREF(descr); + return NULL; } descr->elsize = (int)itemsize; return descr; diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c index a92ac44b7846..fc43bb3fe026 100644 --- a/numpy/core/src/multiarray/getset.c +++ b/numpy/core/src/multiarray/getset.c @@ -714,15 +714,18 @@ _get_part(PyArrayObject *self, int imag) } type = PyArray_DescrFromType(float_type_num); + if (type == NULL) { + return NULL; + } offset = (imag ? type->elsize : 0); if (!PyArray_ISNBO(PyArray_DESCR(self)->byteorder)) { - PyArray_Descr *new; - new = PyArray_DescrNew(type); - new->byteorder = PyArray_DESCR(self)->byteorder; - Py_DECREF(type); - type = new; + Py_SETREF(type, PyArray_DescrNew(type)); + if (type == NULL) { + return NULL; + } + type->byteorder = PyArray_DESCR(self)->byteorder; } ret = (PyArrayObject *)PyArray_NewFromDescrAndBase( Py_TYPE(self), diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index c31a8292ce32..20a70a37e862 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -1330,6 +1330,10 @@ array_sort(PyArrayObject *self, return NULL; } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } Py_DECREF(newd->names); newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; @@ -1455,6 +1459,10 @@ array_argsort(PyArrayObject *self, return NULL; } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } Py_DECREF(newd->names); newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; @@ -1512,6 +1520,10 @@ array_argpartition(PyArrayObject *self, return NULL; } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } Py_DECREF(newd->names); newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; @@ -2144,6 +2156,11 @@ array_setstate(PyArrayObject *self, PyObject *args) } else { fa->descr = PyArray_DescrNew(typecode); + if (fa->descr == NULL) { + Py_CLEAR(fa->mem_handler); + Py_DECREF(rawdata); + return NULL; + } if (PyArray_DESCR(self)->byteorder == NPY_BIG) { PyArray_DESCR(self)->byteorder = NPY_LITTLE; } diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c index bf32e1f6b706..2812aaf3cb51 100644 --- a/numpy/core/src/multiarray/nditer_constr.c +++ b/numpy/core/src/multiarray/nditer_constr.c @@ -1128,13 +1128,12 @@ npyiter_prepare_one_operand(PyArrayObject **op, if (op_flags & NPY_ITER_NBO) { /* Check byte order */ if (!PyArray_ISNBO((*op_dtype)->byteorder)) { - PyArray_Descr *nbo_dtype; - /* Replace with a new descr which is in native byte order */ - nbo_dtype = PyArray_DescrNewByteorder(*op_dtype, NPY_NATIVE); - Py_DECREF(*op_dtype); - *op_dtype = nbo_dtype; - + Py_SETREF(*op_dtype, + PyArray_DescrNewByteorder(*op_dtype, NPY_NATIVE)); + if (*op_dtype == NULL) { + return 0; + } NPY_IT_DBG_PRINT("Iterator: Setting NPY_OP_ITFLAG_CAST " "because of NPY_ITER_NBO\n"); /* Indicate that byte order or alignment needs fixing */ diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c index 564352f1fd3f..edbe5955ce97 100644 --- a/numpy/core/src/multiarray/scalarapi.c +++ b/numpy/core/src/multiarray/scalarapi.c @@ -625,6 +625,9 @@ PyArray_DescrFromScalar(PyObject *sc) } if (PyDataType_ISUNSIZED(descr)) { PyArray_DESCR_REPLACE(descr); + if (descr == NULL) { + return NULL; + } type_num = descr->type_num; if (type_num == NPY_STRING) { descr->elsize = PyBytes_GET_SIZE(sc); diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index 013526ff0c3e..2249fa22bc5a 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -3213,12 +3213,16 @@ void_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } ((PyVoidScalarObject *)ret)->obval = destptr; Py_SET_SIZE((PyVoidScalarObject *)ret, (int) memu); - ((PyVoidScalarObject *)ret)->descr = - PyArray_DescrNewFromType(NPY_VOID); - ((PyVoidScalarObject *)ret)->descr->elsize = (int) memu; ((PyVoidScalarObject *)ret)->flags = NPY_ARRAY_BEHAVED | NPY_ARRAY_OWNDATA; ((PyVoidScalarObject *)ret)->base = NULL; + ((PyVoidScalarObject *)ret)->descr = + PyArray_DescrNewFromType(NPY_VOID); + if (((PyVoidScalarObject *)ret)->descr == NULL) { + Py_DECREF(ret); + return NULL; + } + ((PyVoidScalarObject *)ret)->descr->elsize = (int) memu; return ret; } From f30858a9b15b5871f7a0cd92305f01e05cff0edd Mon Sep 17 00:00:00 2001 From: "Andrew J. Hesford" Date: Tue, 1 Feb 2022 10:34:26 -0500 Subject: [PATCH 27/30] MAINT: be more tolerant of setuptools>=60 NumPy may fail to build with the default vendored distutils in setuptools>=60. Rather than panic and die when new setuptools is found, let's check (or set, if possible) the SETUPTOOLS_USE_DISTUTILS environment variable that restores "proper" setuptools behavior. --- setup.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 06170df51ac4..0257fc5ba755 100755 --- a/setup.py +++ b/setup.py @@ -81,9 +81,16 @@ import numpy.distutils.command.sdist import setuptools if int(setuptools.__version__.split('.')[0]) >= 60: - raise RuntimeError( - "Setuptools version is '{}', version < '60.0.0' is required. " - "See pyproject.toml".format(setuptools.__version__)) + # setuptools >= 60 switches to vendored distutils by default; this + # may break the numpy build, so make sure the stdlib version is used + try: + setuptools_use_distutils = os.environ['SETUPTOOLS_USE_DISTUTILS'] + except KeyError: + os.environ['SETUPTOOLS_USE_DISTUTILS'] = "stdlib" + else: + if setuptools_use_distutils != "stdlib": + raise RuntimeError("setuptools versions >= '60.0.0' require " + "SETUPTOOLS_USE_DISTUTILS=stdlib in the environment") # Initialize cmdclass from versioneer from numpy.distutils.core import numpy_cmdclass From fdca17ca1afc74b17097eb58405a0e22bf3e6036 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Wed, 2 Feb 2022 16:45:33 -0700 Subject: [PATCH 28/30] BUG: Fix misplaced return. Backport of #20980. This lead to crashes when casting failed with an error already set. Internally to NumPy, this is exceedingly rare (maybe impossible aside from catastrophic failures, such as out-of-memory). --- numpy/core/src/multiarray/dtype_transfer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c index 8fb44c4f6c5b..78704f6eda0a 100644 --- a/numpy/core/src/multiarray/dtype_transfer.c +++ b/numpy/core/src/multiarray/dtype_transfer.c @@ -3021,9 +3021,9 @@ init_cast_info(NPY_cast_info *cast_info, NPY_CASTING *casting, if (!PyErr_Occurred()) { PyErr_Format(PyExc_TypeError, "Cannot cast array data from %R to %R.", src_dtype, dst_dtype); - Py_DECREF(meth); - return -1; } + Py_DECREF(meth); + return -1; } assert(PyArray_DescrCheck(cast_info->descriptors[0])); assert(PyArray_DescrCheck(cast_info->descriptors[1])); From a8d8408e45f0bfd470a0465e8dd14c1fc2f90f2e Mon Sep 17 00:00:00 2001 From: Sebastian Berg Date: Thu, 3 Feb 2022 11:36:55 -0600 Subject: [PATCH 29/30] MAINT: Further small return value validation fixes --- numpy/core/src/multiarray/buffer.c | 2 +- numpy/core/src/multiarray/ctors.c | 3 +++ numpy/core/src/multiarray/descriptor.c | 7 ++++--- numpy/core/src/multiarray/methods.c | 4 ++++ tools/swig/pyfragments.swg | 4 ++-- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c index d14f87abb843..13d7038d3448 100644 --- a/numpy/core/src/multiarray/buffer.c +++ b/numpy/core/src/multiarray/buffer.c @@ -1057,7 +1057,7 @@ _descriptor_from_pep3118_format_fast(char const *s, PyObject **result) else { *result = (PyObject*)PyArray_DescrNewByteorder(descr, byte_order); Py_DECREF(descr); - if (result == NULL) { + if (*result == NULL) { return 0; } } diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 2535569a68f6..4464d7ead51d 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -1881,6 +1881,9 @@ PyArray_CheckFromAny(PyObject *op, PyArray_Descr *descr, int min_depth, if (!descr && PyArray_Check(op) && PyArray_ISBYTESWAPPED((PyArrayObject* )op)) { descr = PyArray_DescrNew(PyArray_DESCR((PyArrayObject *)op)); + if (descr == NULL) { + return NULL; + } } else if (descr && !PyArray_ISNBO(descr->byteorder)) { PyArray_DESCR_REPLACE(descr); diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index a5cb6a9fcad0..07abc755fab3 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -597,9 +597,7 @@ _convert_from_array_descr(PyObject *obj, int align) PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID); if (new == NULL) { - Py_XDECREF(fields); - Py_XDECREF(nameslist); - return NULL; + goto fail; } new->fields = fields; new->names = nameslist; @@ -703,6 +701,9 @@ _convert_from_list(PyObject *obj, int align) totalsize += conv->elsize; } PyArray_Descr *new = PyArray_DescrNewFromType(NPY_VOID); + if (new == NULL) { + goto fail; + } new->fields = fields; new->names = nameslist; new->flags = dtypeflags; diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index 20a70a37e862..8fa9bf2ca357 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -1396,6 +1396,10 @@ array_partition(PyArrayObject *self, return NULL; } newd = PyArray_DescrNew(saved); + if (newd == NULL) { + Py_DECREF(new_name); + return NULL; + } Py_DECREF(newd->names); newd->names = new_name; ((PyArrayObject_fields *)self)->descr = newd; diff --git a/tools/swig/pyfragments.swg b/tools/swig/pyfragments.swg index 558633733da3..eac817322242 100644 --- a/tools/swig/pyfragments.swg +++ b/tools/swig/pyfragments.swg @@ -52,7 +52,7 @@ } %#endif if (!PyArray_IsScalar(obj,Integer)) return SWIG_TypeError; - PyArray_Descr * longDescr = PyArray_DescrNewFromType(NPY_LONG); + PyArray_Descr * longDescr = PyArray_DescrFromType(NPY_LONG); PyArray_CastScalarToCtype(obj, (void*)val, longDescr); Py_DECREF(longDescr); return SWIG_OK; @@ -102,7 +102,7 @@ } %#endif if (!PyArray_IsScalar(obj,Integer)) return SWIG_TypeError; - PyArray_Descr * ulongDescr = PyArray_DescrNewFromType(NPY_ULONG); + PyArray_Descr * ulongDescr = PyArray_DescrFromType(NPY_ULONG); PyArray_CastScalarToCtype(obj, (void*)val, ulongDescr); Py_DECREF(ulongDescr); return SWIG_OK; From 2af34ed6fad837c16c8bbe3a37697f12d07320d2 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Thu, 3 Feb 2022 10:30:41 -0700 Subject: [PATCH 30/30] REL: Prepare for NumPy 1.22.2 release. - Update 1.22.2-changelog.rst. - Update 1.22.2-notes.rst --- doc/changelog/1.22.2-changelog.rst | 14 ++++++++++++-- doc/source/release/1.22.2-notes.rst | 18 ++++++++++++++---- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/doc/changelog/1.22.2-changelog.rst b/doc/changelog/1.22.2-changelog.rst index 89ff3e9623ae..067ee2638720 100644 --- a/doc/changelog/1.22.2-changelog.rst +++ b/doc/changelog/1.22.2-changelog.rst @@ -2,7 +2,7 @@ Contributors ============ -A total of 11 people contributed to this release. People with a "+" by their +A total of 14 people contributed to this release. People with a "+" by their names contributed a patch for the first time. * Andrew J. Hesford + @@ -12,15 +12,18 @@ names contributed a patch for the first time. * Hood Chatham * Janus Heide + * Leo Singer +* Matti Picus * Mukulika Pahari * Niyas Sait +* Pearu Peterson * Ralf Gommers +* Sebastian Berg * Serge Guelton Pull requests merged ==================== -A total of 14 pull requests were merged for this release. +A total of 21 pull requests were merged for this release. * `#20842 `__: BLD: Add NPY_DISABLE_SVML env var to opt out of SVML * `#20843 `__: BUG: Fix build of third party extensions with Py_LIMITED_API @@ -36,3 +39,10 @@ A total of 14 pull requests were merged for this release. * `#20936 `__: MAINT, TYP: Added missing where typehints in ``fromnumeric.pyi`` * `#20937 `__: BUG: Fix build_ext interaction with non numpy extensions * `#20938 `__: BUG: Fix missing intrinsics for windows/arm64 target +* `#20945 `__: REL: Prepare for the NumPy 1.22.2 release. +* `#20982 `__: MAINT: f2py: don't generate code that triggers ``-Wsometimes-uninitialized``. +* `#20983 `__: BUG: Fix incorrect return type in reduce without initial value +* `#20984 `__: ENH: review return values for PyArray_DescrNew +* `#20985 `__: MAINT: be more tolerant of setuptools >= 60 +* `#20986 `__: BUG: Fix misplaced return. +* `#20992 `__: MAINT: Further small return value validation fixes diff --git a/doc/source/release/1.22.2-notes.rst b/doc/source/release/1.22.2-notes.rst index 913d4fec1f79..974560fc7a45 100644 --- a/doc/source/release/1.22.2-notes.rst +++ b/doc/source/release/1.22.2-notes.rst @@ -11,13 +11,14 @@ The NumPy 1.22.2 is maintenance release that fixes bugs discovered after the - Various Annotation fixes/additions. - Numpy wheels for Windows will use the 1.41 tool chain, fixing downstream link problems for projects using NumPy provided libraries on Windows. +- Deal with CVE-2021-41495 complaint. The Python versions supported for this release are 3.8-3.10. Contributors ============ -A total of 11 people contributed to this release. People with a "+" by their +A total of 14 people contributed to this release. People with a "+" by their names contributed a patch for the first time. * Andrew J. Hesford + @@ -27,15 +28,18 @@ names contributed a patch for the first time. * Hood Chatham * Janus Heide + * Leo Singer +* Matti Picus * Mukulika Pahari * Niyas Sait +* Pearu Peterson * Ralf Gommers +* Sebastian Berg * Serge Guelton Pull requests merged ==================== -A total of 14 pull requests were merged for this release. +A total of 21 pull requests were merged for this release. * `#20842 `__: BLD: Add NPY_DISABLE_SVML env var to opt out of SVML * `#20843 `__: BUG: Fix build of third party extensions with Py_LIMITED_API @@ -48,7 +52,13 @@ A total of 14 pull requests were merged for this release. * `#20910 `__: BUG: distutils: fix building mixed C/Fortran extensions * `#20912 `__: DOC,TST: Fix Pandas code example as per new release * `#20935 `__: TYP, MAINT: Add annotations for ``flatiter.__setitem__`` -* `#20936 `__: MAINT, TYP: Added missing where type hints in ``fromnumeric.pyi`` +* `#20936 `__: MAINT, TYP: Added missing where typehints in ``fromnumeric.pyi`` * `#20937 `__: BUG: Fix build_ext interaction with non numpy extensions * `#20938 `__: BUG: Fix missing intrinsics for windows/arm64 target - +* `#20945 `__: REL: Prepare for the NumPy 1.22.2 release. +* `#20982 `__: MAINT: f2py: don't generate code that triggers ``-Wsometimes-uninitialized``. +* `#20983 `__: BUG: Fix incorrect return type in reduce without initial value +* `#20984 `__: ENH: review return values for PyArray_DescrNew +* `#20985 `__: MAINT: be more tolerant of setuptools >= 60 +* `#20986 `__: BUG: Fix misplaced return. +* `#20992 `__: MAINT: Further small return value validation fixes