[Python-checkins] r51238 - in python/trunk: Lib/test/test_index.py Misc/NEWS Objects/classobject.c Objects/typeobject.c
neal.norwitz
python-checkins at python.org
Sat Aug 12 20:44:07 CEST 2006
Author: neal.norwitz
Date: Sat Aug 12 20:44:06 2006
New Revision: 51238
Modified:
python/trunk/Lib/test/test_index.py
python/trunk/Misc/NEWS
python/trunk/Objects/classobject.c
python/trunk/Objects/typeobject.c
Log:
Fix a couple of bugs exposed by the new __index__ code. The 64-bit buildbots
were failing due to inappropriate clipping of numbers larger than 2**31
with new-style classes. (typeobject.c) In reviewing the code for classic
classes, there were 2 problems. Any negative value return could be returned.
Always return -1 if there was an error. Also make the checks similar
with the new-style classes. I believe this is correct for 32 and 64 bit
boxes, including Windows64.
Add a test of classic classes too.
Modified: python/trunk/Lib/test/test_index.py
==============================================================================
--- python/trunk/Lib/test/test_index.py (original)
+++ python/trunk/Lib/test/test_index.py Sat Aug 12 20:44:06 2006
@@ -181,8 +181,8 @@
self.assertEqual(self.pos.__index__(), self.pos)
self.assertEqual(self.neg.__index__(), self.neg)
- def test_getitem(self):
- class GetItem(object):
+ def _getitem_helper(self, base):
+ class GetItem(base):
def __len__(self):
return maxint
def __getitem__(self, key):
@@ -195,6 +195,13 @@
self.assertEqual(x[self.neg:self.pos], (-1, maxint))
self.assertEqual(x[self.neg:self.pos:1].indices(maxint), (0, maxint, 1))
+ def test_getitem(self):
+ self._getitem_helper(object)
+
+ def test_getitem_classic(self):
+ class Empty: pass
+ self._getitem_helper(Empty)
+
def test_sequence_repeat(self):
self.failUnlessRaises(OverflowError, lambda: "a" * self.pos)
self.failUnlessRaises(OverflowError, lambda: "a" * self.neg)
Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS (original)
+++ python/trunk/Misc/NEWS Sat Aug 12 20:44:06 2006
@@ -12,6 +12,12 @@
Core and builtins
-----------------
+- Fix bug related to __len__ functions using values > 2**32 on 64-bit machines
+ with new-style classes.
+
+- Fix bug related to __len__ functions returning negative values with
+ classic classes.
+
- Patch #1538606, Fix __index__() clipping. There were some problems
discovered with the API and how integers that didn't fit into Py_ssize_t
were handled. This patch attempts to provide enough alternatives
Modified: python/trunk/Objects/classobject.c
==============================================================================
--- python/trunk/Objects/classobject.c (original)
+++ python/trunk/Objects/classobject.c Sat Aug 12 20:44:06 2006
@@ -974,24 +974,25 @@
if (res == NULL)
return -1;
if (PyInt_Check(res)) {
- Py_ssize_t temp = PyInt_AsSsize_t(res);
- if (temp == -1 && PyErr_Occurred()) {
+ outcome = PyInt_AsSsize_t(res);
+ if (outcome == -1 && PyErr_Occurred()) {
Py_DECREF(res);
return -1;
}
- outcome = (Py_ssize_t)temp;
-#if SIZEOF_SIZE_T < SIZEOF_LONG
+#if SIZEOF_SIZE_T < SIZEOF_INT
/* Overflow check -- range of PyInt is more than C int */
- if (outcome != temp) {
+ if (outcome != (int)outcome) {
PyErr_SetString(PyExc_OverflowError,
"__len__() should return 0 <= outcome < 2**31");
outcome = -1;
}
else
#endif
- if (outcome < 0)
+ if (outcome < 0) {
PyErr_SetString(PyExc_ValueError,
"__len__() should return >= 0");
+ outcome = -1;
+ }
}
else {
PyErr_SetString(PyExc_TypeError,
Modified: python/trunk/Objects/typeobject.c
==============================================================================
--- python/trunk/Objects/typeobject.c (original)
+++ python/trunk/Objects/typeobject.c Sat Aug 12 20:44:06 2006
@@ -4110,19 +4110,17 @@
{
static PyObject *len_str;
PyObject *res = call_method(self, "__len__", &len_str, "()");
- Py_ssize_t temp;
Py_ssize_t len;
if (res == NULL)
return -1;
- temp = PyInt_AsSsize_t(res);
- len = (int)temp;
+ len = PyInt_AsSsize_t(res);
Py_DECREF(res);
if (len == -1 && PyErr_Occurred())
return -1;
-#if SIZEOF_SIZE_T < SIZEOF_LONG
+#if SIZEOF_SIZE_T < SIZEOF_INT
/* Overflow check -- range of PyInt is more than C ssize_t */
- if (len != temp) {
+ if (len != (int)len) {
PyErr_SetString(PyExc_OverflowError,
"__len__() should return 0 <= outcome < 2**31");
return -1;
More information about the Python-checkins
mailing list