summaryrefslogtreecommitdiffstats
path: root/Modules/_collectionsmodule.c
diff options
context:
space:
mode:
Diffstat (limited to 'Modules/_collectionsmodule.c')
-rw-r--r--Modules/_collectionsmodule.c127
1 files changed, 103 insertions, 24 deletions
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index 54c1343..ee17f4f 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -588,7 +588,7 @@ deque_remove(dequeobject *deque, PyObject *value)
PyDoc_STRVAR(remove_doc,
"D.remove(value) -- remove first occurrence of value.");
-static int
+static void
deque_clear(dequeobject *deque)
{
PyObject *item;
@@ -601,7 +601,6 @@ deque_clear(dequeobject *deque)
assert(deque->leftblock == deque->rightblock &&
deque->leftindex - 1 == deque->rightindex &&
deque->len == 0);
- return 0;
}
static PyObject *
@@ -704,10 +703,7 @@ deque_ass_item(dequeobject *deque, Py_ssize_t i, PyObject *v)
static PyObject *
deque_clearmethod(dequeobject *deque)
{
- int rv;
-
- rv = deque_clear(deque);
- assert (rv != -1);
+ deque_clear(deque);
Py_RETURN_NONE;
}
@@ -767,8 +763,9 @@ static PyObject *
deque_reduce(dequeobject *deque)
{
PyObject *dict, *result, *aslist;
+ _Py_IDENTIFIER(__dict__);
- dict = PyObject_GetAttrString((PyObject *)deque, "__dict__");
+ dict = _PyObject_GetAttrId((PyObject *)deque, &PyId___dict__);
if (dict == NULL)
PyErr_Clear();
aslist = PySequence_List((PyObject *)deque);
@@ -832,8 +829,7 @@ deque_richcompare(PyObject *v, PyObject *w, int op)
if (!PyObject_TypeCheck(v, &deque_type) ||
!PyObject_TypeCheck(w, &deque_type)) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
+ Py_RETURN_NOTIMPLEMENTED;
}
/* Shortcuts */
@@ -1141,6 +1137,35 @@ dequeiter_next(dequeiterobject *it)
}
static PyObject *
+dequeiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t i, index=0;
+ PyObject *deque;
+ dequeiterobject *it;
+ if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
+ return NULL;
+ assert(type == &dequeiter_type);
+
+ it = (dequeiterobject*)deque_iter((dequeobject *)deque);
+ if (!it)
+ return NULL;
+ /* consume items from the queue */
+ for(i=0; i<index; i++) {
+ PyObject *item = dequeiter_next(it);
+ if (item) {
+ Py_DECREF(item);
+ } else {
+ if (it->counter) {
+ Py_DECREF(it);
+ return NULL;
+ } else
+ break;
+ }
+ }
+ return (PyObject*)it;
+}
+
+static PyObject *
dequeiter_len(dequeiterobject *it)
{
return PyLong_FromSsize_t(it->counter);
@@ -1148,14 +1173,21 @@ dequeiter_len(dequeiterobject *it)
PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
+static PyObject *
+dequeiter_reduce(dequeiterobject *it)
+{
+ return Py_BuildValue("O(On)", Py_TYPE(it), it->deque, it->deque->len - it->counter);
+}
+
static PyMethodDef dequeiter_methods[] = {
{"__length_hint__", (PyCFunction)dequeiter_len, METH_NOARGS, length_hint_doc},
+ {"__reduce__", (PyCFunction)dequeiter_reduce, METH_NOARGS, reduce_doc},
{NULL, NULL} /* sentinel */
};
static PyTypeObject dequeiter_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "deque_iterator", /* tp_name */
+ "_collections._deque_iterator", /* tp_name */
sizeof(dequeiterobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -1183,6 +1215,16 @@ static PyTypeObject dequeiter_type = {
PyObject_SelfIter, /* tp_iter */
(iternextfunc)dequeiter_next, /* tp_iternext */
dequeiter_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ dequeiter_new, /* tp_new */
0,
};
@@ -1236,9 +1278,38 @@ dequereviter_next(dequeiterobject *it)
return item;
}
+static PyObject *
+dequereviter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t i, index=0;
+ PyObject *deque;
+ dequeiterobject *it;
+ if (!PyArg_ParseTuple(args, "O!|n", &deque_type, &deque, &index))
+ return NULL;
+ assert(type == &dequereviter_type);
+
+ it = (dequeiterobject*)deque_reviter((dequeobject *)deque);
+ if (!it)
+ return NULL;
+ /* consume items from the queue */
+ for(i=0; i<index; i++) {
+ PyObject *item = dequereviter_next(it);
+ if (item) {
+ Py_DECREF(item);
+ } else {
+ if (it->counter) {
+ Py_DECREF(it);
+ return NULL;
+ } else
+ break;
+ }
+ }
+ return (PyObject*)it;
+}
+
static PyTypeObject dequereviter_type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "deque_reverse_iterator", /* tp_name */
+ "_collections._deque_reverse_iterator", /* tp_name */
sizeof(dequeiterobject), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
@@ -1266,6 +1337,16 @@ static PyTypeObject dequereviter_type = {
PyObject_SelfIter, /* tp_iter */
(iternextfunc)dequereviter_next, /* tp_iternext */
dequeiter_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ dequereviter_new, /* tp_new */
0,
};
@@ -1354,13 +1435,15 @@ defdict_reduce(defdictobject *dd)
PyObject *items;
PyObject *iter;
PyObject *result;
+ _Py_IDENTIFIER(items);
+
if (dd->default_factory == NULL || dd->default_factory == Py_None)
args = PyTuple_New(0);
else
args = PyTuple_Pack(1, dd->default_factory);
if (args == NULL)
return NULL;
- items = PyObject_CallMethod((PyObject *)dd, "items", "()");
+ items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, "()");
if (items == NULL) {
Py_DECREF(args);
return NULL;
@@ -1573,12 +1656,8 @@ _count_elements(PyObject *self, PyObject *args)
if (PyDict_CheckExact(mapping)) {
while (1) {
key = PyIter_Next(it);
- if (key == NULL) {
- if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration))
- PyErr_Clear();
- else
- break;
- }
+ if (key == NULL)
+ break;
oldval = PyDict_GetItem(mapping, key);
if (oldval == NULL) {
if (PyDict_SetItem(mapping, key, one) == -1)
@@ -1596,12 +1675,8 @@ _count_elements(PyObject *self, PyObject *args)
} else {
while (1) {
key = PyIter_Next(it);
- if (key == NULL) {
- if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_StopIteration))
- PyErr_Clear();
- else
- break;
- }
+ if (key == NULL)
+ break;
oldval = PyObject_GetItem(mapping, key);
if (oldval == NULL) {
if (!PyErr_Occurred() || !PyErr_ExceptionMatches(PyExc_KeyError))
@@ -1678,9 +1753,13 @@ PyInit__collections(void)
if (PyType_Ready(&dequeiter_type) < 0)
return NULL;
+ Py_INCREF(&dequeiter_type);
+ PyModule_AddObject(m, "_deque_iterator", (PyObject *)&dequeiter_type);
if (PyType_Ready(&dequereviter_type) < 0)
return NULL;
+ Py_INCREF(&dequereviter_type);
+ PyModule_AddObject(m, "_deque_reverse_iterator", (PyObject *)&dequereviter_type);
return m;
}