summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2013-10-24 02:22:48 +0200
committerSebastian Berg <sebastian@sipsolutions.net>2013-10-24 02:36:01 +0200
commit6e5f0c1231af4958acfa8aa4cf3dfea404acbe9c (patch)
treedfeb77e6ab1931d4701ed75d55172fff0c90190b /numpy
parent77ecefbbae4892f45ffed0119ca3dab28a4d1f65 (diff)
downloadnumpy-6e5f0c1231af4958acfa8aa4cf3dfea404acbe9c.tar.gz
MAINT|BUG: Some small refcounting fixes
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/nditer_constr.c37
-rw-r--r--numpy/core/src/multiarray/number.c5
-rw-r--r--numpy/core/src/umath/test_rational.c.src3
-rw-r--r--numpy/core/tests/test_regression.py10
4 files changed, 32 insertions, 23 deletions
diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c
index 1b2708619..a12457a1e 100644
--- a/numpy/core/src/multiarray/nditer_constr.c
+++ b/numpy/core/src/multiarray/nditer_constr.c
@@ -1161,11 +1161,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
/* Check the readonly/writeonly flags, and fill in op_itflags */
if (!npyiter_check_per_op_flags(op_flags[iop], &op_itflags[iop])) {
- for (i = 0; i <= iop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
- return 0;
+ goto fail_iop;
}
/* Extract the operand which is for masked iteration */
@@ -1174,11 +1170,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
PyErr_SetString(PyExc_ValueError,
"Only one iterator operand may receive an "
"ARRAYMASK flag");
- for (i = 0; i <= iop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
- return 0;
+ goto fail_iop;
}
maskop = iop;
@@ -1199,11 +1191,7 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
&op_dtype[iop],
flags,
op_flags[iop], &op_itflags[iop])) {
- for (i = 0; i <= iop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
- return 0;
+ goto fail_iop;
}
}
@@ -1217,13 +1205,9 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
}
}
if (all_null) {
- for (i = 0; i < nop; ++i) {
- Py_XDECREF(op[i]);
- Py_XDECREF(op_dtype[i]);
- }
PyErr_SetString(PyExc_ValueError,
"At least one iterator operand must be non-NULL");
- return 0;
+ goto fail_nop;
}
}
@@ -1232,17 +1216,26 @@ npyiter_prepare_operands(int nop, PyArrayObject **op_in,
"An iterator operand was flagged as WRITEMASKED, "
"but no ARRAYMASK operand was given to supply "
"the mask");
- return 0;
+ goto fail_nop;
}
else if (!any_writemasked_ops && maskop >= 0) {
PyErr_SetString(PyExc_ValueError,
"An iterator operand was flagged as the ARRAYMASK, "
"but no WRITEMASKED operands were given to use "
"the mask");
- return 0;
+ goto fail_nop;
}
return 1;
+
+ fail_nop:
+ iop = nop;
+ fail_iop:
+ for (i = 0; i < iop; ++i) {
+ Py_XDECREF(op[i]);
+ Py_XDECREF(op_dtype[i]);
+ }
+ return 0;
}
static const char *
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index 2ad65bbe8..c8a7c9c7e 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -771,6 +771,7 @@ array_int(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
@@ -812,6 +813,7 @@ array_float(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_float(pv);
@@ -849,6 +851,7 @@ array_long(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_long(pv);
@@ -884,6 +887,7 @@ array_oct(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_oct(pv);
@@ -919,6 +923,7 @@ array_hex(PyArrayObject *v)
PyDataType_REFCHK(PyArray_DESCR((PyArrayObject *)pv))) {
PyErr_SetString(PyExc_TypeError,
"object array may be self-referencing");
+ Py_DECREF(pv);
return NULL;
}
pv2 = Py_TYPE(pv)->tp_as_number->nb_hex(pv);
diff --git a/numpy/core/src/umath/test_rational.c.src b/numpy/core/src/umath/test_rational.c.src
index 1650dd1d3..d8f90f9e5 100644
--- a/numpy/core/src/umath/test_rational.c.src
+++ b/numpy/core/src/umath/test_rational.c.src
@@ -1242,12 +1242,15 @@ PyMODINIT_FUNC inittest_rational(void) {
PyErr_Format(PyExc_AssertionError, \
"ufunc %s takes %d arguments, our loop takes %ld", \
#name, ufunc->nargs, sizeof(_types)/sizeof(int)); \
+ Py_DECREF(ufunc); \
goto fail; \
} \
if (PyUFunc_RegisterLoopForType((PyUFuncObject*)ufunc, npy_rational, \
rational_ufunc_##name, _types, 0) < 0) { \
+ Py_DECREF(ufunc); \
goto fail; \
} \
+ Py_DECREF(ufunc); \
}
#define REGISTER_UFUNC_BINARY_RATIONAL(name) \
REGISTER_UFUNC(name, {npy_rational, npy_rational, npy_rational})
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 02cf1b8df..b98746e1b 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -1654,6 +1654,14 @@ class TestRegression(TestCase):
assert_raises(TypeError, oct, a)
assert_raises(TypeError, hex, a)
+ # Test the same for a circular reference.
+ b = np.array(a, dtype=object)
+ a[()] = b
+ assert_raises(TypeError, int, a)
+ # Numpy has no tp_traverse currently, so circular references
+ # cannot be detected. So resolve it:
+ a[()] = 0
+
# This was causing a to become like the above
a = np.array(0, dtype=object)
a[...] += 1
@@ -1661,7 +1669,7 @@ class TestRegression(TestCase):
def test_object_array_self_copy(self):
# An object array being copied into itself DECREF'ed before INCREF'ing
- # causing segmentation faults (gh-3787)
+ # causing segmentation faults (gh-3787)
a = np.array(object(), dtype=object)
np.copyto(a, a)
assert_equal(sys.getrefcount(a[()]), 2)