Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Replace iter.c with iter.py

We use the test suite created in the previous commit to ensure
that the replacement is equivalent.
  • Loading branch information...
commit 8dfb39786c5d5c6313947328509481f9bdccc27b 1 parent f910f6d
@cortesi cortesi authored
View
18 test/test_iter.py
@@ -25,6 +25,24 @@ def test_simple(self):
libpry.raises("too few items", list, i)
+class uFlatten(libpry.AutoTree):
+ def test_simple(self):
+ l = [1, 2, 3]
+ assert list(iter.flatten(l)) == l
+
+ l = [[1, 2], 3]
+ assert list(iter.flatten(l)) == [1, 2, 3]
+
+ l = [[1, [2]], 3]
+ assert list(iter.flatten(l)) == [1, 2, 3]
+
+ l = [["one", [2]], 3]
+ assert list(iter.flatten(l)) == ["one", 2, 3]
+
+
+
+
tests = [
+ uFlatten(),
uIter(),
]
View
187 xcb/iter.c
@@ -1,187 +0,0 @@
-#include "module.h"
-#include "except.h"
-#include "iter.h"
-
-/*
- * Helpers
- */
-PyObject *xpybExcept_base;
-
-
-static void
-xpybIter_err(xpybIter *self)
-{
- if (self->is_list)
- PyErr_Format(xpybExcept_base,
- "Extra items in '%s' list (expect multiple of %d).",
- PyString_AS_STRING(self->name), self->groupsize);
- else
- PyErr_Format(xpybExcept_base,
- "Too few items in '%s' list (expect %d).",
- PyString_AS_STRING(self->name), self->groupsize);
-}
-
-static PyObject *
-xpybIter_pop(xpybIter *self)
-{
- PyObject *cur, *next, *item;
-
- cur = PyList_GET_ITEM(self->stack, self->top);
- item = PyIter_Next(cur);
-
- if (item == NULL) {
- if (PyErr_Occurred() || self->top < 1)
- return NULL;
- if (PyList_SetSlice(self->stack, self->top, self->top + 1, NULL) < 0)
- return NULL;
- self->top--;
- return xpybIter_pop(self);
- }
-
- if (PySequence_Check(item)) {
- next = PyObject_GetIter(item);
- if (next == NULL)
- goto err1;
- if (PyList_Append(self->stack, next) < 0)
- goto err2;
-
- self->top++;
- Py_DECREF(next);
- Py_DECREF(item);
- return xpybIter_pop(self);
- }
-
- return item;
-err2:
- Py_DECREF(next);
-err1:
- Py_DECREF(item);
- return NULL;
-}
-
-
-/*
- * Infrastructure
- */
-
-static PyObject *
-xpybIter_new(PyTypeObject *self, PyObject *args, PyObject *kw)
-{
- return PyType_GenericNew(self, args, kw);
-}
-
-static int
-xpybIter_init(xpybIter *self, PyObject *args, PyObject *kw)
-{
- PyObject *name, *list, *bool;
- Py_ssize_t groupsize;
-
- if (!PyArg_ParseTuple(args, "OnSO", &list, &groupsize, &name, &bool))
- return -1;
-
- Py_INCREF(self->name = name);
- Py_INCREF(self->list = list);
- self->groupsize = groupsize;
- self->is_list = PyObject_IsTrue(bool);
- return 0;
-}
-
-static PyObject *
-xpybIter_get(xpybIter *self)
-{
- PyObject *iterator;
-
- Py_CLEAR(self->stack);
-
- self->stack = PyList_New(1);
- if (self->stack == NULL)
- return NULL;
-
- iterator = PyObject_GetIter(self->list);
- if (iterator == NULL)
- return NULL;
-
- PyList_SET_ITEM(self->stack, 0, iterator);
- self->top = 0;
-
- Py_INCREF(self);
- return (PyObject *)self;
-}
-
-static PyObject *
-xpybIter_next(xpybIter *self)
-{
- PyObject *tuple, *tmp;
- Py_ssize_t i;
-
- tuple = PyTuple_New(self->groupsize);
- if (tuple == NULL)
- return NULL;
-
- for (i = 0; i < self->groupsize; i++) {
- tmp = xpybIter_pop(self);
- if (tmp == NULL) {
- if (i > 0 && !PyErr_Occurred())
- xpybIter_err(self);
- goto end;
- }
- PyTuple_SET_ITEM(tuple, i, tmp);
- }
-
- return tuple;
-end:
- Py_DECREF(tuple);
- return NULL;
-}
-
-static void
-xpybIter_dealloc(xpybIter *self)
-{
- Py_CLEAR(self->stack);
- Py_CLEAR(self->list);
- Py_CLEAR(self->name);
-
- xpybIter_type.tp_base->tp_dealloc((PyObject *)self);
-}
-
-
-/*
- * Members
- */
-
-
-/*
- * Definition
- */
-
-PyTypeObject xpybIter_type = {
- PyObject_HEAD_INIT(NULL)
- .tp_name = "xcb.Iterator",
- .tp_basicsize = sizeof(xpybIter),
- .tp_init = (initproc)xpybIter_init,
- .tp_new = xpybIter_new,
- .tp_dealloc = (destructor)xpybIter_dealloc,
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = "XCB flattening-iterator object",
- .tp_iter = (getiterfunc)xpybIter_get,
- .tp_iternext = (iternextfunc)xpybIter_next
-};
-
-
-/*
- * Module init
- */
-void inititer(void){
- PyObject *module, *common;
-
- module = Py_InitModule("iter", NULL);
- if (PyType_Ready(&xpybIter_type) < 0)
- return;
- Py_INCREF(&xpybIter_type);
- if (PyModule_AddObject(module, "Iterator", (PyObject *)&xpybIter_type) < 0)
- return;
- common = PyImport_ImportModule("xcb.common");
- if (!common)
- return;
- xpybExcept_base = PyObject_GetAttrString(common, "Exception");
-}
View
18 xcb/iter.h
@@ -1,18 +0,0 @@
-#ifndef XPYB_ITER_H
-#define XPYB_ITER_H
-
-typedef struct {
- PyObject_HEAD
- PyObject *name;
- PyObject *list;
- PyObject *stack;
- Py_ssize_t top;
- Py_ssize_t groupsize;
- int is_list;
-} xpybIter;
-
-extern PyTypeObject xpybIter_type;
-
-int xpybIter_modinit(PyObject *m);
-
-#endif
View
22 xcb/iter.py
@@ -0,0 +1,22 @@
+import common
+
+def flatten(obj):
+ for el in obj:
+ if hasattr(el, "__iter__") and not isinstance(el, basestring):
+ for i in flatten(el):
+ yield i
+ else:
+ yield el
+
+
+def Iterator(obj, group, name, is_list):
+ f = list(flatten(obj))
+ if len(f)%group:
+ if is_list:
+ m = "Extra items in %s list (expect multiples of %s)."
+ else:
+ m = "Too few items in %s list (expect %s)."
+ raise common.Exception(m%(name, group))
+ for i in range(0, len(f), group):
+ yield tuple(f[i:i+group])
+
View
3  xcb/module.c
@@ -11,7 +11,6 @@
#include "struct.h"
#include "union.h"
#include "list.h"
-#include "iter.h"
#include "conn.h"
#include "extkey.h"
#include "ext.h"
@@ -347,8 +346,6 @@ initxcb(void)
if (xpybList_modinit(m) < 0)
return;
- if (xpybIter_modinit(m) < 0)
- return;
if (xpybVoid_modinit(m) < 0)
return;
Please sign in to comment.
Something went wrong with that request. Please try again.