[Jython-checkins] jython: Extract imap from itertools.java.

frank.wierzbicki jython-checkins at python.org
Fri Apr 27 00:20:22 CEST 2012


http://hg.python.org/jython/rev/1476b10e8a23
changeset:   6627:1476b10e8a23
user:        Frank Wierzbicki <fwierzbicki at gmail.com>
date:        Thu Apr 26 15:00:54 2012 -0700
summary:
  Extract imap from itertools.java.

files:
  src/org/python/modules/itertools/itertools.java |  976 +---------
  src/org/python/modules/itertools/itertools.java |   56 +-
  2 files changed, 55 insertions(+), 977 deletions(-)


diff --git a/src/org/python/modules/itertools/itertools.java b/src/org/python/modules/itertools/imap.java
copy from src/org/python/modules/itertools/itertools.java
copy to src/org/python/modules/itertools/imap.java
--- a/src/org/python/modules/itertools/itertools.java
+++ b/src/org/python/modules/itertools/imap.java
@@ -1,257 +1,74 @@
 /* Copyright (c) Jython Developers */
 package org.python.modules.itertools;
 
-import java.util.ArrayList;
-import java.util.List;
-
-import org.python.core.__builtin__;
 import org.python.core.ArgParser;
-import org.python.core.ClassDictInit;
 import org.python.core.Py;
-import org.python.core.PyException;
-import org.python.core.PyInteger;
 import org.python.core.PyIterator;
-import org.python.core.PyNone;
 import org.python.core.PyObject;
 import org.python.core.PyString;
 import org.python.core.PyTuple;
-import org.python.core.PyXRange;
+import org.python.core.PyType;
+import org.python.expose.ExposedClassMethod;
+import org.python.expose.ExposedGet;
+import org.python.expose.ExposedNew;
+import org.python.expose.ExposedMethod;
+import org.python.expose.ExposedType;
 
-import java.util.Arrays; //XXX
+import java.util.ArrayList;
 
