summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2021-03-23 14:11:52 -0500
committerSebastian Berg <sebastian@sipsolutions.net>2021-03-23 16:22:17 -0500
commitbbc07e76c1ac0395e48500dd943dd89231e5b35b (patch)
tree20b7e860eefb2238958857dec7f6b32727638c5b
parent8ada030bd5b37c764ae83449b46c93d743455b40 (diff)
downloadnumpy-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.c26
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c3
-rw-r--r--numpy/core/src/umath/_umath_tests.c.src1
-rw-r--r--numpy/core/src/umath/_umath_tests.dispatch.c1
-rw-r--r--numpy/core/src/umath/ufunc_object.c4
-rw-r--r--numpy/core/tests/test_overrides.py26
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):