[pypy-svn] r56253 - in pypy/dist/pypy/module/__builtin__: . test

arigo at codespeak.net arigo at codespeak.net
Thu Jul 3 11:47:01 CEST 2008


Author: arigo
Date: Thu Jul  3 11:46:50 2008
New Revision: 56253

Modified:
   pypy/dist/pypy/module/__builtin__/app_functional.py
   pypy/dist/pypy/module/__builtin__/test/test_functional.py
Log:
issue360 resolved

Adapt filter() to use exactly the same logic as CPython.


Modified: pypy/dist/pypy/module/__builtin__/app_functional.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/app_functional.py	(original)
+++ pypy/dist/pypy/module/__builtin__/app_functional.py	Thu Jul  3 11:46:50 2008
@@ -68,37 +68,43 @@
         else:
             return res
 
+def filterstring(function, collection, str_type):
+    if function is None and type(collection) is str_type:
+        return collection
+    res = []
+    for i in xrange(len(collection)):
+        c = collection[i]
+        if function is None or function(c):
+            if not isinstance(c, str_type):
+                raise TypeError("can't filter %s to %s: __getitem__ returned different type", str_type.__name__, str_type.__name__)
+            res.append(c)
+    return str_type().join(res)
+
+def filtertuple(function, collection):
+    if function is None:
+        function = bool
+    res = []
+    for i in xrange(len(collection)):
+        c = collection[i]
+        if function(c):
+            res.append(c)
+    return tuple(res)
+
 def filter(function, collection):
     """construct a list of those elements of collection for which function
        is True.  If function is None, then return the items in the sequence
        which are True."""
-    str_type = None
     if isinstance(collection, str):
-        str_type = str
+        return filterstring(function, collection, str)
     elif isinstance(collection, unicode):
-        str_type = unicode
+        return filterstring(function, collection, unicode)
+    elif isinstance(collection, tuple):
+        return filtertuple(function, collection)
 
-    if str_type is not None:
-        if function is None and type(collection) is str_type:
-            return collection
-        res = []
-        for i in xrange(len(collection)):
-            c = collection[i]
-            if function is None or function(c):
-                if not isinstance(c, str_type):
-                    raise TypeError("can't filter %s to %s: __getitem__ returned different type", str_type.__name__, str_type.__name__)
-                res.append(c)
-        return str_type('').join(res) #added '' to make the annotator happy
-        
     if function is None:
-        res = [item for item in collection if item]
-    else:
-        res = [item for item in collection if function(item)]
-
-    if isinstance(collection, tuple):
-       return tuple(res)
+        return [item for item in collection if item]
     else:
-       return res
+        return [item for item in collection if function(item)]
 
 def zip(*collections):
     """return a list of tuples, where the nth tuple contains every

Modified: pypy/dist/pypy/module/__builtin__/test/test_functional.py
==============================================================================
--- pypy/dist/pypy/module/__builtin__/test/test_functional.py	(original)
+++ pypy/dist/pypy/module/__builtin__/test/test_functional.py	Thu Jul  3 11:46:50 2008
@@ -89,6 +89,13 @@
 
    def test_function(self):
        assert filter(lambda x: x != "a", "a small text") == " smll text"
+       assert filter(lambda x: x < 20, [3, 33, 5, 55]) == [3, 5]
+
+   def test_filter_tuple_calls_getitem(self):
+       class T(tuple):
+           def __getitem__(self, i):
+               return i * 10
+       assert filter(lambda x: x != 20, T("abcd")) == (0, 10, 30)
 
 class AppTestXRange:
    def test_xrange(self):



More information about the Pypy-commit mailing list