Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0edc7a0

Browse files
author
Michael W. Hudson
committed
Fix:
[ 1229429 ] missing Py_DECREF in PyObject_CallMethod Add a test in test_enumerate, which is a bit random, but suffices (reversed_new calls PyObject_CallMethod under some circumstances).
1 parent 208eec2 commit 0edc7a0

3 files changed

Lines changed: 36 additions & 8 deletions

File tree

Lib/test/test_enumerate.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import unittest
2+
import sys
23

34
from test import test_support
45

@@ -175,6 +176,25 @@ def test_args(self):
175176
self.assertRaises(TypeError, reversed)
176177
self.assertRaises(TypeError, reversed, [], 'extra')
177178

179+
def test_bug1229429(self):
180+
# this bug was never in reversed, it was in
181+
# PyObject_CallMethod, and reversed_new calls that sometimes.
182+
if not hasattr(sys, "getrefcount"):
183+
return
184+
def f():
185+
pass
186+
r = f.__reversed__ = object()
187+
rc = sys.getrefcount(r)
188+
for i in range(10):
189+
try:
190+
reversed(f)
191+
except TypeError:
192+
pass
193+
else:
194+
self.fail("non-callable __reversed__ didn't raise!")
195+
self.assertEqual(rc, sys.getrefcount(r))
196+
197+
178198
def test_main(verbose=None):
179199
testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
180200
TestReversed)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
1212
Core and builtins
1313
-----------------
1414

15+
- SF bug #1229429: PyObject_CallMethod failed to decrement some
16+
reference counts in some error exit cases.
17+
1518
- SF bug #1185883: Python's small-object memory allocator took over
1619
a block managed by the platform C library whenever a realloc specified
1720
a small new size. However, there's no portable way to know then how

Objects/abstract.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,9 @@ PyObject *
17971797
PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
17981798
{
17991799
va_list va;
1800-
PyObject *args, *func = 0, *retval;
1800+
PyObject *args = NULL;
1801+
PyObject *func = NULL;
1802+
PyObject *retval = NULL;
18011803

18021804
if (o == NULL || name == NULL)
18031805
return null_error();
@@ -1808,8 +1810,10 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
18081810
return 0;
18091811
}
18101812

1811-
if (!PyCallable_Check(func))
1812-
return type_error("call of non-callable attribute");
1813+
if (!PyCallable_Check(func)) {
1814+
type_error("call of non-callable attribute");
1815+
goto exit;
1816+
}
18131817

18141818
if (format && *format) {
18151819
va_start(va, format);
@@ -1820,23 +1824,24 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
18201824
args = PyTuple_New(0);
18211825

18221826
if (!args)
1823-
return NULL;
1827+
goto exit;
18241828

18251829
if (!PyTuple_Check(args)) {
18261830
PyObject *a;
18271831

18281832
a = PyTuple_New(1);
18291833
if (a == NULL)
1830-
return NULL;
1834+
goto exit;
18311835
if (PyTuple_SetItem(a, 0, args) < 0)
1832-
return NULL;
1836+
goto exit;
18331837
args = a;
18341838
}
18351839

18361840
retval = PyObject_Call(func, args, NULL);
18371841

1838-
Py_DECREF(args);
1839-
Py_DECREF(func);
1842+
exit:
1843+
Py_XDECREF(args);
1844+
Py_XDECREF(func);
18401845

18411846
return retval;
18421847
}

0 commit comments

Comments
 (0)