[pypy-svn] pypy default: Merge heads, including manually merging interp_itertools.py.

arigo commits-noreply at bitbucket.org
Tue Jan 25 17:48:07 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r41312:d2060664e908
Date: 2011-01-25 17:47 +0100
http://bitbucket.org/pypy/pypy/changeset/d2060664e908/

Log:	Merge heads, including manually merging interp_itertools.py.

diff --git a/pypy/module/itertools/test/test_itertools.py b/pypy/module/itertools/test/test_itertools.py
--- a/pypy/module/itertools/test/test_itertools.py
+++ b/pypy/module/itertools/test/test_itertools.py
@@ -1,6 +1,7 @@
 import py
 from pypy.conftest import gettestobjspace
 
+
 class AppTestItertools: 
     def setup_class(cls):
         cls.space = gettestobjspace(usemodules=['itertools'])
@@ -26,6 +27,8 @@
         assert repr(it) == 'count(123)'
         it.next()
         assert repr(it) == 'count(124)'
+        it = itertools.count(12.1, 1.0)
+        assert repr(it) == 'count(12.1, 1.0)'
 
     def test_repeat(self):
         import itertools
@@ -727,7 +730,10 @@
         m = ['a', 'b']
 
         prodlist = product(l, m)
-        assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
+        res = [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
+        assert list(prodlist) == res
+        assert list(product([])) == []
+        assert list(product(iter(l), iter(m))) == res
 
         prodlist = product(iter(l), iter(m))
         assert list(prodlist) == [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
@@ -805,6 +811,29 @@
         assert list(permutations([], 0)) == [()]
         assert list(permutations([], 1)) == []
         assert list(permutations(range(3), 4)) == []
+        #
+        perm = list(permutations([1, 2, 3, 4]))
+        assert perm == [(1, 2, 3, 4), (1, 2, 4, 3), (1, 3, 2, 4), (1, 3, 4, 2),
+                        (1, 4, 2, 3), (1, 4, 3, 2), (2, 1, 3, 4), (2, 1, 4, 3),
+                        (2, 3, 1, 4), (2, 3, 4, 1), (2, 4, 1, 3), (2, 4, 3, 1),
+                        (3, 1, 2, 4), (3, 1, 4, 2), (3, 2, 1, 4), (3, 2, 4, 1),
+                        (3, 4, 1, 2), (3, 4, 2, 1), (4, 1, 2, 3), (4, 1, 3, 2),
+                        (4, 2, 1, 3), (4, 2, 3, 1), (4, 3, 1, 2), (4, 3, 2, 1)]
+
+    def test_permutations_r(self):
+        from itertools import permutations
+        perm = list(permutations([1, 2, 3, 4], 2))
+        assert perm == [(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1),
+                       (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)]
+
+    def test_permutations_r_gt_n(self):
+        from itertools import permutations
+        perm = permutations([1, 2], 3)
+        raises(StopIteration, perm.next)
+
+    def test_permutations_neg_r(self):
+        from itertools import permutations
+        raises(ValueError, permutations, [1, 2], -1)
 
 
 class AppTestItertools27:

diff --git a/pypy/module/itertools/interp_itertools.py b/pypy/module/itertools/interp_itertools.py
--- a/pypy/module/itertools/interp_itertools.py
+++ b/pypy/module/itertools/interp_itertools.py
@@ -23,7 +23,8 @@
     def repr_w(self):
         space = self.space
         c = space.str_w(space.repr(self.w_c))
-        if space.eq_w(self.w_step, space.wrap(1)):
+        if (space.isinstance_w(self.w_step, space.w_int) and
+            space.eq_w(self.w_step, space.wrap(1))):
             s = 'count(%s)' % (c,)
         else:
             step = space.str_w(space.repr(self.w_step))
@@ -1033,14 +1034,16 @@
 
 
 class W_Product(Wrappable):
-
     def __init__(self, space, args_w, w_repeat):
-        self.space = space
-        args = [space.fixedview(w_arg) for w_arg in args_w]
-        self.gears = args * space.int_w(w_repeat)
+        self.gears = [
+            space.fixedview(arg_w) for arg_w in args_w
+        ] * space.int_w(w_repeat)
         self.num_gears = len(self.gears)
         # initialization of indicies to loop over
-        self.indicies = [(0, len(gear)) for gear in self.gears]
+        self.indicies = [
+            (0, len(gear))
+            for gear in self.gears
+        ]
         self.cont = True
         for _, lim in self.indicies:
             if lim <= 0:
@@ -1072,19 +1075,20 @@
             else:
                 break
 
-    def iter_w(self):
-        return self.space.wrap(self)
+    @unwrap_spec("self", ObjSpace)
+    def iter_w(self, space):
+        return space.wrap(self)
 
-    def next_w(self):
+    @unwrap_spec("self", ObjSpace)
+    def next_w(self, space):
         if not self.cont:
-            raise OperationError(self.space.w_StopIteration,
-                                     self.space.w_None)
+            raise OperationError(space.w_StopIteration, space.w_None)
         l = [None] * self.num_gears
         for x in range(0, self.num_gears):
             index, limit = self.indicies[x]
             l[x] = self.gears[x][index]
         self.roll_gears()
-        return self.space.newtuple(l)
+        return space.newtuple(l)
 
 
 @unwrap_spec(ObjSpace, W_Root, Arguments)
@@ -1106,8 +1110,8 @@
 W_Product.typedef = TypeDef(
     'product',
     __new__ = interp2app(W_Product__new__),
-    __iter__ = interp2app(W_Product.iter_w, unwrap_spec=['self']),
-    next = interp2app(W_Product.next_w, unwrap_spec=['self']),
+    __iter__ = interp2app(W_Product.iter_w),
+    next = interp2app(W_Product.next_w),
     __doc__ = """
    Cartesian product of input iterables.
 
@@ -1137,6 +1141,69 @@
                yield tuple(prod)
 """)
 
+
+class W_Permutations(Wrappable):
+    def __init__(self, space, iterable_w, w_r):
+        self.space = space
+        self.pool_w = iterable_w[:]
+        self.n = n = len(self.pool_w)
+        self.r = r = n if space.is_w(w_r, space.w_None) else space.int_w(w_r)
+        if r < 0:
+            raise OperationError(self.space.w_ValueError,
+                                 self.space.wrap("r cannot be negative"))
+        self.indices = range(n)
+        self.cycles = range(n, n - r, -1)
+        self.first_run = True
+
+    def iter_w(self):
+        return self.space.wrap(self)
+
+    def next_w(self):
+        if self.r > self.n:
+            raise OperationError(self.space.w_StopIteration, self.space.w_None)
+        if self.first_run:
+            self.first_run = False
+        else:
+            # cargo-culted from python docs
+            for i in xrange(self.r - 1, -1, -1):
+                self.cycles[i] -= 1
+                if self.cycles[i] == 0:
+                    new_indices = self.indices[i + 1:] + self.indices[i:i + 1]
+                    for x in xrange(len(new_indices)):
+                        self.indices[i + x] = new_indices[x]
+                    self.cycles[i] = self.n - i
+                else:
+                    j = self.cycles[i]
+                    self.indices[i], self.indices[-j] = (self.indices[-j],
+                                                         self.indices[i])
+                    break
+            else:
+                raise OperationError(self.space.w_StopIteration,
+                                     self.space.w_None)
+        res_w = [self.pool_w[self.indices[x]] for x in range(self.r)]
+        return self.space.newtuple(res_w)
+
+
+def W_Permutations__new__(space, w_subtype, w_iterable, w_r=None):
+    iterable_w = space.listview(w_iterable)
+    return space.wrap(W_Permutations(space, iterable_w, w_r))
+
+
+W_Permutations.typedef = TypeDef(
+    'permutations',
+    __new__ = interp2app(W_Permutations__new__,
+                         unwrap_spec=[ObjSpace, W_Root, W_Root, W_Root]),
+    __iter__ = interp2app(W_Permutations.iter_w, unwrap_spec=['self']),
+    next = interp2app(W_Permutations.next_w, unwrap_spec=['self']),
+    __doc__ = """\
+permutations(iterable[, r]) --> permutations object
+
+Return successive r-length permutations of elements in the iterable.
+
+permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
+""")
+
+
 class W_Combinations(Wrappable):
     def __init__(self, space, pool_w, indices, r):
         self.pool_w = pool_w

diff --git a/pypy/translator/c/test/test_dtoa.py b/pypy/translator/c/test/test_dtoa.py
deleted file mode 100644
--- a/pypy/translator/c/test/test_dtoa.py
+++ /dev/null
@@ -1,92 +0,0 @@
-from __future__ import with_statement
-from pypy.translator.tool.cbuild import ExternalCompilationInfo
-from pypy.tool.autopath import pypydir
-from pypy.rpython.lltypesystem import lltype, rffi
-from pypy.rlib.rstring import StringBuilder
-import py
-
-includes = []
-libraries = []
-
-cdir = py.path.local(pypydir) / 'translator' / 'c'
-files = [cdir / 'src' / 'dtoa.c']
-include_dirs = [cdir]
-
-eci = ExternalCompilationInfo(
-    include_dirs = include_dirs,
-    libraries = libraries,
-    separate_module_files = files,
-    separate_module_sources = ['''
-        #include <stdlib.h>
-        #include <assert.h>
-        #define WITH_PYMALLOC
-        #include "src/obmalloc.c"
-    '''],
-    export_symbols = ['_Py_dg_strtod',
-                      '_Py_dg_dtoa',
-                      '_Py_dg_freedtoa',
-                      ],
-)
-
-dg_strtod = rffi.llexternal(
-    '_Py_dg_strtod', [rffi.CCHARP, rffi.CCHARPP], rffi.DOUBLE,
-    compilation_info=eci)
-
-dg_dtoa = rffi.llexternal(
-    '_Py_dg_dtoa', [rffi.DOUBLE, rffi.INT, rffi.INT,
-                    rffi.INTP, rffi.INTP, rffi.CCHARPP], rffi.CCHARP,
-    compilation_info=eci)
-
-dg_freedtoa = rffi.llexternal(
-    '_Py_dg_freedtoa', [rffi.CCHARP], lltype.Void,
-    compilation_info=eci)
-
-def strtod(input):
-    with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
-        with rffi.scoped_str2charp(input) as ll_input:
-            result = dg_strtod(ll_input, end_ptr)
-            if end_ptr[0] and ord(end_ptr[0][0]):
-                offset = (rffi.cast(rffi.LONG, end_ptr[0]) -
-                          rffi.cast(rffi.LONG, ll_input))
-                raise ValueError("invalid input at position %d" % (offset,))
-            return result
-
-def dtoa(value, mode=0, precision=0):
-    builder = StringBuilder(20)
-    with lltype.scoped_alloc(rffi.INTP.TO, 1) as decpt_ptr:
-        with lltype.scoped_alloc(rffi.INTP.TO, 1) as sign_ptr:
-            with lltype.scoped_alloc(rffi.CCHARPP.TO, 1) as end_ptr:
-                output_ptr = dg_dtoa(value, mode, precision,
-                                     decpt_ptr, sign_ptr, end_ptr)
-                try:
-                    buflen = (rffi.cast(rffi.LONG, end_ptr[0]) -
-                              rffi.cast(rffi.LONG, output_ptr))
-                    intpart = rffi.cast(lltype.Signed, decpt_ptr[0])
-                    if intpart <= buflen:
-                        builder.append(rffi.charpsize2str(output_ptr, intpart))
-                    else:
-                        builder.append(rffi.charpsize2str(output_ptr, buflen))
-                        while buflen < intpart:
-                            builder.append('0')
-                            intpart -= 1
-                    builder.append('.')
-                    fracpart = buflen - intpart
-                    if fracpart > 0:
-                        ptr = rffi.ptradd(output_ptr, intpart)
-                        builder.append(rffi.charpsize2str(ptr, fracpart))
-                finally:
-                    dg_freedtoa(output_ptr)
-    return builder.build()
-
-def test_strtod():
-    assert strtod("12345") == 12345.0
-    assert strtod("1.1") == 1.1
-    assert strtod("3.47") == 3.47
-    raises(ValueError, strtod, "123A")
-
-def test_dtoa():
-    assert dtoa(3.47) == "3.47"
-    assert dtoa(1.1) == "1.1"
-    assert dtoa(12.3577) == "12.3577"
-    assert dtoa(10) == "10."
-    assert dtoa(1e100) == "1" + "0" * 100 + "."


More information about the Pypy-commit mailing list