mirror of
https://github.com/python/cpython.git
synced 2025-07-19 17:25:54 +00:00
Merged revisions 55007-55179 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r55077 | guido.van.rossum | 2007-05-02 11:54:37 -0700 (Wed, 02 May 2007) | 2 lines Use the new print syntax, at least. ........ r55142 | fred.drake | 2007-05-04 21:27:30 -0700 (Fri, 04 May 2007) | 1 line remove old cruftiness ........ r55143 | fred.drake | 2007-05-04 21:52:16 -0700 (Fri, 04 May 2007) | 1 line make this work with the new Python ........ r55162 | neal.norwitz | 2007-05-06 22:29:18 -0700 (Sun, 06 May 2007) | 1 line Get asdl code gen working with Python 2.3. Should continue to work with 3.0 ........ r55164 | neal.norwitz | 2007-05-07 00:00:38 -0700 (Mon, 07 May 2007) | 1 line Verify checkins to p3yk (sic) branch go to 3000 list. ........ r55166 | neal.norwitz | 2007-05-07 00:12:35 -0700 (Mon, 07 May 2007) | 1 line Fix this test so it runs again by importing warnings_test properly. ........ r55167 | neal.norwitz | 2007-05-07 01:03:22 -0700 (Mon, 07 May 2007) | 8 lines So long xrange. range() now supports values that are outside -sys.maxint to sys.maxint. floats raise a TypeError. This has been sitting for a long time. It probably has some problems and needs cleanup. Objects/rangeobject.c now uses 4-space indents since it is almost completely new. ........ r55171 | guido.van.rossum | 2007-05-07 10:21:26 -0700 (Mon, 07 May 2007) | 4 lines Fix two tests that were previously depending on significant spaces at the end of a line (and before that on Python 2.x print behavior that has no exact equivalent in 3.0). ........
This commit is contained in:
parent
598d98a7e8
commit
805365ee39
150 changed files with 1412 additions and 1320 deletions
|
@ -1593,302 +1593,6 @@ sep: string inserted between values, default a space.\n\
|
|||
end: string appended after the last value, default a newline.");
|
||||
|
||||
|
||||
/* Return number of items in range (lo, hi, step), when arguments are
|
||||
* PyInt or PyLong objects. step > 0 required. Return a value < 0 if
|
||||
* & only if the true value is too large to fit in a signed long.
|
||||
* Arguments MUST return 1 with either PyInt_Check() or
|
||||
* PyLong_Check(). Return -1 when there is an error.
|
||||
*/
|
||||
static long
|
||||
get_len_of_range_longs(PyObject *lo, PyObject *hi, PyObject *step)
|
||||
{
|
||||
/* -------------------------------------------------------------
|
||||
Algorithm is equal to that of get_len_of_range(), but it operates
|
||||
on PyObjects (which are assumed to be PyLong or PyInt objects).
|
||||
---------------------------------------------------------------*/
|
||||
long n;
|
||||
PyObject *diff = NULL;
|
||||
PyObject *one = NULL;
|
||||
PyObject *tmp1 = NULL, *tmp2 = NULL, *tmp3 = NULL;
|
||||
/* holds sub-expression evaluations */
|
||||
|
||||
/* If (lo >= hi), return length of 0 (or error). */
|
||||
n = PyObject_RichCompareBool(lo, hi, Py_LT);
|
||||
if (n <= 0)
|
||||
return n;
|
||||
|
||||
if ((one = PyLong_FromLong(1L)) == NULL)
|
||||
goto Fail;
|
||||
|
||||
if ((tmp1 = PyNumber_Subtract(hi, lo)) == NULL)
|
||||
goto Fail;
|
||||
|
||||
if ((diff = PyNumber_Subtract(tmp1, one)) == NULL)
|
||||
goto Fail;
|
||||
|
||||
if ((tmp2 = PyNumber_FloorDivide(diff, step)) == NULL)
|
||||
goto Fail;
|
||||
|
||||
if ((tmp3 = PyNumber_Add(tmp2, one)) == NULL)
|
||||
goto Fail;
|
||||
|
||||
n = PyLong_AsLong(tmp3);
|
||||
if (PyErr_Occurred()) { /* Check for Overflow */
|
||||
PyErr_Clear();
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
Py_DECREF(tmp3);
|
||||
Py_DECREF(tmp2);
|
||||
Py_DECREF(diff);
|
||||
Py_DECREF(tmp1);
|
||||
Py_DECREF(one);
|
||||
return n;
|
||||
|
||||
Fail:
|
||||
Py_XDECREF(tmp3);
|
||||
Py_XDECREF(tmp2);
|
||||
Py_XDECREF(diff);
|
||||
Py_XDECREF(tmp1);
|
||||
Py_XDECREF(one);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* An extension of builtin_range() that handles the case when PyLong
|
||||
* arguments are given. */
|
||||
static PyObject *
|
||||
handle_range_longs(PyObject *self, PyObject *args)
|
||||
{
|
||||
PyObject *ilow;
|
||||
PyObject *ihigh = NULL;
|
||||
PyObject *istep = NULL;
|
||||
|
||||
PyObject *curnum = NULL;
|
||||
PyObject *v = NULL;
|
||||
long bign;
|
||||
int i, n;
|
||||
int step_pos;
|
||||
|
||||
PyObject *zero = PyLong_FromLong(0);
|
||||
|
||||
if (zero == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!PyArg_UnpackTuple(args, "range", 1, 3, &ilow, &ihigh, &istep)) {
|
||||
Py_DECREF(zero);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Figure out which way we were called, supply defaults, and be
|
||||
* sure to incref everything so that the decrefs at the end
|
||||
* are correct.
|
||||
*/
|
||||
assert(ilow != NULL);
|
||||
if (ihigh == NULL) {
|
||||
/* only 1 arg -- it's the upper limit */
|
||||
ihigh = ilow;
|
||||
ilow = NULL;
|
||||
}
|
||||
assert(ihigh != NULL);
|
||||
Py_INCREF(ihigh);
|
||||
|
||||
/* ihigh correct now; do ilow */
|
||||
if (ilow == NULL)
|
||||
ilow = zero;
|
||||
Py_INCREF(ilow);
|
||||
|
||||
/* ilow and ihigh correct now; do istep */
|
||||
if (istep == NULL) {
|
||||
istep = PyLong_FromLong(1L);
|
||||
if (istep == NULL)
|
||||
goto Fail;
|
||||
}
|
||||
else {
|
||||
Py_INCREF(istep);
|
||||
}
|
||||
|
||||
if (!PyInt_Check(ilow) && !PyLong_Check(ilow)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"range() integer start argument expected, got %s.",
|
||||
ilow->ob_type->tp_name);
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if (!PyInt_Check(ihigh) && !PyLong_Check(ihigh)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"range() integer end argument expected, got %s.",
|
||||
ihigh->ob_type->tp_name);
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
if (!PyInt_Check(istep) && !PyLong_Check(istep)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"range() integer step argument expected, got %s.",
|
||||
istep->ob_type->tp_name);
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
step_pos = PyObject_RichCompareBool(istep, zero, Py_GT);
|
||||
if (step_pos < 0)
|
||||
goto Fail;
|
||||
if (step_pos)
|
||||
bign = get_len_of_range_longs(ilow, ihigh, istep);
|
||||
else {
|
||||
int step_zero = PyObject_RichCompareBool(istep, zero, Py_EQ);
|
||||
PyObject *neg_istep;
|
||||
if (step_zero < 0)
|
||||
goto Fail;
|
||||
if (step_zero) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"range() step argument must not be zero");
|
||||
goto Fail;
|
||||
}
|
||||
neg_istep = PyNumber_Negative(istep);
|
||||
if (neg_istep == NULL)
|
||||
goto Fail;
|
||||
bign = get_len_of_range_longs(ihigh, ilow, neg_istep);
|
||||
Py_DECREF(neg_istep);
|
||||
}
|
||||
|
||||
n = (int)bign;
|
||||
if (bign < 0 || (long)n != bign) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"range() result has too many items");
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
v = PyList_New(n);
|
||||
if (v == NULL)
|
||||
goto Fail;
|
||||
|
||||
curnum = ilow;
|
||||
Py_INCREF(curnum);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
PyObject *w = PyNumber_Long(curnum);
|
||||
PyObject *tmp_num;
|
||||
if (w == NULL)
|
||||
goto Fail;
|
||||
|
||||
PyList_SET_ITEM(v, i, w);
|
||||
|
||||
tmp_num = PyNumber_Add(curnum, istep);
|
||||
if (tmp_num == NULL)
|
||||
goto Fail;
|
||||
|
||||
Py_DECREF(curnum);
|
||||
curnum = tmp_num;
|
||||
}
|
||||
Py_DECREF(ilow);
|
||||
Py_DECREF(ihigh);
|
||||
Py_DECREF(istep);
|
||||
Py_DECREF(zero);
|
||||
Py_DECREF(curnum);
|
||||
return v;
|
||||
|
||||
Fail:
|
||||
Py_DECREF(ilow);
|
||||
Py_DECREF(ihigh);
|
||||
Py_XDECREF(istep);
|
||||
Py_DECREF(zero);
|
||||
Py_XDECREF(curnum);
|
||||
Py_XDECREF(v);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return number of items in range/xrange (lo, hi, step). step > 0
|
||||
* required. Return a value < 0 if & only if the true value is too
|
||||
* large to fit in a signed long.
|
||||
*/
|
||||
static long
|
||||
get_len_of_range(long lo, long hi, long step)
|
||||
{
|
||||
/* -------------------------------------------------------------
|
||||
If lo >= hi, the range is empty.
|
||||
Else if n values are in the range, the last one is
|
||||
lo + (n-1)*step, which must be <= hi-1. Rearranging,
|
||||
n <= (hi - lo - 1)/step + 1, so taking the floor of the RHS gives
|
||||
the proper value. Since lo < hi in this case, hi-lo-1 >= 0, so
|
||||
the RHS is non-negative and so truncation is the same as the
|
||||
floor. Letting M be the largest positive long, the worst case
|
||||
for the RHS numerator is hi=M, lo=-M-1, and then
|
||||
hi-lo-1 = M-(-M-1)-1 = 2*M. Therefore unsigned long has enough
|
||||
precision to compute the RHS exactly.
|
||||
---------------------------------------------------------------*/
|
||||
long n = 0;
|
||||
if (lo < hi) {
|
||||
unsigned long uhi = (unsigned long)hi;
|
||||
unsigned long ulo = (unsigned long)lo;
|
||||
unsigned long diff = uhi - ulo - 1;
|
||||
n = (long)(diff / (unsigned long)step + 1);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
builtin_range(PyObject *self, PyObject *args)
|
||||
{
|
||||
long ilow = 0, ihigh = 0, istep = 1;
|
||||
long bign;
|
||||
int i, n;
|
||||
|
||||
PyObject *v;
|
||||
|
||||
if (PyTuple_Size(args) <= 1) {
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"l;range() requires 1-3 int arguments",
|
||||
&ihigh)) {
|
||||
PyErr_Clear();
|
||||
return handle_range_longs(self, args);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!PyArg_ParseTuple(args,
|
||||
"ll|l;range() requires 1-3 int arguments",
|
||||
&ilow, &ihigh, &istep)) {
|
||||
PyErr_Clear();
|
||||
return handle_range_longs(self, args);
|
||||
}
|
||||
}
|
||||
if (istep == 0) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"range() step argument must not be zero");
|
||||
return NULL;
|
||||
}
|
||||
if (istep > 0)
|
||||
bign = get_len_of_range(ilow, ihigh, istep);
|
||||
else
|
||||
bign = get_len_of_range(ihigh, ilow, -istep);
|
||||
n = (int)bign;
|
||||
if (bign < 0 || (long)n != bign) {
|
||||
PyErr_SetString(PyExc_OverflowError,
|
||||
"range() result has too many items");
|
||||
return NULL;
|
||||
}
|
||||
v = PyList_New(n);
|
||||
if (v == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < n; i++) {
|
||||
PyObject *w = PyInt_FromLong(ilow);
|
||||
if (w == NULL) {
|
||||
Py_DECREF(v);
|
||||
return NULL;
|
||||
}
|
||||
PyList_SET_ITEM(v, i, w);
|
||||
ilow += istep;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(range_doc,
|
||||
"range([start,] stop[, step]) -> list of integers\n\
|
||||
\n\
|
||||
Return a list containing an arithmetic progression of integers.\n\
|
||||
range(i, j) returns [i, i+1, i+2, ..., j-1]; start (!) defaults to 0.\n\
|
||||
When step is given, it specifies the increment (or decrement).\n\
|
||||
For example, range(4) returns [0, 1, 2, 3]. The end point is omitted!\n\
|
||||
These are exactly the valid indices for a list of 4 elements.");
|
||||
|
||||
static PyObject *
|
||||
builtin_input(PyObject *self, PyObject *args)
|
||||
{
|
||||
|
@ -2277,7 +1981,6 @@ static PyMethodDef builtin_methods[] = {
|
|||
{"ord", builtin_ord, METH_O, ord_doc},
|
||||
{"pow", builtin_pow, METH_VARARGS, pow_doc},
|
||||
{"print", (PyCFunction)builtin_print, METH_VARARGS | METH_KEYWORDS, print_doc},
|
||||
{"range", builtin_range, METH_VARARGS, range_doc},
|
||||
{"reload", builtin_reload, METH_O, reload_doc},
|
||||
{"repr", builtin_repr, METH_O, repr_doc},
|
||||
{"round", (PyCFunction)builtin_round, METH_VARARGS | METH_KEYWORDS, round_doc},
|
||||
|
@ -2344,6 +2047,7 @@ _PyBuiltin_Init(void)
|
|||
SETBUILTIN("int", &PyLong_Type);
|
||||
SETBUILTIN("list", &PyList_Type);
|
||||
SETBUILTIN("object", &PyBaseObject_Type);
|
||||
SETBUILTIN("range", &PyRange_Type);
|
||||
SETBUILTIN("reversed", &PyReversed_Type);
|
||||
SETBUILTIN("set", &PySet_Type);
|
||||
SETBUILTIN("slice", &PySlice_Type);
|
||||
|
@ -2353,7 +2057,6 @@ _PyBuiltin_Init(void)
|
|||
SETBUILTIN("super", &PySuper_Type);
|
||||
SETBUILTIN("tuple", &PyTuple_Type);
|
||||
SETBUILTIN("type", &PyType_Type);
|
||||
SETBUILTIN("xrange", &PyRange_Type);
|
||||
SETBUILTIN("unicode", &PyUnicode_Type);
|
||||
debug = PyBool_FromLong(Py_OptimizeFlag == 0);
|
||||
if (PyDict_SetItemString(dict, "__debug__", debug) < 0) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue