]> granicus.if.org Git - python/commitdiff
Fix:
authorMichael W. Hudson <mwh@python.net>
Tue, 12 Jul 2005 10:21:19 +0000 (10:21 +0000)
committerMichael W. Hudson <mwh@python.net>
Tue, 12 Jul 2005 10:21:19 +0000 (10:21 +0000)
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).

Lib/test/test_enumerate.py
Misc/NEWS
Objects/abstract.c

index 0ed2b4c5c1f761a4651a8fe7c72309fb71df29fc..0a88e8d7d418970533908cbf1d97d509bc7e7f14 100644 (file)
@@ -1,4 +1,5 @@
 import unittest
+import sys
 
 from test import test_support
 
@@ -175,6 +176,25 @@ class TestReversed(unittest.TestCase):
         self.assertRaises(TypeError, reversed)
         self.assertRaises(TypeError, reversed, [], 'extra')
 
+    def test_bug1229429(self):
+        # this bug was never in reversed, it was in
+        # PyObject_CallMethod, and reversed_new calls that sometimes.
+        if not hasattr(sys, "getrefcount"):
+            return
+        def f():
+            pass
+        r = f.__reversed__ = object()
+        rc = sys.getrefcount(r)
+        for i in range(10):
+            try:
+                reversed(f)
+            except TypeError:
+                pass
+            else:
+                self.fail("non-callable __reversed__ didn't raise!")
+        self.assertEqual(rc, sys.getrefcount(r))
+            
+
 def test_main(verbose=None):
     testclasses = (EnumerateTestCase, SubclassTestCase, TestEmpty, TestBig,
                    TestReversed)
index 4f41ab1597aaae102e424e23332b7c1e33200ae2..13c7761c0af1c39404a1ac881c1b0b263546363c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5 alpha 1?
 Core and builtins
 -----------------
 
+- SF bug #1229429: PyObject_CallMethod failed to decrement some
+  reference counts in some error exit cases.
+
 - SF bug #1185883:  Python's small-object memory allocator took over
   a block managed by the platform C library whenever a realloc specified
   a small new size.  However, there's no portable way to know then how
index d28006a97d30911dd0afcbe965b8b4c6c7334a5f..cade2aa19d3c88706a2470eecd5b66212a75f512 100644 (file)
@@ -1797,7 +1797,9 @@ PyObject *
 PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
 {
        va_list va;
-       PyObject *args, *func = 0, *retval;
+       PyObject *args = NULL;
+       PyObject *func = NULL;
+       PyObject *retval = NULL;
 
        if (o == NULL || name == NULL)
                return null_error();
@@ -1808,8 +1810,10 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
                return 0;
        }
 
-       if (!PyCallable_Check(func))
-               return type_error("call of non-callable attribute");
+       if (!PyCallable_Check(func)) {
+               type_error("call of non-callable attribute"); 
+               goto exit;
+       }
 
        if (format && *format) {
                va_start(va, format);
@@ -1820,23 +1824,24 @@ PyObject_CallMethod(PyObject *o, char *name, char *format, ...)
                args = PyTuple_New(0);
 
        if (!args)
-               return NULL;
+               goto exit;
 
        if (!PyTuple_Check(args)) {
                PyObject *a;
 
                a = PyTuple_New(1);
                if (a == NULL)
-                       return NULL;
+                       goto exit;
                if (PyTuple_SetItem(a, 0, args) < 0)
-                       return NULL;
+                       goto exit;
                args = a;
        }
 
        retval = PyObject_Call(func, args, NULL);
 
-       Py_DECREF(args);
-       Py_DECREF(func);
+  exit:
+       Py_XDECREF(args);
+       Py_XDECREF(func);
 
        return retval;
 }