mirror of https://github.com/python/cpython
Convert iterator __len__() methods to a private API.
This commit is contained in:
parent
9ceebd5445
commit
6b27cda643
|
@ -422,6 +422,21 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
|
||||||
PyAPI_FUNC(int) PyObject_Length(PyObject *o);
|
PyAPI_FUNC(int) PyObject_Length(PyObject *o);
|
||||||
#define PyObject_Length PyObject_Size
|
#define PyObject_Length PyObject_Size
|
||||||
|
|
||||||
|
PyAPI_FUNC(int) _PyObject_LengthCue(PyObject *o);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Return the size of object o. If the object, o, provides
|
||||||
|
both sequence and mapping protocols, the sequence size is
|
||||||
|
returned. On error, -1 is returned. If the object provides
|
||||||
|
a _length_cue() method, its value is returned. This is the
|
||||||
|
equivalent to the Python expression:
|
||||||
|
try:
|
||||||
|
return len(o)
|
||||||
|
except (AttributeError, TypeError):
|
||||||
|
if hasattr(o, '_length_cue'):
|
||||||
|
return o._length_cue()
|
||||||
|
raise
|
||||||
|
*/
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key);
|
PyAPI_FUNC(PyObject *) PyObject_GetItem(PyObject *o, PyObject *key);
|
||||||
|
|
||||||
|
|
|
@ -144,6 +144,7 @@ class TestReversed(unittest.TestCase):
|
||||||
|
|
||||||
def test_len(self):
|
def test_len(self):
|
||||||
# This is an implementation detail, not an interface requirement
|
# This is an implementation detail, not an interface requirement
|
||||||
|
from test.test_iterlen import len
|
||||||
for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
|
for s in ('hello', tuple('hello'), list('hello'), xrange(5)):
|
||||||
self.assertEqual(len(reversed(s)), len(s))
|
self.assertEqual(len(reversed(s)), len(s))
|
||||||
r = reversed(s)
|
r = reversed(s)
|
||||||
|
|
|
@ -43,12 +43,22 @@ enumerate(iter('abc')).
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from test import test_support
|
from test import test_support
|
||||||
from itertools import repeat, count
|
from itertools import repeat
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from UserList import UserList
|
from UserList import UserList
|
||||||
|
from __builtin__ import len as _len
|
||||||
|
|
||||||
n = 10
|
n = 10
|
||||||
|
|
||||||
|
def len(obj):
|
||||||
|
try:
|
||||||
|
return _len(obj)
|
||||||
|
except TypeError:
|
||||||
|
try:
|
||||||
|
return obj._length_cue()
|
||||||
|
except AttributeError:
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
class TestInvariantWithoutMutations(unittest.TestCase):
|
class TestInvariantWithoutMutations(unittest.TestCase):
|
||||||
|
|
||||||
def test_invariant(self):
|
def test_invariant(self):
|
||||||
|
|
|
@ -670,6 +670,7 @@ class TestVariousIteratorArgs(unittest.TestCase):
|
||||||
class LengthTransparency(unittest.TestCase):
|
class LengthTransparency(unittest.TestCase):
|
||||||
|
|
||||||
def test_repeat(self):
|
def test_repeat(self):
|
||||||
|
from test.test_iterlen import len
|
||||||
self.assertEqual(len(repeat(None, 50)), 50)
|
self.assertEqual(len(repeat(None, 50)), 50)
|
||||||
self.assertRaises(TypeError, len, repeat(None))
|
self.assertRaises(TypeError, len, repeat(None))
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 2.5 alpha 1?
|
||||||
Core and builtins
|
Core and builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- All iterators now have a Boolean value of true. Formerly, some iterators
|
||||||
|
supported a __len__() method which evaluated to False when the iterator
|
||||||
|
was empty.
|
||||||
|
|
||||||
- On 64-bit platforms, when __len__() returns a value that cannot be
|
- On 64-bit platforms, when __len__() returns a value that cannot be
|
||||||
represented as a C int, raise OverflowError.
|
represented as a C int, raise OverflowError.
|
||||||
|
|
||||||
|
|
|
@ -935,15 +935,17 @@ dequeiter_next(dequeiterobject *it)
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
dequeiter_len(dequeiterobject *it)
|
dequeiter_len(dequeiterobject *it)
|
||||||
{
|
{
|
||||||
return it->counter;
|
return PyInt_FromLong(it->counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods dequeiter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)dequeiter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef dequeiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)dequeiter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject dequeiter_type = {
|
PyTypeObject dequeiter_type = {
|
||||||
|
@ -960,7 +962,7 @@ PyTypeObject dequeiter_type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&dequeiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -976,6 +978,7 @@ PyTypeObject dequeiter_type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)dequeiter_next, /* tp_iternext */
|
(iternextfunc)dequeiter_next, /* tp_iternext */
|
||||||
|
dequeiter_methods, /* tp_methods */
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1042,7 +1045,7 @@ PyTypeObject dequereviter_type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&dequeiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -1058,6 +1061,7 @@ PyTypeObject dequereviter_type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)dequereviter_next, /* tp_iternext */
|
(iternextfunc)dequereviter_next, /* tp_iternext */
|
||||||
|
dequeiter_methods, /* tp_methods */
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2336,17 +2336,21 @@ repeat_repr(repeatobject *ro)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
repeat_len(repeatobject *ro)
|
repeat_len(repeatobject *ro)
|
||||||
{
|
{
|
||||||
if (ro->cnt == -1)
|
if (ro->cnt == -1) {
|
||||||
PyErr_SetString(PyExc_TypeError, "len() of unsized object");
|
PyErr_SetString(PyExc_TypeError, "len() of unsized object");
|
||||||
return (int)(ro->cnt);
|
return NULL;
|
||||||
|
}
|
||||||
|
return PyInt_FromLong(ro->cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods repeat_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)repeat_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef repeat_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)repeat_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyDoc_STRVAR(repeat_doc,
|
PyDoc_STRVAR(repeat_doc,
|
||||||
|
@ -2368,7 +2372,7 @@ static PyTypeObject repeat_type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
(reprfunc)repeat_repr, /* tp_repr */
|
(reprfunc)repeat_repr, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&repeat_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -2385,7 +2389,7 @@ static PyTypeObject repeat_type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)repeat_next, /* tp_iternext */
|
(iternextfunc)repeat_next, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
repeat_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
|
|
|
@ -81,6 +81,31 @@ PyObject_Length(PyObject *o)
|
||||||
}
|
}
|
||||||
#define PyObject_Length PyObject_Size
|
#define PyObject_Length PyObject_Size
|
||||||
|
|
||||||
|
int
|
||||||
|
_PyObject_LengthCue(PyObject *o)
|
||||||
|
{
|
||||||
|
int rv = PyObject_Size(o);
|
||||||
|
if (rv != -1)
|
||||||
|
return rv;
|
||||||
|
if (PyErr_ExceptionMatches(PyExc_TypeError) ||
|
||||||
|
PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
PyObject *err_type, *err_value, *err_tb, *ro;
|
||||||
|
|
||||||
|
PyErr_Fetch(&err_type, &err_value, &err_tb);
|
||||||
|
ro = PyObject_CallMethod(o, "_length_cue", NULL);
|
||||||
|
if (ro != NULL) {
|
||||||
|
rv = (int)PyInt_AsLong(ro);
|
||||||
|
Py_DECREF(ro);
|
||||||
|
Py_XDECREF(err_type);
|
||||||
|
Py_XDECREF(err_value);
|
||||||
|
Py_XDECREF(err_tb);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
PyErr_Restore(err_type, err_value, err_tb);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyObject_GetItem(PyObject *o, PyObject *key)
|
PyObject_GetItem(PyObject *o, PyObject *key)
|
||||||
{
|
{
|
||||||
|
@ -1399,7 +1424,7 @@ PySequence_Tuple(PyObject *v)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Guess result size and allocate space. */
|
/* Guess result size and allocate space. */
|
||||||
n = PyObject_Size(v);
|
n = _PyObject_LengthCue(v);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
||||||
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
|
|
@ -2054,17 +2054,20 @@ dictiter_dealloc(dictiterobject *di)
|
||||||
PyObject_Del(di);
|
PyObject_Del(di);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
dictiter_len(dictiterobject *di)
|
dictiter_len(dictiterobject *di)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
|
if (di->di_dict != NULL && di->di_used == di->di_dict->ma_used)
|
||||||
return di->len;
|
len = di->len;
|
||||||
return 0;
|
return PyInt_FromLong(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods dictiter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)dictiter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef dictiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)dictiter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *dictiter_iternextkey(dictiterobject *di)
|
static PyObject *dictiter_iternextkey(dictiterobject *di)
|
||||||
|
@ -2120,7 +2123,7 @@ PyTypeObject PyDictIterKey_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&dictiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -2136,6 +2139,8 @@ PyTypeObject PyDictIterKey_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)dictiter_iternextkey, /* tp_iternext */
|
(iternextfunc)dictiter_iternextkey, /* tp_iternext */
|
||||||
|
dictiter_methods, /* tp_methods */
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *dictiter_iternextvalue(dictiterobject *di)
|
static PyObject *dictiter_iternextvalue(dictiterobject *di)
|
||||||
|
@ -2191,7 +2196,7 @@ PyTypeObject PyDictIterValue_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&dictiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -2207,6 +2212,8 @@ PyTypeObject PyDictIterValue_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)dictiter_iternextvalue, /* tp_iternext */
|
(iternextfunc)dictiter_iternextvalue, /* tp_iternext */
|
||||||
|
dictiter_methods, /* tp_methods */
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *dictiter_iternextitem(dictiterobject *di)
|
static PyObject *dictiter_iternextitem(dictiterobject *di)
|
||||||
|
@ -2276,7 +2283,7 @@ PyTypeObject PyDictIterItem_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&dictiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -2292,4 +2299,6 @@ PyTypeObject PyDictIterItem_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)dictiter_iternextitem, /* tp_iternext */
|
(iternextfunc)dictiter_iternextitem, /* tp_iternext */
|
||||||
|
dictiter_methods, /* tp_methods */
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
|
|
@ -239,23 +239,25 @@ PyDoc_STRVAR(reversed_doc,
|
||||||
"\n"
|
"\n"
|
||||||
"Return a reverse iterator");
|
"Return a reverse iterator");
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
reversed_len(reversedobject *ro)
|
reversed_len(reversedobject *ro)
|
||||||
{
|
{
|
||||||
int position, seqsize;
|
int position, seqsize;
|
||||||
|
|
||||||
if (ro->seq == NULL)
|
if (ro->seq == NULL)
|
||||||
return 0;
|
return PyInt_FromLong(0);
|
||||||
seqsize = PySequence_Size(ro->seq);
|
seqsize = PySequence_Size(ro->seq);
|
||||||
if (seqsize == -1)
|
if (seqsize == -1)
|
||||||
return -1;
|
return NULL;
|
||||||
position = ro->index + 1;
|
position = ro->index + 1;
|
||||||
return (seqsize < position) ? 0 : position;
|
return PyInt_FromLong((seqsize < position) ? 0 : position);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods reversed_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)reversed_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef reversediter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)reversed_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PyReversed_Type = {
|
PyTypeObject PyReversed_Type = {
|
||||||
|
@ -272,7 +274,7 @@ PyTypeObject PyReversed_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&reversed_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -289,7 +291,7 @@ PyTypeObject PyReversed_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)reversed_next, /* tp_iternext */
|
(iternextfunc)reversed_next, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
reversediter_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
|
|
|
@ -71,7 +71,7 @@ iter_iternext(PyObject *iterator)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
iter_len(seqiterobject *it)
|
iter_len(seqiterobject *it)
|
||||||
{
|
{
|
||||||
int seqsize, len;
|
int seqsize, len;
|
||||||
|
@ -79,17 +79,19 @@ iter_len(seqiterobject *it)
|
||||||
if (it->it_seq) {
|
if (it->it_seq) {
|
||||||
seqsize = PySequence_Size(it->it_seq);
|
seqsize = PySequence_Size(it->it_seq);
|
||||||
if (seqsize == -1)
|
if (seqsize == -1)
|
||||||
return -1;
|
return NULL;
|
||||||
len = seqsize - it->it_index;
|
len = seqsize - it->it_index;
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
return len;
|
return PyInt_FromLong(len);
|
||||||
}
|
}
|
||||||
return 0;
|
return PyInt_FromLong(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods iter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)iter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef seqiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)iter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PySeqIter_Type = {
|
PyTypeObject PySeqIter_Type = {
|
||||||
|
@ -106,7 +108,7 @@ PyTypeObject PySeqIter_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&iter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -122,13 +124,8 @@ PyTypeObject PySeqIter_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)iter_iternext, /* tp_iternext */
|
(iternextfunc)iter_iternext, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
seqiter_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
|
||||||
0, /* tp_base */
|
|
||||||
0, /* tp_dict */
|
|
||||||
0, /* tp_descr_get */
|
|
||||||
0, /* tp_descr_set */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* -------------------------------------- */
|
/* -------------------------------------- */
|
||||||
|
@ -236,10 +233,4 @@ PyTypeObject PyCallIter_Type = {
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)calliter_iternext, /* tp_iternext */
|
(iternextfunc)calliter_iternext, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
0, /* tp_methods */
|
||||||
0, /* tp_members */
|
|
||||||
0, /* tp_getset */
|
|
||||||
0, /* tp_base */
|
|
||||||
0, /* tp_dict */
|
|
||||||
0, /* tp_descr_get */
|
|
||||||
0, /* tp_descr_set */
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -775,7 +775,7 @@ listextend(PyListObject *self, PyObject *b)
|
||||||
iternext = *it->ob_type->tp_iternext;
|
iternext = *it->ob_type->tp_iternext;
|
||||||
|
|
||||||
/* Guess a result list size. */
|
/* Guess a result list size. */
|
||||||
n = PyObject_Size(b);
|
n = _PyObject_LengthCue(b);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
||||||
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
@ -2764,21 +2764,23 @@ listiter_next(listiterobject *it)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
listiter_len(listiterobject *it)
|
listiter_len(listiterobject *it)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
if (it->it_seq) {
|
if (it->it_seq) {
|
||||||
len = PyList_GET_SIZE(it->it_seq) - it->it_index;
|
len = PyList_GET_SIZE(it->it_seq) - it->it_index;
|
||||||
if (len >= 0)
|
if (len >= 0)
|
||||||
return len;
|
return PyInt_FromLong((long)len);
|
||||||
}
|
}
|
||||||
return 0;
|
return PyInt_FromLong(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods listiter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)listiter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef listiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)listiter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PyListIter_Type = {
|
PyTypeObject PyListIter_Type = {
|
||||||
|
@ -2795,7 +2797,7 @@ PyTypeObject PyListIter_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&listiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -2811,13 +2813,8 @@ PyTypeObject PyListIter_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)listiter_next, /* tp_iternext */
|
(iternextfunc)listiter_next, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
listiter_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
|
||||||
0, /* tp_base */
|
|
||||||
0, /* tp_dict */
|
|
||||||
0, /* tp_descr_get */
|
|
||||||
0, /* tp_descr_set */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*********************** List Reverse Iterator **************************/
|
/*********************** List Reverse Iterator **************************/
|
||||||
|
|
|
@ -262,17 +262,18 @@ rangeiter_next(rangeiterobject *r)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
rangeiter_len(rangeiterobject *r)
|
rangeiter_len(rangeiterobject *r)
|
||||||
{
|
{
|
||||||
return r->len - r->index;
|
return PyInt_FromLong(r->len - r->index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods rangeiter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)rangeiter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
static PyMethodDef rangeiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)rangeiter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
|
};
|
||||||
|
|
||||||
static PyTypeObject Pyrangeiter_Type = {
|
static PyTypeObject Pyrangeiter_Type = {
|
||||||
PyObject_HEAD_INIT(&PyType_Type)
|
PyObject_HEAD_INIT(&PyType_Type)
|
||||||
|
@ -288,7 +289,7 @@ static PyTypeObject Pyrangeiter_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&rangeiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -304,5 +305,6 @@ static PyTypeObject Pyrangeiter_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)rangeiter_next, /* tp_iternext */
|
(iternextfunc)rangeiter_next, /* tp_iternext */
|
||||||
0, /* tp_methods */
|
rangeiter_methods, /* tp_methods */
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
|
|
@ -749,17 +749,20 @@ setiter_dealloc(setiterobject *si)
|
||||||
PyObject_Del(si);
|
PyObject_Del(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
setiter_len(setiterobject *si)
|
setiter_len(setiterobject *si)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
if (si->si_set != NULL && si->si_used == si->si_set->used)
|
if (si->si_set != NULL && si->si_used == si->si_set->used)
|
||||||
return si->len;
|
len = si->len;
|
||||||
return 0;
|
return PyInt_FromLong(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods setiter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)setiter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef setiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)setiter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyObject *setiter_iternext(setiterobject *si)
|
static PyObject *setiter_iternext(setiterobject *si)
|
||||||
|
@ -814,7 +817,7 @@ static PyTypeObject PySetIter_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&setiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -830,6 +833,8 @@ static PyTypeObject PySetIter_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)setiter_iternext, /* tp_iternext */
|
(iternextfunc)setiter_iternext, /* tp_iternext */
|
||||||
|
setiter_methods, /* tp_methods */
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -851,17 +851,20 @@ tupleiter_next(tupleiterobject *it)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static PyObject *
|
||||||
tupleiter_len(tupleiterobject *it)
|
tupleiter_len(tupleiterobject *it)
|
||||||
{
|
{
|
||||||
|
int len = 0;
|
||||||
if (it->it_seq)
|
if (it->it_seq)
|
||||||
return PyTuple_GET_SIZE(it->it_seq) - it->it_index;
|
len = PyTuple_GET_SIZE(it->it_seq) - it->it_index;
|
||||||
return 0;
|
return PyInt_FromLong(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PySequenceMethods tupleiter_as_sequence = {
|
PyDoc_STRVAR(length_cue_doc, "Private method returning an estimate of len(list(it)).");
|
||||||
(inquiry)tupleiter_len, /* sq_length */
|
|
||||||
0, /* sq_concat */
|
static PyMethodDef tupleiter_methods[] = {
|
||||||
|
{"_length_cue", (PyCFunction)tupleiter_len, METH_NOARGS, length_cue_doc},
|
||||||
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyTypeObject PyTupleIter_Type = {
|
PyTypeObject PyTupleIter_Type = {
|
||||||
|
@ -878,7 +881,7 @@ PyTypeObject PyTupleIter_Type = {
|
||||||
0, /* tp_compare */
|
0, /* tp_compare */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
&tupleiter_as_sequence, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -894,4 +897,6 @@ PyTypeObject PyTupleIter_Type = {
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)tupleiter_next, /* tp_iternext */
|
(iternextfunc)tupleiter_next, /* tp_iternext */
|
||||||
|
tupleiter_methods, /* tp_methods */
|
||||||
|
0,
|
||||||
};
|
};
|
||||||
|
|
|
@ -221,7 +221,7 @@ builtin_filter(PyObject *self, PyObject *args)
|
||||||
goto Fail_arg;
|
goto Fail_arg;
|
||||||
|
|
||||||
/* Guess a result list size. */
|
/* Guess a result list size. */
|
||||||
len = PyObject_Size(seq);
|
len = _PyObject_LengthCue(seq);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
||||||
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
@ -873,7 +873,7 @@ builtin_map(PyObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update len. */
|
/* Update len. */
|
||||||
curlen = PyObject_Size(curseq);
|
curlen = _PyObject_LengthCue(curseq);
|
||||||
if (curlen < 0) {
|
if (curlen < 0) {
|
||||||
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
||||||
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
@ -2108,7 +2108,7 @@ builtin_zip(PyObject *self, PyObject *args)
|
||||||
len = -1; /* unknown */
|
len = -1; /* unknown */
|
||||||
for (i = 0; i < itemsize; ++i) {
|
for (i = 0; i < itemsize; ++i) {
|
||||||
PyObject *item = PyTuple_GET_ITEM(args, i);
|
PyObject *item = PyTuple_GET_ITEM(args, i);
|
||||||
int thislen = PyObject_Size(item);
|
int thislen = _PyObject_LengthCue(item);
|
||||||
if (thislen < 0) {
|
if (thislen < 0) {
|
||||||
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
if (!PyErr_ExceptionMatches(PyExc_TypeError) &&
|
||||||
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
!PyErr_ExceptionMatches(PyExc_AttributeError)) {
|
||||||
|
|
Loading…
Reference in New Issue