[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