Fix SystemError and a wasps nest of ref counting issues.

This commit is contained in:
Raymond Hettinger 2009-06-12 18:40:16 +00:00
parent 83eacca7a6
commit 94f5583777
3 changed files with 33 additions and 8 deletions

View File

@ -71,6 +71,13 @@ class RangeTest(unittest.TestCase):
self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))), self.assertEquals(list(pickle.loads(pickle.dumps(r, proto))),
list(r)) 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(): def test_main():
test.support.run_unittest(RangeTest) test.support.run_unittest(RangeTest)

View File

@ -12,6 +12,8 @@ What's New in Python 3.1 Release Candidate 2?
Core and Builtins Core and Builtins
----------------- -----------------
- Fixed SystemError triggered by "range([], 1, -1)".
- Issue #5924: On Windows, a large PYTHONPATH environment variable - Issue #5924: On Windows, a large PYTHONPATH environment variable
(more than 255 characters) would be completely ignored. (more than 255 characters) would be completely ignored.

View File

@ -59,26 +59,42 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (PyTuple_Size(args) <= 1) { if (PyTuple_Size(args) <= 1) {
if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop)) if (!PyArg_UnpackTuple(args, "range", 1, 1, &stop))
goto Fail; return NULL;
stop = PyNumber_Index(stop); stop = PyNumber_Index(stop);
if (!stop) if (!stop)
goto Fail; return NULL;
start = PyLong_FromLong(0); start = PyLong_FromLong(0);
if (!start) {
Py_DECREF(stop);
return NULL;
}
step = PyLong_FromLong(1); step = PyLong_FromLong(1);
if (!start || !step) if (!step) {
goto Fail; Py_DECREF(stop);
Py_DECREF(start);
return NULL;
}
} }
else { else {
if (!PyArg_UnpackTuple(args, "range", 2, 3, if (!PyArg_UnpackTuple(args, "range", 2, 3,
&start, &stop, &step)) &start, &stop, &step))
goto Fail; return NULL;
/* Convert borrowed refs to owned refs */ /* Convert borrowed refs to owned refs */
start = PyNumber_Index(start); start = PyNumber_Index(start);
if (!start)
return NULL;
stop = PyNumber_Index(stop); stop = PyNumber_Index(stop);
step = validate_step(step); if (!stop) {
if (!start || !stop || !step) Py_DECREF(start);
goto Fail; 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); obj = PyObject_New(rangeobject, &PyRange_Type);