-/**
- * Functional tools for creating and using iterators. Java implementation of the CPython module
- * itertools.
- * 
- * @since 2.5
- */
-public class itertools implements ClassDictInit {
+ at ExposedType(name = "itertools.imap", base = PyObject.class)
+public class imap extends PyObject {
 
+    public static final PyType TYPE = PyType.fromClass(imap.class);
+    private PyIterator iter;
+
+    @ExposedGet
     public static PyString __doc__ = new PyString(
-            "Functional tools for creating and using iterators.\n\nInfinite iterators:\n"
-	        + "count([n]) --> n, n+1, n+2, ...\n"
-	        + "cycle(p) --> p0, p1, ... plast, p0, p1, ...\n"
-	        + "repeat(elem [,n]) --> elem, elem, elem, ... endlessly or up to n times\n\n"
-	    
-	        + "Iterators terminating on the shortest input sequence:\n"
-	        + "chain(p, q, ...) --> p0, p1, ... plast, q0, q1, ...\n"
-	        + "compress(data, selectors) --> (d[0] if s[0]), (d[1] if s[1]), ...\n"
-	        + "dropwhile(pred, seq) --> seq[n], seq[n+1], starting when pred fails\n"
-	        + "groupby(iterable[, keyfunc]) --> sub-iterators grouped by value of keyfunc(v)\n"
-	        + "ifilter(pred, seq) --> elements of seq where pred(elem) is True\n"
-	        + "ifilterfalse(pred, seq) --> elements of seq where pred(elem) is False\n"
-	        + "islice(seq, [start,] stop [, step]) --> elements from seq[start:stop:step]\n"
-	        + "imap(fun, p, q, ...) --> fun(p0, q0), fun(p1, q1), ...\n"
-	        + "starmap(fun, seq) --> fun(*seq[0]), fun(*seq[1]), ...\n"
-	        + "tee(it, n=2) --> (it1, it2 , ... itn) splits one iterator into n\n"
-	        + "takewhile(pred, seq) --> seq[0], seq[1], until pred fails\n"
-	        + "izip(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n"
-	        + "izip_longest(p, q, ...) --> (p[0], q[0]), (p[1], q[1]), ...\n\n"
-
-	        + "Combinatoric generators:\n"
-	        + "product(p, q, ... [repeat=1]) --> cartesian product\n"
-	        + "permutations(p[, r])\n"
-	        + "combinations(p, r)\n"
-	        + "combinations_with_replacement(p, r)");
-
-    /**
-     * Iterator base class used by most methods.
-     */
-    static abstract class ItertoolsIterator extends PyIterator {
-
-        /**
-         * Returns the next element from an iterator. If it raises/throws StopIteration just store
-         * the Exception and return null according to PyIterator practice.
-         */
-        protected PyObject nextElement(PyObject pyIter) {
-            PyObject element = null;
-            try {
-                element = pyIter.__iternext__();//next();
-            } catch (PyException pyEx) {
-                if (pyEx.match(Py.StopIteration)) {
-                    // store exception - will be used by PyIterator.next()
-                    stopException = pyEx;
-                } else {
-                    throw pyEx;
-                }
-            }
-            return element;
-        }
-    }
-
-    public static void classDictInit(PyObject dict) {
-        dict.__setitem__("__name__", new PyString("itertools"));
-        dict.__setitem__("__doc__", __doc__);
-        dict.__setitem__("chain", chain.TYPE);
-
-        // Hide from Python
-        dict.__setitem__("classDictInit", null);
-        dict.__setitem__("initClassExceptions", null);
-    }
-    
-
-    public static PyString __doc__count = new PyString(
-        "count(start=0, step=1) --> count object\n\n" +
-        "Return a count object whose .next() method returns consecutive values.\n" +
-        "  Equivalent to:\n" +
-        "\n" +
-        "      def count(firstval=0, step=1):\n" +
-        "      x = firstval\n" +
-        "      while 1:\n" +
-        "          yield x\n" +
-        "          x += step\n");
-
-
-    /**
-     * Creates an iterator that returns consecutive integers starting at <code>init</code> with <code>step</code> step.
-     */
-    public static PyIterator count(final int init, final int step) {
-        return new PyIterator() {
-            int counter = init;
-            int stepper = step;
-
-            public PyObject __iternext__() {
-                int result = counter;
-                counter += stepper;
-                return new PyInteger(result);
-            }
-            
-            public PyString __repr__() {
-                return (PyString)(Py.newString("count(%d, %d)").__mod__(new PyTuple(
-                                Py.newInteger(counter), Py.newInteger(stepper))));
-            }
-
-        };
-    }
-
-    /**
-     * Creates an iterator that returns consecutive integers starting at <code>init</code>.
-     */
-    public static PyIterator count(final int init) {
-        return count(init, 1);
-    }
-
-    /**
-     * Creates an iterator that returns consecutive integers starting at 0.
-     */
-    public static PyIterator count() {
-        return itertools.count(0);
-    }
-
-
-    public static PyString __doc__cycle = new PyString(
-            "cycle(iterable) --> cycle object\n\nReturn elements from the iterable "
-                    + "until itis exhausted.\nThen repeat the sequence indefinitely.");
-
-    /**
-     * Returns an iterator that iterates over an iterable, saving the values for each iteration.
-     * When the iterable is exhausted continues to iterate over the saved values indefinitely.
-     */
-    public static PyIterator cycle(final PyObject sequence) {
-        return new ItertoolsIterator() {
-            List<PyObject> saved = new ArrayList<PyObject>();
-            int counter = 0;
-            PyObject iter = sequence.__iter__();
-
-            boolean save = true;
-
-            public PyObject __iternext__() {
-                if (save) {
-                    PyObject obj = nextElement(iter);
-                    if (obj != null) {
-                        saved.add(obj);
-                        return obj;
-                    } else {
-                        save = false;
-                    }
-                }
-                if (saved.size() == 0) {
-                    return null;
-                }
-                
-                // pick element from saved List
-                if (counter >= saved.size()) {
-                    // start over again
-                    counter = 0;
-                }
-                return saved.get(counter++);
-            }
-
-        };
-    }
-    
-    public static PyString __doc__repeat = new PyString(
-            "'repeat(element [,times]) -> create an iterator which returns the element\n"
-                    + "for the specified number of times.  If not specified, returns the element\nendlessly.");
-
-    /**
-     * Creates an iterator that returns the same object the number of times given by
-     * <code>times</code>.
-     */
-    public static PyIterator repeat(final PyObject object, final int times) {
-        return new PyIterator() {
-            int counter = times;
-
-            public PyObject __iternext__() {
-                if (counter > 0) {
-                    counter--;
-                    return object;
-                }
-                return null;
-            }
-            
-            public int __len__() {
-               return times; 
-            }
-            
-            public PyString __repr__() {
-                return (PyString)(Py.newString("repeat(%r, %d)").
-                        __mod__(new PyTuple(object, Py.newInteger(counter))));
-            }
-        };
-    }
-
-    /**
-     * Creates an iterator that returns the same object over and over again.
-     */
-    public static PyIterator repeat(final PyObject object) {
-        return new PyIterator() {
-            public PyObject __iternext__() {
-                return object;
-            }
-                        
-            public PyString __repr__() {
-                return (PyString)(Py.newString("repeat(%r)").
-                        __mod__(new PyTuple(object)));
-            }
-        };
-    }
-
-    public static PyString __doc__imap = new PyString(
             "'map(func, *iterables) --> imap object\n\nMake an iterator that computes the "
                     + "function using arguments from\neach of the iterables.\tLike map() except that it returns\n"
                     + "an iterator instead of a list and that it stops when the shortest\niterable is exhausted "
                     + "instead of filling in None for shorter\niterables.");
 
+    public imap() {
+        super();
+    }
+
+    public imap(PyType subType) {
+        super(subType);
+    }
+
+    public imap(PyObject... args) {
+        super();
+        imap___init__(args);
+    }
+
+
     /**
      * Works as <code>__builtin__.map()</code> but returns an iterator instead of a list. (Code in
      * this method is based on __builtin__.map()).
      */
-    public static PyIterator imap(PyObject[] argstar) {
-        final int n = argstar.length - 1;
-        if (n < 1) {
+    @ExposedNew
+    @ExposedMethod
+    final void imap___init__(final PyObject[] args, String[] kwds) {
+        if (kwds.length > 0) {
+            throw Py.TypeError(String.format("imap does not take keyword arguments"));
+        }
+        imap___init__(args);
+    }
+
+    private void imap___init__(final PyObject[] argstar) {
+        if (argstar.length < 2) {
             throw Py.TypeError("imap requires at least two arguments");
         }
+        final int n = argstar.length - 1;
+        final PyObject func = argstar[0];
 
-        final PyObject callable = argstar[0];
-        final PyObject[] iters = new PyObject[n];
-
+        final PyObject[] iterables = new PyObject[n];
         for (int j = 0; j < n; j++) {
-            iters[j] = Py.iter(argstar[j + 1], "argument " + (j + 1)
+            iterables[j] = Py.iter(argstar[j + 1], "argument " + (j + 1)
                     + " to imap() must support iteration");
         }
-
-        return new PyIterator() {
+        iter = new PyIterator() {
             PyObject[] args = new PyObject[n];
 
             PyObject element = null;
@@ -259,16 +76,16 @@
             public PyObject __iternext__() {
 
                 for (int i = 0; i < n; i++) {
-                    if ((element = iters[i].__iternext__()) != null) {
-                        // collect the arguments for the callable
+                    if ((element = iterables[i].__iternext__()) != null) {
+                        // collect the arguments for the func
                         args[i] = element;
                     } else {
                         // break iteration
                         return null;
                     }
                 }
-                if (callable == Py.None) {
-                    // if None is supplied as callable we just return what's in
+                if (func == Py.None) {
+                    // if None is supplied as func we just return what's in
                     // the iterable(s)
                     if (n == 1) {
                         return args[0];
@@ -276,704 +93,19 @@
                         return new PyTuple(args.clone());
                     }
                 } else {
-                    return callable.__call__(args);
+                    return func.__call__(args);
                 }
             }
         };
     }
 
-    public static PyString __doc__islice = new PyString(
-            "islice(iterable, [start,] stop [, step]) --> islice object\n"
-                    + "\nReturn an iterator whose next() method returns selected values from an\n"
-                    + "iterable.  If start is specified, will skip all preceding elements;\notherwise, start defaults to zero."
-                    + "Step defaults to one.  If\nspecified as another value, step determines how manyvalues are \n"
-                    + "skipped between successive calls.  Works like a slice() on a list\nbut returns an iterator.");
-
-    
-    private static int py2int(PyObject obj, int defaultValue, String msg) {
-        if (obj instanceof PyNone) {
-            return defaultValue;
-        } else {
-            int value = defaultValue;
-            try {
-                value = Py.py2int(obj);
-            }
-            catch (PyException pyEx) {
-                if (pyEx.match(Py.TypeError)) {
-                    throw Py.ValueError(msg);
-                } else {
-                    throw pyEx;
-                }
-            }
-            return value;
-        }
-    }
-    /**
-     * Creates an iterator that returns selected values from an iterable.
-     * 
-     * @param startObj
-     *            the index of where in the iterable to start returning values
-     * @param stopObj
-     *            the index of where in the iterable to stop returning values
-     * @param stepObj
-     *            the number of steps to take beween each call to <code>next()</code>
-     */
-    public static PyIterator islice(final PyObject iterable, PyObject startObj,
-            PyObject stopObj, PyObject stepObj) {
-        final int stop = py2int(stopObj, 0, "Stop argument must be a non-negative integer or None");
-        final int start = py2int(startObj, 0, "Start argument must be a non-negative integer or None");
-        final int step = py2int(stepObj, 1, "Step argument must be a non-negative integer or None");
-        final boolean stopNone = stopObj instanceof PyNone;
-
-        if (start < 0 || step < 0 || stop < 0) {
-            throw Py.ValueError("Indices for islice() must be non-negative integers");
-        }
-
-        if (step == 0) {
-            throw Py.ValueError("Step must be one or larger for islice()");
-        }
-
-        return new ItertoolsIterator() {
-            int counter = start;
-
-            int lastCount = 0;
-
-            PyObject iter = iterable.__iter__();
-
-            public PyObject __iternext__() {
-                PyObject result = null;
-
-                if (counter >= stop && !stopNone) {
-                    return null;
-                }
-
-                while (lastCount <= counter) {
-                    result = nextElement(iter);
-                    lastCount++;
-                }
-                counter += step;
-                return result;
-            }
-
-        };
-
+    @ExposedMethod
+    public PyObject __iter__() {
+        return iter;
     }
 
-    /**
-     * @see #islice(PyObject, PyObject, PyObject, PyObject) startObj defaults to 0 and stepObj to 1
-     */
-    public static PyIterator islice(PyObject iterable, PyObject stopObj) {
-        return islice(iterable, new PyInteger(0), stopObj, new PyInteger(1));
+    @ExposedMethod
+    public PyObject next() {
+        return iter.next();
     }
-
-    /**
-     * @see #islice(PyObject, PyObject, PyObject, PyObject) stepObj defaults to 1
-     */
-    public static PyIterator islice(PyObject iterable, PyObject start,
-            PyObject stopObj) {
-        return islice(iterable, start, stopObj, new PyInteger(1));
-    }
-
-    /**
-     * Iterator base class for iterators returned by <code>ifilter</code> and
-     * <code>ifilterfalse</code>.
-     */
-    static class FilterIterator extends ItertoolsIterator {
-        private PyObject predicate;
-
-        private PyObject iterator;
-
-        private boolean filterTrue;
-
-        FilterIterator(PyObject predicate, PyObject iterable, boolean filterTrue) {
-            if (predicate instanceof PyNone) {
-                this.predicate = null;
-            } else {
-                this.predicate = predicate;
-            }
-            this.iterator = iterable.__iter__();
-            this.filterTrue = filterTrue;
-        }
-
-        public PyObject __iternext__() {
-
-            while (true) {
-                PyObject element = nextElement(iterator);
-                if (element != null) {
-                    // the boolean value of calling predicate with the element
-                    // or if predicate is null/None of the element itself
-                    boolean booleanValue = predicate != null ? predicate
-                            .__call__(element).__nonzero__() : element
-                            .__nonzero__();
-                    if (booleanValue == filterTrue) {
-                        // if the boolean value is the same as filterTrue return
-                        // the element
-                        // for ifilter filterTrue is always true, for
-                        // ifilterfalse always false
-                        return element;
-                    }
-                } else {
-                    return null;
-                }
-            }
-        }
-    }
-
-    public static PyString __doc__ifilter = new PyString(
-            "ifilter(function or None, sequence) --> ifilter object\n\n"
-                    + "Return those items of sequence for which function(item) is true.\nIf function is None, "
-                    + "return the items that are true.");
-
-    /**
-     * Creates an iterator that returns the items of the iterable for which
-     * <code>predicate(item)</code> is <code>true</code>. If <code>predicate</code> is null
-     * (None) return the items that are true.
-     */
-    public static PyIterator ifilter(PyObject predicate, PyObject iterable) {
-        return new FilterIterator(predicate, iterable, true);
-    }
-
-    public static PyString __doc__ifilterfalse = new PyString(
-            "'ifilterfalse(function or None, sequence) --> ifilterfalse object\n\n"
-                    + "Return those items of sequence for which function(item) is false.\nIf function is None, "
-                    + "return the items that are false.'");
-
-    /**
-     * Creates an iterator that returns the items of the iterable for which
-     * <code>predicate(item)</code> is <code>false</code>. If <code>predicate</code> is null
-     * (None) return the items that are false.
-     */
-    public static PyIterator ifilterfalse(PyObject predicate, PyObject iterable) {
-        return new FilterIterator(predicate, iterable, false);
-    }
-
-    public static PyString __doc__izip = new PyString(
-            "izip(iter1 [,iter2 [...]]) --> izip object\n\nReturn an izip object "
-                    + "whose .next() method returns a tuple where\nthe i-th element comes from the i-th iterable argument.  "
-                    + "The .next()\nmethod continues until the shortest iterable in the argument sequence\nis exhausted and then it "
-                    + "raises StopIteration.  Works like the zip()\nfunction but consumes less memory by returning an iterator "
-                    + "instead of\na list.");
-
-    /**
-     * Create an iterator whose <code>next()</code> method returns a tuple where the i-th element
-     * comes from the i-th iterable argument. Continues until the shortest iterable is exhausted.
-     * (Code in this method is based on __builtin__.zip()).
-     * 
-     */
-    public static PyIterator izip(PyObject[] argstar) {
-        final int itemsize = argstar.length;
-        
-        if (itemsize == 0) {
-            return (PyIterator)(new PyXRange(0).__iter__());            
-        }
-
-        // Type check the arguments; they must be sequences.
-        final PyObject[] iters = new PyObject[itemsize];
-
-        for (int i = 0; i < itemsize; i++) {
-            PyObject iter = argstar[i].__iter__();
-            if (iter == null) {
-                throw Py.TypeError("izip argument #" + (i + 1)
-                        + " must support iteration");
-            }
-            iters[i] = iter;
-        }
-
-        return new ItertoolsIterator() {
-
-            public PyObject __iternext__() {
-                if (itemsize == 0)
-                    return null;
-
-                PyObject[] next = new PyObject[itemsize];
-                PyObject item;
-
-                for (int i = 0; i < itemsize; i++) {
-
-                    item = nextElement(iters[i]);
-
-                    if (item == null) {
-                        return null;
-                    }
-                    next[i] = item;
-                }
-                return new PyTuple(next);
-            }
-
-        };
-
-    }
-
-    public static PyString __doc__starmap = new PyString(
-            "starmap(function, sequence) --> starmap object\n\nReturn an "
-                    + "iterator whose values are returned from the function evaluated\nwith an argument tuple taken from the "
-                    + "given sequence.");
-
-    /**
-     * Create an iterator whose <code>next()</code> method returns the result
-     * of calling the function (first argument) with a tuple of arguments
-     * returned from the iterable (second argument).
-     * 
-     * @param starargs
-     *            [0] = callable function, [1] = iterable with argument tuples
-     */
-    public static PyIterator starmap(PyObject[] starargs) {
-        if (starargs.length != 2) {
-            throw Py.TypeError("starmap requires 2 arguments, got "
-                    + starargs.length);
-        }
-        final PyObject callable = starargs[0];
-        final PyObject iterator = starargs[1].__iter__();
-
-        return new ItertoolsIterator() {
-
-            public PyObject __iternext__() {
-                PyObject args = nextElement(iterator);
-                PyObject result = null;
-
-                if (args != null) {
-                    if (!args.getClass().isAssignableFrom(PyTuple.class)) {
-                        throw Py.TypeError("iterator must return a tuple");
-                    }
-                    PyTuple argTuple = (PyTuple) args;
-                    // convert to array of PyObjects in call to function
-                    result = callable.__call__(argTuple.getArray());
-                }
-                return result;
-            }
-
-        };
-    }
-
-    /**
-     * Iterator base class used by <code>dropwhile()</code> and <code>takewhile</code>.
-     */
-    static class WhileIterator extends ItertoolsIterator {
-        private PyObject iterator;
-
-        private PyObject predicate;
-
-        // flag that indicates if the iterator shoul drop or return arguments "while" the predicate is true
-        private boolean drop;
-
-        // flag that is set once the predicate is satisfied
-        private boolean predicateSatisfied;
-
-        WhileIterator(PyObject predicate, PyObject iterable, boolean drop) {
-            this.predicate = predicate;
-            iterator = iterable.__iter__();
-            this.drop = drop;
-        }
-
-        public PyObject __iternext__() {
-
-            while (true) {
-                PyObject element = nextElement(iterator);
-                if (element != null) {
-                    if (!predicateSatisfied) {
-                        // the predicate is not satisfied yet (or still satisfied in the case of drop beeing 
-                        // false), so we need to check it
-                        if (predicate.__call__(element).__nonzero__() != drop) {
-                            predicateSatisfied = drop;
-                            return element;
-                        }
-                        predicateSatisfied = !drop;
-                    } else {
-                        if (drop) {
-                            return element;
-                        } else {
-                            // end iteration if predicate is false and drop is false
-                            return null;
-                        }
-                    }
-                } else {
-                    // end iteration
-                    return null;
-                }
-
-            }
-        }
-    }
-
-    public static PyString __doc__dropwhile = new PyString(
-            "dropwhile(predicate, iterable) --> dropwhile object\n\nDrop items "
-                    + "from the iterable while predicate(item) is true.\nAfterwards, return every element until theiterable is exhausted.");
-
-    /**
-     * Create an iterator that drops items from the iterable while <code>prdicate(item)</code>
-     * equals true. After which every remaining item of the iterable is returned.
-     */
-    public static PyIterator dropwhile(PyObject predicate, PyObject iterable) {
-        return new WhileIterator(predicate, iterable, true);
-    }
-
-    public static PyString __doc__takewhile = new PyString(
-            "takewhile(predicate, iterable) --> takewhile object\n\nReturn "
-                    + "successive entries from an iterable as long as the \npredicate evaluates to true for each entry.");
-
-    /**
-     * Create an iterator that returns items from the iterable while <code>predicate(item)</code>
-     * is true. After which iteration is stopped.
-     */
-    public static PyIterator takewhile(PyObject predicate, PyObject iterable) {
-        return new WhileIterator(predicate, iterable, false);
-    }
-
-    private final static class GroupBy extends ItertoolsIterator {
-
-        private final PyObject iterator;
-        private final PyObject keyFunc;
-        private PyObject currentKey;
-        private PyObject currentValue;
-        private PyObject targetKey;
-
-        private GroupBy(PyObject iterable, PyObject key) {
-            iterator = iterable.__iter__();
-            keyFunc = key;
-            targetKey = currentKey = currentValue = new PyXRange(0);
-        }
-
-        public PyObject __iternext__() {
-            while (currentKey.equals(targetKey)) {
-                currentValue = nextElement(iterator);
-                if (currentValue == null) {
-                    return null;
-                }
-                if (keyFunc == null) {
-                    currentKey = currentValue;
-                } else {
-                    currentKey = keyFunc.__call__(currentValue);
-                }
-            }
-            targetKey = currentKey;
-            return new PyTuple(currentKey, new GroupByIterator());
-        }
-
-        private class GroupByIterator extends ItertoolsIterator {
-
-            private boolean completed = false;
-
-            public PyObject __iternext__() {
-                final PyObject item = currentValue;
-                if (completed) {
-                    return null;
-                }
-                currentValue = nextElement(iterator);
-                if (currentValue == null) {
-                    completed = true;
-                } else {
-                    if (keyFunc == null) {
-                        currentKey = currentValue;
-                    } else {
-                        currentKey = keyFunc.__call__(currentValue);
-                    }
-                }
-                if (!currentKey.equals(targetKey)) {
-                    completed = true;
-                }
-                return item;
-            }
-        }
-    }
-
-    public static PyString __doc__groupby = new PyString(
-            "groupby(iterable[, keyfunc]) -> create an iterator which returns\n" +
-            "(key, sub-iterator) grouped by each value of key(value).");
-
-    /**
-     * Create an iterator which returns the pair (key, sub-iterator) grouped by key(value).
-     */
-    public static PyIterator groupby(PyObject [] args, String [] kws) {
-        ArgParser ap = new ArgParser("groupby", args, kws, "iterable", "key");
-        if(args.length > 2){
-            throw Py.TypeError("groupby takes two arguments, iterable and key");
-        }
-        PyObject iterable = ap.getPyObject(0);
-        PyObject key = ap.getPyObject(1, null);
-        return new GroupBy(iterable, key);
-    }
-    
-    public static PyString __doc__tee = new PyString(
-            "tee(iterable, n=2) --> tuple of n independent iterators.");
-
-    /**
-     * Create a tuple of iterators, each of which is effectively a copy of iterable.
-     */
-    public static PyTuple tee(PyObject iterable, final int n) {
-        return new PyTuple(PyTeeIterator.makeTees(iterable, n));
-    }
-
-    /**
-     * Create a pair of iterators, each of which is effectively a copy of iterable.
-     */
-    public static PyTuple tee(PyObject iterable) {
-        return tee(iterable, 2);
-    }
-
-    private static PyTuple makeIndexedTuple(PyTuple pool, int indices[]) {
-        return makeIndexedTuple(pool, indices, indices.length);
-    }
-    
-    private static PyTuple makeIndexedTuple(PyTuple pool, int indices[], int end) {
-        PyObject items[] = new PyObject[end];
-        for (int i = 0; i < end; i++) {
-            items[i] = pool.__getitem__(indices[i]);
-        }
-        return new PyTuple(items);
-    }
-    
-    public static PyIterator combinations(PyObject iterable, final int r) {
-        if (r < 0) throw Py.ValueError("r must be non-negative");
-        final PyTuple pool = PyTuple.fromIterable(iterable);
-        final int n = pool.__len__();
-        final int indices[] = new int[r];
-        for (int i = 0; i < r; i++) {
-            indices[i] = i;
-        }
-
-        return new ItertoolsIterator() {
-            boolean firstthru = true;
-
-            @Override
-            public PyObject __iternext__() {
-                if (r > n) { return null; }
-                if (firstthru) {
-                    firstthru = false;
-                    return makeIndexedTuple(pool, indices);
-                }
-                int i;
-                for (i = r-1; i >= 0 && indices[i] == i+n-r ; i--);
-                if (i < 0) return null;
-                indices[i]++;
-                for (int j = i+1; j < r; j++) {
-                    indices[j] = indices[j-1] + 1;
-                }
-                return makeIndexedTuple(pool, indices);
-            }
-            
-
-        };
-    }
-
-    public static PyIterator combinations_with_replacement(PyObject iterable, final int r) {
-        final PyTuple pool = PyTuple.fromIterable(iterable);
-        final int n = pool.__len__();
-        final int indices[] = new int[r];
-        for (int i = 0; i < r; i++) {
-            indices[i] = 0;
-        }
-
-        return new ItertoolsIterator() {
-            boolean firstthru = true;
-
-            @Override
-            public PyObject __iternext__() {
-                if (n == 0 || r == 0) {
-                    return null;
-                }
-                if (firstthru) {
-                    firstthru = false;
-                    return makeIndexedTuple(pool, indices);
-                }
-                int i;
-                for (i= r - 1 ; i >= 0 && indices[i] == n - 1; i--);
-                if (i < 0) return null;
-                indices[i]++;
-                for (int j = i + 1; j < r; j++) {
-                    indices[j] = indices[j-1];
-                }
-                return makeIndexedTuple(pool, indices);
-            }
-        };
-    }
-
-    public static PyString __doc__compress = new PyString(
-        "compress(data, selectors) --> iterator over selected data\n\n" +
-        "Return data elements corresponding to true selector elements.\n" +
-        "Forms a shorter iterator from selected data elements using the\n" +
-        "selectors to choose the data elements.");
-    
-    public static PyIterator compress(PyObject [] args, String [] kws) {
-        ArgParser ap = new ArgParser("compress", args, kws, "data", "selectors");
-        if (args.length > 2) {
-            throw Py.TypeError(String.format("compress() takes at most 2 arguments (%s given)", args.length));
-        }
-        final PyObject data = ap.getPyObject(0).__iter__();
-        final PyObject selectors = ap.getPyObject(1, null).__iter__();
-
-        return new ItertoolsIterator() {
-
-            @Override
-            public PyObject __iternext__() {
-                while (true) {
-                    PyObject datum = nextElement(data);
-                    if (datum == null) { return null; }
-                    PyObject selector = nextElement(selectors);
-                    if (selector == null) { return null; }
-                    if (selector.__nonzero__()) {
-                        return datum;
-                        }
-                }
-            }
-            public PyString __repr__() {
-                return new PyString(String.format("itertools.compress object at 0x%x", Py.id(this)));
-            }
-
-        };
-    }
-
-    public static PyIterator izip_longest(PyObject[] args, String[] kws) {
-        final int num_iterables;
-        final PyObject fillvalue;
-        if (kws.length == 1 && kws[0] == "fillvalue") {
-            fillvalue = args[args.length - 1];
-            num_iterables = args.length - 1;
-        } else {
-            fillvalue = Py.None;
-            num_iterables = args.length;
-        }
-
-        //XXX error checking on args
-        final PyObject iterators[] = new PyObject[num_iterables];
-        final boolean exhausted[] = new boolean[num_iterables];
-        for (int i = 0; i < num_iterables; i++) {
-            iterators[i] = args[i].__iter__();
-            exhausted[i] = false;
-        }
-
-        return new ItertoolsIterator() {
-            int unexhausted = num_iterables;
-
-            @Override
-            public PyObject __iternext__() {
-                PyObject item[] = new PyObject[num_iterables];
-                for (int i = 0; i < num_iterables; i++) {
-                    if (exhausted[i]) {
-                        item[i] = fillvalue;
-                    } else {
-                        PyObject elem = iterators[i].__iternext__();
-                        if (elem == null) {
-                            unexhausted--;
-                            exhausted[i] = true;
-                            item[i] = fillvalue;
-                        } else {
-                            item[i] = elem;
-                        }
-                    }
-                }
-                if (unexhausted == 0) {
-                    return null;
-                } else {
-                    return new PyTuple(item);
-                }
-            }
-        };
-    }
-
-    public static PyIterator permutations(PyObject iterable, final int r) {
-        //XXX keyword args support
-        if (r < 0) throw Py.ValueError("r must be non-negative");
-        final PyTuple pool = PyTuple.fromIterable(iterable);
-        final int n = pool.__len__();
-        final int indices[] = new int[n];
-        for (int i = 0; i < n; i++) {
-            indices[i] = i;
-        }
-        final int cycles[] = new int[r];
-        for (int i = 0; i < r; i++) {
-            cycles[i] = n - i;
-        }
-
-        return new ItertoolsIterator() {
-            boolean firstthru = true;
-
-            @Override
-            public PyObject __iternext__() {
-                if (r > n) return null;
-                if (firstthru) {
-                    firstthru = false;
-                    return makeIndexedTuple(pool, indices, r);
-                }
-                for (int i = r - 1; i >= 0; i--) {
-                    cycles[i] -= 1;
-                    if (cycles[i] == 0) {
-                        // rotate indices at the ith position
-                        int first = indices[i];
-                        for (int j = i; j < n - 1; j++) {
-                            indices[j] = indices[j + 1];
-                        }
-                        indices[n - 1] = first;
-                        cycles[i] = n - i;
-                    } else {
-                        int j = cycles[i];
-                        int index = indices[i];
-                        indices[i] = indices[n - j];
-                        indices[n - j] = index;
-                        return makeIndexedTuple(pool, indices, r);
-                    }
-                }
-                return null;
-            }
-        };
-    }
-
-    public static PyIterator product(PyObject [] args, String [] kws) {
-        final int repeat;
-        final int num_iterables;
-        if (kws.length == 1 && kws[0] == "repeat") {
-            repeat = args[args.length -1].asInt();
-            num_iterables = args.length - 1;
-        } else {
-            repeat = 1;
-            num_iterables = args.length;
-        }
-        // XXX error checking on args! XXX
-        final int num_pools = num_iterables * repeat;
-        final PyTuple pools[] = new PyTuple[num_pools];
-        for (int i = 0; i < num_iterables; i++) {
-            pools[i] = PyTuple.fromIterable(args[i]);
-        }
-        // Make repeat - 1 duplicates, in order
-        for (int r = 1; r < repeat; r++) {
-            for (int i = 0; i < num_iterables; i++) {
-                pools[r * num_iterables + i] = pools[i];
-            }
-        }
-        final int indices[] = new int[num_pools];
-        for (int i = 0; i < num_pools; i++) {
-            indices[i] = 0;
-        }
-
-        return new ItertoolsIterator() {
-            boolean firstthru = true;
-
-            @Override
-            public PyObject __iternext__() {
-                if (firstthru) {
-                    firstthru = false;
-                    return makeTuple();
-                }
-                for (int i = num_pools - 1; i >= 0; i--) {
-                    indices[i]++;
-
-                    if (indices[i] == pools[i].__len__()) {
-                        indices[i] = 0;
-                    } else {
-                        return makeTuple();         
-                    }
-                }
-                return null;
-            }
-
-            private PyTuple makeTuple() {
-                PyObject items[] = new PyObject[num_pools];
-                for (int i = 0; i < num_pools; i++) {
-                    items[i] = pools[i].__getitem__(indices[i]);
-                }
-                return new PyTuple(items);
-            }
-
-        };
-    }
-
 }
diff --git a/src/org/python/modules/itertools/itertools.java b/src/org/python/modules/itertools/itertools.java
--- a/src/org/python/modules/itertools/itertools.java
+++ b/src/org/python/modules/itertools/itertools.java
@@ -83,6 +83,7 @@
         dict.__setitem__("__name__", new PyString("itertools"));
         dict.__setitem__("__doc__", __doc__);
         dict.__setitem__("chain", chain.TYPE);
+        dict.__setitem__("imap", imap.TYPE);
 
         // Hide from Python
         dict.__setitem__("classDictInit", null);
@@ -227,61 +228,6 @@
         };
     }
 
-    public static PyString __doc__imap = new PyString(
-            "'map(func, *iterables) --> imap object\n\nMake an iterator that computes the "
-                    + "function using arguments from\neach of the iterables.\tLike map() except that it returns\n"
-                    + "an iterator instead of a list and that it stops when the shortest\niterable is exhausted "
-                    + "instead of filling in None for shorter\niterables.");
-
-    /**
-     * Works as <code>__builtin__.map()</code> but returns an iterator instead of a list. (Code in
-     * this method is based on __builtin__.map()).
-     */
-    public static PyIterator imap(PyObject[] argstar) {
-        final int n = argstar.length - 1;
-        if (n < 1) {
-            throw Py.TypeError("imap requires at least two arguments");
-        }
-
-        final PyObject callable = argstar[0];
-        final PyObject[] iters = new PyObject[n];
-
-        for (int j = 0; j < n; j++) {
-            iters[j] = Py.iter(argstar[j + 1], "argument " + (j + 1)
-                    + " to imap() must support iteration");
-        }
-
-        return new PyIterator() {
-            PyObject[] args = new PyObject[n];
-
-            PyObject element = null;
-
-            public PyObject __iternext__() {
-
-                for (int i = 0; i < n; i++) {
-                    if ((element = iters[i].__iternext__()) != null) {
-                        // collect the arguments for the callable
-                        args[i] = element;
-                    } else {
-                        // break iteration
-                        return null;
-                    }
-                }
-                if (callable == Py.None) {
-                    // if None is supplied as callable we just return what's in
-                    // the iterable(s)
-                    if (n == 1) {
-                        return args[0];
-                    } else {
-                        return new PyTuple(args.clone());
-                    }
-                } else {
-                    return callable.__call__(args);
-                }
-            }
-        };
-    }
-
     public static PyString __doc__islice = new PyString(
             "islice(iterable, [start,] stop [, step]) --> islice object\n"
                     + "\nReturn an iterator whose next() method returns selected values from an\n"

-- 
Repository URL: http://hg.python.org/jython


More information about the Jython-checkins mailing list