[Python-checkins] r57909 - in sandbox/trunk/2to3: README fixes/fix_idioms.py fixes/fix_sort.py tests/test_fixers.py

collin.winter python-checkins at python.org
Sun Sep 2 21:33:15 CEST 2007


Author: collin.winter
Date: Sun Sep  2 21:33:14 2007
New Revision: 57909

Removed:
   sandbox/trunk/2to3/fixes/fix_sort.py
Modified:
   sandbox/trunk/2to3/README
   sandbox/trunk/2to3/fixes/fix_idioms.py
   sandbox/trunk/2to3/tests/test_fixers.py
Log:
Fold fix_sort into fix_idioms.

Modified: sandbox/trunk/2to3/README
==============================================================================
--- sandbox/trunk/2to3/README	(original)
+++ sandbox/trunk/2to3/README	Sun Sep  2 21:33:14 2007
@@ -64,9 +64,10 @@
 * **fix_has_key** - "d.has_key(x)" -> "x in d".
 
 * **fix_idioms** - convert type(x) == T to isinstance(x, T), "while 1:" to
-  "while True:", etc. This fixer must be explicitly requested with "-f idioms".
+  "while True:", plus others. This fixer must be explicitly requested
+  with "-f idioms".
 
-* **fix_imports** - Fix incompatible imports.
+* **fix_imports** - Fix (some) incompatible imports.
 
 * **fix_input** - "input()" -> "eval(input())" (PEP 3111).
 
@@ -92,9 +93,6 @@
 
 * **fix_repr** - swap backticks for repr() calls.
 
-* **fix_sort** - converts the two-line "v = list(x)" "v.sort()" idiom into
-  the single-line "v = sorted(x)" equivalent.
-
 * **fix_standarderror** - StandardError -> Exception.
 
 * **fix_throw** - fix generator.throw() calls to be 3.0-compliant (PEP 3109).

Modified: sandbox/trunk/2to3/fixes/fix_idioms.py
==============================================================================
--- sandbox/trunk/2to3/fixes/fix_idioms.py	(original)
+++ sandbox/trunk/2to3/fixes/fix_idioms.py	Sun Sep  2 21:33:14 2007
@@ -7,6 +7,23 @@
     type(x) is not T -> not isinstance(x, T)
     
 * Change "while 1:" into "while True:".
+
+* Change both
+
+    v = list(EXPR)
+    v.sort()
+    foo(v)
+
+and the more general
+
+    v = EXPR
+    v.sort()
+    foo(v)
+    
+into
+
+    v = sorted(EXPR)
+    foo(v)
 """
 # Author: Jacques Frechet, Collin Winter
 
@@ -21,17 +38,63 @@
 
     explicit = True # The user must ask for this fixer
 
-    PATTERN = """
-        isinstance=comparison< %s %s T=any > |
-        isinstance=comparison< T=any %s %s > |
+    PATTERN = r"""
+        isinstance=comparison< %s %s T=any >
+        |
+        isinstance=comparison< T=any %s %s >
+        |
         while_stmt< 'while' while='1' ':' any+ >
+        |
+        sorted=any<
+            any*
+            simple_stmt<
+              expr_stmt< id1=any '='
+                         power< list='list' trailer< '(' (not arglist<any+>) any ')' > >
+              >
+              '\n'
+            >
+            sort=
+            simple_stmt<
+              power< id2=any
+                     trailer< '.' 'sort' > trailer< '(' ')' >
+              >
+              '\n'
+            >
+            next=any*
+        >
+        |
+        sorted=any<
+            any*
+            simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' >
+            sort=
+            simple_stmt<
+              power< id2=any
+                     trailer< '.' 'sort' > trailer< '(' ')' >
+              >
+              '\n'
+            >
+            next=any*
+        >
     """ % (TYPE, CMP, CMP, TYPE)
 
+    def match(self, node):
+        r = super(FixIdioms, self).match(node)
+        # If we've matched one of the sort/sorted subpatterns above, we
+        # want to reject matches where the initial assignment and the
+        # subsequent .sort() call involve different identifiers.
+        if r and "sorted" in r:
+            if r["id1"] == r["id2"]:
+                return r
+            return None
+        return r
+
     def transform(self, node, results):
         if "isinstance" in results:
             return self.transform_isinstance(node, results)
         elif "while" in results:
             return self.transform_while(node, results)
+        elif "sorted" in results:
+            return self.transform_sort(node, results)
         else:
             raise RuntimeError("Invalid match")
 
@@ -50,3 +113,22 @@
     def transform_while(self, node, results):
         one = results["while"]
         one.replace(Name("True", prefix=one.get_prefix()))
+
+    def transform_sort(self, node, results):
+        sort_stmt = results["sort"]
+        next_stmt = results["next"]
+        list_call = results.get("list")
+        simple_expr = results.get("expr")
+
+        if list_call:
+            list_call.replace(Name("sorted", prefix=list_call.get_prefix()))
+        elif simple_expr:
+            new = simple_expr.clone()
+            new.set_prefix("")
+            simple_expr.replace(Call(Name("sorted"), [new],
+                                     prefix=simple_expr.get_prefix()))
+        else:
+            raise RuntimeError("should not have reached here")
+        sort_stmt.remove()
+        if next_stmt:
+            next_stmt[0].set_prefix(sort_stmt.get_prefix())

