diff options
author | Sebastian Berg <sebastian@sipsolutions.net> | 2021-03-23 14:11:52 -0500 |
---|---|---|
committer | Sebastian Berg <sebastian@sipsolutions.net> | 2021-03-23 16:22:17 -0500 |
commit | bbc07e76c1ac0395e48500dd943dd89231e5b35b (patch) | |
tree | 20b7e860eefb2238958857dec7f6b32727638c5b | |
parent | 8ada030bd5b37c764ae83449b46c93d743455b40 (diff) | |
download | numpy-bbc07e76c1ac0395e48500dd943dd89231e5b35b.tar.gz |
BUG: Fix small issues found with pytest-leaks
None of these are particularly worrying as they either usually only
leak reference (and not memory) or appear in rare or almost impossible
error-paths, or are limited to the tests.
Unfortunately, this PR will not apply to 1.20.x, due to small changes
in the overrides.
-rw-r--r-- | numpy/core/src/multiarray/arrayfunction_override.c | 26 | ||||
-rw-r--r-- | numpy/core/src/multiarray/convert_datatype.c | 3 | ||||
-rw-r--r-- | numpy/core/src/umath/_umath_tests.c.src | 1 | ||||
-rw-r--r-- | numpy/core/src/umath/_umath_tests.dispatch.c | 1 | ||||
-rw-r--r-- | numpy/core/src/umath/ufunc_object.c | 4 | ||||
-rw-r--r-- | numpy/core/tests/test_overrides.py | 26 |
6 files changed, 37 insertions, 24 deletions
diff --git a/numpy/core/src/multiarray/arrayfunction_override.c b/numpy/core/src/multiarray/arrayfunction_override.c index 31415e4f2..463a2d4d8 100644 --- a/numpy/core/src/multiarray/arrayfunction_override.c +++ b/numpy/core/src/multiarray/arrayfunction_override.c @@ -341,18 +341,23 @@ array_implement_array_function( return NULL; } - /* Remove `like=` kwarg, which is NumPy-exclusive and thus not present + /* + * Remove `like=` kwarg, which is NumPy-exclusive and thus not present * in downstream libraries. If `like=` is specified but doesn't * implement `__array_function__`, raise a `TypeError`. */ if (kwargs != NULL && PyDict_Contains(kwargs, npy_ma_str_like)) { PyObject *like_arg = PyDict_GetItem(kwargs, npy_ma_str_like); - if (like_arg && !get_array_function(like_arg)) { - return PyErr_Format(PyExc_TypeError, - "The `like` argument must be an array-like that implements " - "the `__array_function__` protocol."); + if (like_arg != NULL) { + PyObject *tmp_has_override = get_array_function(like_arg); + if (tmp_has_override == NULL) { + return PyErr_Format(PyExc_TypeError, + "The `like` argument must be an array-like that " + "implements the `__array_function__` protocol."); + } + Py_DECREF(tmp_has_override); + PyDict_DelItem(kwargs, npy_ma_str_like); } - PyDict_DelItem(kwargs, npy_ma_str_like); } PyObject *res = array_implement_array_function_internal( @@ -382,11 +387,14 @@ array_implement_c_array_function_creation( PyObject *public_api = NULL; PyObject *result = NULL; - if (!get_array_function(like)) { + /* If `like` doesn't implement `__array_function__`, raise a `TypeError` */ + PyObject *tmp_has_override = get_array_function(like); + if (tmp_has_override == NULL) { return PyErr_Format(PyExc_TypeError, - "The `like` argument must be an array-like that implements " - "the `__array_function__` protocol."); + "The `like` argument must be an array-like that " + "implements the `__array_function__` protocol."); } + Py_DECREF(tmp_has_override); if (fast_args != NULL) { /* diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index d3c969034..18179f253 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -916,8 +916,7 @@ PyArray_FindConcatenationDescriptor( "The dtype `%R` is not a valid dtype for concatenation " "since it is a subarray dtype (the subarray dimensions " "would be added as array dimensions).", result); - Py_DECREF(result); - return NULL; + Py_SETREF(result, NULL); } goto finish; } diff --git a/numpy/core/src/umath/_umath_tests.c.src b/numpy/core/src/umath/_umath_tests.c.src index 4e250e43b..7cc74a4f3 100644 --- a/numpy/core/src/umath/_umath_tests.c.src +++ b/numpy/core/src/umath/_umath_tests.c.src @@ -621,6 +621,7 @@ UMath_Tests_test_dispatch(PyObject *NPY_UNUSED(dummy), PyObject *NPY_UNUSED(dumm goto err; } NPY_CPU_DISPATCH_CALL_ALL(_umath_tests_dispatch_attach, (item)); + Py_SETREF(item, NULL); if (PyErr_Occurred()) { goto err; } diff --git a/numpy/core/src/umath/_umath_tests.dispatch.c b/numpy/core/src/umath/_umath_tests.dispatch.c index d86a54411..85f365010 100644 --- a/numpy/core/src/umath/_umath_tests.dispatch.c +++ b/numpy/core/src/umath/_umath_tests.dispatch.c @@ -29,5 +29,6 @@ void NPY_CPU_DISPATCH_CURFX(_umath_tests_dispatch_attach)(PyObject *list) PyObject *item = PyUnicode_FromString(NPY_TOSTRING(NPY_CPU_DISPATCH_CURFX(func))); if (item) { PyList_Append(list, item); + Py_DECREF(item); } } diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c index 653e0b5be..d70d15c50 100644 --- a/numpy/core/src/umath/ufunc_object.c +++ b/numpy/core/src/umath/ufunc_object.c @@ -5495,6 +5495,7 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds) /* DEPRECATED 2020-05-13, NumPy 1.20 */ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, matrix_deprecation_msg, ufunc->name, "first") < 0) { + Py_DECREF(tmp); return NULL; } ap1 = (PyArrayObject *) PyArray_FromObject(tmp, NPY_NOTYPE, 0, 0); @@ -5514,6 +5515,7 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds) /* DEPRECATED 2020-05-13, NumPy 1.20 */ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, matrix_deprecation_msg, ufunc->name, "second") < 0) { + Py_DECREF(tmp); Py_DECREF(ap1); return NULL; } @@ -5538,7 +5540,7 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds) "maximum supported dimension for an ndarray is %d, but " "`%s.outer()` result would have %d.", NPY_MAXDIMS, ufunc->name, newdims.len); - return NPY_FAIL; + goto fail; } if (newdims.ptr == NULL) { goto fail; diff --git a/numpy/core/tests/test_overrides.py b/numpy/core/tests/test_overrides.py index 0809e1e92..9216a3f5f 100644 --- a/numpy/core/tests/test_overrides.py +++ b/numpy/core/tests/test_overrides.py @@ -1,5 +1,6 @@ import inspect import sys +import os import tempfile from io import StringIO from unittest import mock @@ -558,18 +559,19 @@ class TestArrayLike: data = np.random.random(5) - fname = tempfile.mkstemp()[1] - data.tofile(fname) - - array_like = np.fromfile(fname, like=ref) - if numpy_ref is True: - assert type(array_like) is np.ndarray - np_res = np.fromfile(fname, like=ref) - assert_equal(np_res, data) - assert_equal(array_like, np_res) - else: - assert type(array_like) is self.MyArray - assert array_like.function is self.MyArray.fromfile + with tempfile.TemporaryDirectory() as tmpdir: + fname = os.path.join(tmpdir, "testfile") + data.tofile(fname) + + array_like = np.fromfile(fname, like=ref) + if numpy_ref is True: + assert type(array_like) is np.ndarray + np_res = np.fromfile(fname, like=ref) + assert_equal(np_res, data) + assert_equal(array_like, np_res) + else: + assert type(array_like) is self.MyArray + assert array_like.function is self.MyArray.fromfile @requires_array_function def test_exception_handling(self): |