[Python-checkins] r73392 - in python/branches/py3k: Lib/test/test_range.py Misc/NEWS Objects/rangeobject.c

raymond.hettinger python-checkins at python.org
Fri Jun 12 20:40:16 CEST 2009


Author: raymond.hettinger
Date: Fri Jun 12 20:40:16 2009
New Revision: 73392

Log:
Fix SystemError and a wasps nest of ref counting issues.

Modified:
   python/branches/py3k/Lib/test/test_range.py
   python/branches/py3k/Misc/NEWS
   python/branches/py3k/Objects/rangeobject.c

Modified: python/branches/py3k/Lib/test/test_range.py
==============================================================================
--- python/branches/py3k/Lib/test/test_range.py	(original)
+++ python/branches/py3k/Lib/test/test_range.py	Fri Jun 12 20:40:16 2009
@@ -71,6 +71,13 @@
                 self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))),
                                   list(r))
 
+    def test_odd_bug(self):
+        # This used to raise a "SystemError: NULL result without error"
+        # because the range validation step was eating the exception
+        # before NULL was returned.
+        with self.assertRaises(TypeError):
+            range([], 1, -1)
+
 def test_main():
     test.support.run_unittest(RangeTest)
 

Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Fri Jun 12 20:40:16 2009
@@ -12,6 +12,8 @@
 Core and Builtins
 -----------------
 
+- Fixed SystemError triggered by "range([], 1, -1)".
+
 - Issue #5924: On Windows, a large PYTHONPATH environment variable
   (more than 255 characters) would be completely ignored.
 

Modified: python/branches/py3k/Objects/rangeobject.c
==============================================================================
--- python/branches/py3k/Objects/rangeobject.c	(original)
+++ python/branches/py3k/Objects/rangeobject.c	Fri Jun 12 20:40:16 2009
@@ -59,26 +59,42 @@
 
     if (PyTuple_Size(args) <= 1) {
         if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
-            goto Fail;
+            return NULL;
         stop = PyNumber_Index(stop);
         if (!stop)
-            goto Fail;
+            return NULL;
         start = PyLong_FromLong(0);
+        if (!start) {
+            Py_DECREF(stop);
+            return NULL;
+        }
         step = PyLong_FromLong(1);
-        if (!start || !step)
-            goto Fail;
+        if (!step) {
+            Py_DECREF(stop);
+            Py_DECREF(start);
+            return NULL;
+        }
     }
     else {
         if (!PyArg_UnpackTuple(args, "range", 2, 3,
                                &start, &stop, &step))
-            goto Fail;
+            return NULL;
 
         /* Convert borrowed refs to owned refs */
         start = PyNumber_Index(start);
+        if (!start)
+            return NULL;
         stop = PyNumber_Index(stop);
-        step = validate_step(step);
-        if (!start || !stop || !step)
-            goto Fail;
+        if (!stop) {
+            Py_DECREF(start);
+            return NULL;
+        }
+        step = validate_step(step);    /* Caution, this can clear exceptions */
+        if (!step) {
+            Py_DECREF(start);
+            Py_DECREF(stop);
+            return NULL;
+        }
     }
 
     obj = PyObject_New(rangeobject, &PyRange_Type);


More information about the Python-checkins mailing list