Deleted: /sandbox/trunk/2to3/fixes/fix_sort.py
==============================================================================
--- /sandbox/trunk/2to3/fixes/fix_sort.py	Sun Sep  2 21:33:14 2007
+++ (empty file)
@@ -1,87 +0,0 @@
-"""Change the two-line list/sort idiom into the modern sorted() call.
-
-That is, both
-
-    v = list(t())
-    v.sort()
-    foo(v)
-
-and
-
-    v = t()
-    v.sort()
-    foo(v)
-    
-becomes
-
-    v = sorted(t())
-    foo(v)
-"""
-# Author: Collin Winter
-
-# Local imports
-from fixes import basefix
-from fixes.util import Name, Call
-
-
-class FixSort(basefix.BaseFix):
-
-    PATTERN = r"""
-              any<
-                  any*
-                  simple_stmt<
-                    expr_stmt< id1=any '='
-                               power< list='list' trailer< '(' (not arglist<any+>) any ')' > >
-                    >
-                    '\n'
-                  >
-                  sort=
-                  simple_stmt<
-                    power< id2=any
-                           trailer< '.' 'sort' > trailer< '(' ')' >
-                    >
-                    '\n'
-                  >
-                  next=any*
-              >
-              |
-              any<
-                  any*
-                  simple_stmt< expr_stmt< id1=any '=' expr=any > '\n' >
-                  sort=
-                  simple_stmt<
-                    power< id2=any
-                           trailer< '.' 'sort' > trailer< '(' ')' >
-                    >
-                    '\n'
-                  >
-                  next=any*
-              >
-              """
-
-    def match(self, node):
-        r = super(FixSort, self).match(node)
-        if r:
-            if r["id1"] == r["id2"]:
-                return r
-            return None
-        return r
-
-    def transform(self, node, results):
-        sort_stmt = results["sort"]
-        next_stmt = results["next"]
-        list_call = results.get("list")
-        simple_expr = results.get("expr")
-
-        if list_call:
-            list_call.replace(Name("sorted", prefix=list_call.get_prefix()))
-        elif simple_expr:
-            new = simple_expr.clone()
-            new.set_prefix("")
-            simple_expr.replace(Call(Name("sorted"), [new],
-                                     prefix=simple_expr.get_prefix()))
-        else:
-            raise RuntimeError("should not have reached here")
-        sort_stmt.remove()
-        if next_stmt:
-            next_stmt[0].set_prefix(sort_stmt.get_prefix())

Modified: sandbox/trunk/2to3/tests/test_fixers.py
==============================================================================
--- sandbox/trunk/2to3/tests/test_fixers.py	(original)
+++ sandbox/trunk/2to3/tests/test_fixers.py	Sun Sep  2 21:33:14 2007
@@ -2382,10 +2382,154 @@
         a = """int"""
         self.check(b, a)
 
-class Test_sort(FixerTestCase):
-    fixer = "sort"
+class Test_idioms(FixerTestCase):
+    fixer = "idioms"
+
+    def test_while(self):
+        b = """while 1: foo()"""
+        a = """while True: foo()"""
+        self.check(b, a)
+
+        b = """while   1: foo()"""
+        a = """while   True: foo()"""
+        self.check(b, a)
+
+        b = """
+            while 1:
+                foo()
+            """
+        a = """
+            while True:
+                foo()
+            """
+        self.check(b, a)
+
+    def test_while_unchanged(self):
+        s = """while 11: foo()"""
+        self.unchanged(s)
+
+        s = """while 0: foo()"""
+        self.unchanged(s)
+
+        s = """while foo(): foo()"""
+        self.unchanged(s)
+
+        s = """while []: foo()"""
+        self.unchanged(s)
+
+    def test_eq_simple(self):
+        b = """type(x) == T"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) == T: pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_eq_reverse(self):
+        b = """T == type(x)"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T == type(x): pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_eq_expression(self):
+        b = """type(x+y) == d.get('T')"""
+        a = """isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) == d.get('T')"""
+        a = """isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_is_simple(self):
+        b = """type(x) is T"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) is T: pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_reverse(self):
+        b = """T is type(x)"""
+        a = """isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T is type(x): pass"""
+        a = """if   isinstance(x, T): pass"""
+        self.check(b, a)
 
