[Python-3000-checkins] r59585 - in python/branches/py3k: Include/longobject.h Objects/longobject.c Objects/rangeobject.c

martin.v.loewis python-3000-checkins at python.org
Thu Dec 20 23:57:24 CET 2007


Author: martin.v.loewis
Date: Thu Dec 20 23:57:23 2007
New Revision: 59585

Modified:
   python/branches/py3k/Include/longobject.h
   python/branches/py3k/Objects/longobject.c
   python/branches/py3k/Objects/rangeobject.c
Log:
Drop _PyLong_FitsInLong. Fixes #1666.


Modified: python/branches/py3k/Include/longobject.h
==============================================================================
--- python/branches/py3k/Include/longobject.h	(original)
+++ python/branches/py3k/Include/longobject.h	Thu Dec 20 23:57:23 2007
@@ -50,7 +50,6 @@
    be multiplied by SHIFT!  There may not be enough room in an int to store
    e*SHIFT directly. */
 PyAPI_FUNC(double) _PyLong_AsScaledDouble(PyObject *vv, int *e);
-  PyAPI_FUNC(int) _PyLong_FitsInLong(PyObject* vv);
 
 PyAPI_FUNC(double) PyLong_AsDouble(PyObject *);
 PyAPI_FUNC(PyObject *) PyLong_FromVoidPtr(void *);

Modified: python/branches/py3k/Objects/longobject.c
==============================================================================
--- python/branches/py3k/Objects/longobject.c	(original)
+++ python/branches/py3k/Objects/longobject.c	Thu Dec 20 23:57:23 2007
@@ -392,19 +392,6 @@
 	return result;
 }
 
-int
-_PyLong_FitsInLong(PyObject *vv)
-{
-	int size;
-	if (!PyLong_CheckExact(vv)) {
-		PyErr_BadInternalCall();
-		return 0;
-	}
-	/* conservative estimate */
-	size = Py_SIZE(vv);
-	return -2 <= size && size <= 2;
-}
-
 /* Get a Py_ssize_t from a long int object.
    Returns -1 and sets an error condition if overflow occurs. */
 

Modified: python/branches/py3k/Objects/rangeobject.c
==============================================================================
--- python/branches/py3k/Objects/rangeobject.c	(original)
+++ python/branches/py3k/Objects/rangeobject.c	Thu Dec 20 23:57:23 2007
@@ -558,14 +558,23 @@
     rangeobject *r = (rangeobject *)seq;
     longrangeiterobject *it;
     PyObject *tmp, *len;
+    long lstart, lstop, lstep;
 
     assert(PyRange_Check(seq));
-    if (_PyLong_FitsInLong(r->start) &&
-        _PyLong_FitsInLong(r->stop) &&
-        _PyLong_FitsInLong(r->step))
-        return int_range_iter(PyLong_AsLong(r->start),
-                      PyLong_AsLong(r->stop),
-                      PyLong_AsLong(r->step));
+
+    /* If all three fields convert to long, use the int version */
+    lstart = PyLong_AsLong(r->start);
+    if (lstart != -1 || !PyErr_Occurred()) {
+	lstop = PyLong_AsLong(r->stop);
+	if (lstop != -1 || !PyErr_Occurred()) {
+	    lstep = PyLong_AsLong(r->step);
+	    if (lstep != -1 || !PyErr_Occurred())
+		return int_range_iter(lstart, lstop, lstep);
+	}
+    }
+    /* Some conversion failed, so there is an error set. Clear it,
+       and try again with a long range. */
+    PyErr_Clear();
 
     it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
     if (it == NULL)
@@ -605,27 +614,33 @@
     rangeobject *range = (rangeobject*) seq;
     longrangeiterobject *it;
     PyObject *one, *sum, *diff, *len = NULL, *product;
+    long lstart, lstop, lstep;
 
     /* XXX(nnorwitz): do the calc for the new start/stop first,
         then if they fit, call the proper iter()?
     */
     assert(PyRange_Check(seq));
-    if (_PyLong_FitsInLong(range->start) &&
-        _PyLong_FitsInLong(range->stop) &&
-        _PyLong_FitsInLong(range->step)) {
-        long start = PyLong_AsLong(range->start);
-        long step = PyLong_AsLong(range->step);
-        long stop = PyLong_AsLong(range->stop);
-        /* XXX(nnorwitz): need to check for overflow and simplify. */
-        long len = get_len_of_range(start, stop, step);
-        long new_start = start + (len - 1) * step;
-        long new_stop = start;
-        if (step > 0)
-            new_stop -= 1;
-        else
-            new_stop += 1;
-        return int_range_iter(new_start, new_stop, -step);
+
+    /* If all three fields convert to long, use the int version */
+    lstart = PyLong_AsLong(range->start);
+    if (lstart != -1 || !PyErr_Occurred()) {
+	lstop = PyLong_AsLong(range->stop);
+	if (lstop != -1 || !PyErr_Occurred()) {
+	    lstep = PyLong_AsLong(range->step);
+	    if (lstep != -1 || !PyErr_Occurred()) {
+		/* XXX(nnorwitz): need to check for overflow and simplify. */
+		long len = get_len_of_range(lstart, lstop, lstep);
+		long new_start = lstart + (len - 1) * lstep;
+		long new_stop = lstart;
+		if (lstep > 0)
+		    new_stop -= 1;
+		else
+		    new_stop += 1;
+		return int_range_iter(new_start, new_stop, -lstep);
+	    }
+	}
     }
+    PyErr_Clear();
 
     it = PyObject_New(longrangeiterobject, &PyLongRangeIter_Type);
     if (it == NULL)


More information about the Python-3000-checkins mailing list