-    def test_list_call(self):
+    def test_is_expression(self):
+        b = """type(x+y) is d.get('T')"""
+        a = """isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) is d.get('T')"""
+        a = """isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_is_not_simple(self):
+        b = """type(x) is not T"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) is not T: pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_not_reverse(self):
+        b = """T is not type(x)"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T is not type(x): pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_is_not_expression(self):
+        b = """type(x+y) is not d.get('T')"""
+        a = """not isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) is not d.get('T')"""
+        a = """not isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_ne_simple(self):
+        b = """type(x) != T"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   type(x) != T: pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_ne_reverse(self):
+        b = """T != type(x)"""
+        a = """not isinstance(x, T)"""
+        self.check(b, a)
+
+        b = """if   T != type(x): pass"""
+        a = """if   not isinstance(x, T): pass"""
+        self.check(b, a)
+
+    def test_ne_expression(self):
+        b = """type(x+y) != d.get('T')"""
+        a = """not isinstance(x+y, d.get('T'))"""
+        self.check(b, a)
+
+        b = """type(   x  +  y) != d.get('T')"""
+        a = """not isinstance(x  +  y, d.get('T'))"""
+        self.check(b, a)
+
+    def test_type_unchanged(self):
+        a = """type(x).__name__"""
+        self.unchanged(a)
+
+    def test_sort_list_call(self):
         b = """
             v = list(t)
             v.sort()
@@ -2445,7 +2589,7 @@
             """
         self.check(b, a)
 
-    def test_simple_expr(self):
+    def test_sort_simple_expr(self):
         b = """
             v = t
             v.sort()
@@ -2527,7 +2671,7 @@
             """
         self.check(b, a)
 
-    def test_unchanged(self):
+    def test_sort_unchanged(self):
         s = """
             v = list(t)
             w.sort()
@@ -2543,154 +2687,6 @@
         self.unchanged(s)
 
 
-class Test_idioms(FixerTestCase):
-    fixer = "idioms"
-
-    def test_while(self):
-        b = """while 1: foo()"""
-        a = """while True: foo()"""
-        self.check(b, a)
-
-        b = """while   1: foo()"""
-        a = """while   True: foo()"""
-        self.check(b, a)
-
-        b = """
-            while 1:
-                foo()
-            """
-        a = """
-            while True:
-                foo()
-            """
-        self.check(b, a)
-
-    def test_while_unchanged(self):
-        s = """while 11: foo()"""
-        self.unchanged(s)
-
-        s = """while 0: foo()"""
-        self.unchanged(s)
-
-        s = """while foo(): foo()"""
-        self.unchanged(s)
-
-        s = """while []: foo()"""
-        self.unchanged(s)
-
-    def test_eq_simple(self):
-        b = """type(x) == T"""
-        a = """isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   type(x) == T: pass"""
-        a = """if   isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_eq_reverse(self):
-        b = """T == type(x)"""
-        a = """isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   T == type(x): pass"""
-        a = """if   isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_eq_expression(self):
-        b = """type(x+y) == d.get('T')"""
-        a = """isinstance(x+y, d.get('T'))"""
-        self.check(b, a)
-
-        b = """type(   x  +  y) == d.get('T')"""
-        a = """isinstance(x  +  y, d.get('T'))"""
-        self.check(b, a)
-
-    def test_is_simple(self):
-        b = """type(x) is T"""
-        a = """isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   type(x) is T: pass"""
-        a = """if   isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_is_reverse(self):
-        b = """T is type(x)"""
-        a = """isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   T is type(x): pass"""
-        a = """if   isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_is_expression(self):
-        b = """type(x+y) is d.get('T')"""
-        a = """isinstance(x+y, d.get('T'))"""
-        self.check(b, a)
-
-        b = """type(   x  +  y) is d.get('T')"""
-        a = """isinstance(x  +  y, d.get('T'))"""
-        self.check(b, a)
-
-    def test_is_not_simple(self):
-        b = """type(x) is not T"""
-        a = """not isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   type(x) is not T: pass"""
-        a = """if   not isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_is_not_reverse(self):
-        b = """T is not type(x)"""
-        a = """not isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   T is not type(x): pass"""
-        a = """if   not isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_is_not_expression(self):
-        b = """type(x+y) is not d.get('T')"""
-        a = """not isinstance(x+y, d.get('T'))"""
-        self.check(b, a)
-
-        b = """type(   x  +  y) is not d.get('T')"""
-        a = """not isinstance(x  +  y, d.get('T'))"""
-        self.check(b, a)
-
-    def test_ne_simple(self):
-        b = """type(x) != T"""
-        a = """not isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   type(x) != T: pass"""
-        a = """if   not isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_ne_reverse(self):
-        b = """T != type(x)"""
-        a = """not isinstance(x, T)"""
-        self.check(b, a)
-
-        b = """if   T != type(x): pass"""
-        a = """if   not isinstance(x, T): pass"""
-        self.check(b, a)
-
-    def test_ne_expression(self):
-        b = """type(x+y) != d.get('T')"""
-        a = """not isinstance(x+y, d.get('T'))"""
-        self.check(b, a)
-
-        b = """type(   x  +  y) != d.get('T')"""
-        a = """not isinstance(x  +  y, d.get('T'))"""
-        self.check(b, a)
-
-    def test_unchanged(self):
-        a = """type(x).__name__"""
-        self.unchanged(a)
-
-
 if __name__ == "__main__":
     import __main__
     support.run_all_tests(__main__)


More information about the Python-checkins mailing list