[Python-checkins] r66911 - in python/trunk/Lib/lib2to3: fixes/fix_next.py fixes/fix_set_literal.py main.py refactor.py tests/data/README tests/test_fixers.py tests/test_pytree.py tests/test_refactor.py

benjamin.peterson python-checkins at python.org
Thu Oct 16 01:10:29 CEST 2008


Author: benjamin.peterson
Date: Thu Oct 16 01:10:28 2008
New Revision: 66911

Log:
Merged revisions 66805,66841,66860,66884-66886,66893,66907,66910 via svnmerge from 
svn+ssh://pythondev@svn.python.org/sandbox/trunk/2to3/lib2to3

........
  r66805 | benjamin.peterson | 2008-10-04 20:11:02 -0500 (Sat, 04 Oct 2008) | 1 line
  
  mention what the fixes directory is for
........
  r66841 | benjamin.peterson | 2008-10-07 17:48:12 -0500 (Tue, 07 Oct 2008) | 1 line
  
  use assertFalse and assertTrue
........
  r66860 | benjamin.peterson | 2008-10-08 16:05:07 -0500 (Wed, 08 Oct 2008) | 1 line
  
  instead of abusing the pattern matcher, use start_tree to find a next binding
........
  r66884 | benjamin.peterson | 2008-10-13 15:50:30 -0500 (Mon, 13 Oct 2008) | 1 line
  
  don't print tokens to stdout when -v is given
........
  r66885 | benjamin.peterson | 2008-10-13 16:28:57 -0500 (Mon, 13 Oct 2008) | 1 line
  
  add the -x option to disable fixers
........
  r66886 | benjamin.peterson | 2008-10-13 16:33:53 -0500 (Mon, 13 Oct 2008) | 1 line
  
  cut down on some crud
........
  r66893 | benjamin.peterson | 2008-10-14 17:16:54 -0500 (Tue, 14 Oct 2008) | 1 line
  
  add an optional set literal fixer
........
  r66907 | benjamin.peterson | 2008-10-15 16:59:41 -0500 (Wed, 15 Oct 2008) | 1 line
  
  don't write backup files by default
........
  r66910 | benjamin.peterson | 2008-10-15 17:43:10 -0500 (Wed, 15 Oct 2008) | 1 line
  
  add the -n option; it stops backupfiles from being written
........


Added:
   python/trunk/Lib/lib2to3/fixes/fix_set_literal.py
      - copied unchanged from r66910, /sandbox/trunk/2to3/lib2to3/fixes/fix_set_literal.py
Modified:
   python/trunk/Lib/lib2to3/   (props changed)
   python/trunk/Lib/lib2to3/fixes/fix_next.py
   python/trunk/Lib/lib2to3/main.py
   python/trunk/Lib/lib2to3/refactor.py
   python/trunk/Lib/lib2to3/tests/data/README
   python/trunk/Lib/lib2to3/tests/test_fixers.py
   python/trunk/Lib/lib2to3/tests/test_pytree.py
   python/trunk/Lib/lib2to3/tests/test_refactor.py

Modified: python/trunk/Lib/lib2to3/fixes/fix_next.py
==============================================================================
--- python/trunk/Lib/lib2to3/fixes/fix_next.py	(original)
+++ python/trunk/Lib/lib2to3/fixes/fix_next.py	Thu Oct 16 01:10:28 2008
@@ -28,15 +28,19 @@
                      any* > >
     |
     global=global_stmt< 'global' any* 'next' any* >
-    |
-    mod=file_input< any+ >
     """
 
     order = "pre" # Pre-order tree traversal
 
     def start_tree(self, tree, filename):
         super(FixNext, self).start_tree(tree, filename)
-        self.shadowed_next = False
+
+        n = find_binding('next', tree)
+        if n:
+            self.warning(n, bind_warning)
+            self.shadowed_next = True
+        else:
+            self.shadowed_next = False
 
     def transform(self, node, results):
         assert results
@@ -69,11 +73,6 @@
         elif "global" in results:
             self.warning(node, bind_warning)
             self.shadowed_next = True
-        elif mod:
-            n = find_binding('next', mod)
-            if n:
-                self.warning(n, bind_warning)
-                self.shadowed_next = True
 
 
 ### The following functions help test if node is part of an assignment

Modified: python/trunk/Lib/lib2to3/main.py
==============================================================================
--- python/trunk/Lib/lib2to3/main.py	(original)
+++ python/trunk/Lib/lib2to3/main.py	Thu Oct 16 01:10:28 2008
@@ -15,10 +15,31 @@
     Prints output to stdout.
     """
 
+    def __init__(self, fixers, options, explicit, nobackups):
+        self.nobackups = nobackups
+        super(StdoutRefactoringTool, self).__init__(fixers, options, explicit)
+
     def log_error(self, msg, *args, **kwargs):
         self.errors.append((msg, args, kwargs))
         self.logger.error(msg, *args, **kwargs)
 
+    def write_file(self, new_text, filename, old_text):
+        if not self.nobackups:
+            # Make backup
+            backup = filename + ".bak"
+            if os.path.lexists(backup):
+                try:
+                    os.remove(backup)
+                except os.error, err:
+                    self.log_message("Can't remove backup %s", backup)
+            try:
+                os.rename(filename, backup)
+            except os.error, err:
+                self.log_message("Can't rename %s to %s", filename, backup)
+        # Actually write the new file
+        super(StdoutRefactoringTool, self).write_file(new_text,
+                                                      filename, old_text)
+
     def print_output(self, lines):
         for line in lines:
             print line
@@ -39,7 +60,9 @@
     parser.add_option("-d", "--doctests_only", action="store_true",
                       help="Fix up doctests only")
     parser.add_option("-f", "--fix", action="append", default=[],
-                      help="Each FIX specifies a transformation; default all")
+                      help="Each FIX specifies a transformation; default: all")
+    parser.add_option("-x", "--nofix", action="append", default=[],
+                      help="Prevent a fixer from being run.")
     parser.add_option("-l", "--list-fixes", action="store_true",
                       help="List available transformations (fixes/fix_*.py)")
     parser.add_option("-p", "--print-function", action="store_true",
@@ -48,10 +71,14 @@
                       help="More verbose logging")
     parser.add_option("-w", "--write", action="store_true",
                       help="Write back modified files")
+    parser.add_option("-n", "--nobackups", action="store_true", default=False,
+                      help="Don't write backups for modified files.")
 
     # Parse command line arguments
     refactor_stdin = False
     options, args = parser.parse_args(args)
+    if not options.write and options.nobackups:
+        parser.error("Can't use -n without -w")
     if options.list_fixes:
         print "Available transformations for the -f/--fix option:"
         for fixname in refactor.get_all_fix_names(fixer_pkg):
@@ -74,15 +101,22 @@
 
     # Initialize the refactoring tool
     rt_opts = {"print_function" : options.print_function}
-    avail_names = refactor.get_fixers_from_package(fixer_pkg)
-    explicit = []
+    avail_fixes = set(refactor.get_fixers_from_package(fixer_pkg))
+    unwanted_fixes = set(fixer_pkg + ".fix_" + fix for fix in options.nofix)
+    explicit = set()
     if options.fix:
-        explicit = [fixer_pkg + ".fix_" + fix
-                    for fix in options.fix if fix != "all"]
-        fixer_names = avail_names if "all" in options.fix else explicit
+        all_present = False
+        for fix in options.fix:
+            if fix == "all":
+                all_present = True
+            else:
+                explicit.add(fixer_pkg + ".fix_" + fix)
+        requested = avail_fixes.union(explicit) if all_present else explicit
     else:
-        fixer_names = avail_names
-    rt = StdoutRefactoringTool(fixer_names, rt_opts, explicit=explicit)
+        requested = avail_fixes.union(explicit)
+    fixer_names = requested.difference(unwanted_fixes)
+    rt = StdoutRefactoringTool(sorted(fixer_names), rt_opts, sorted(explicit),
+                               options.nobackups)
 
     # Refactor all files and directories passed as arguments
     if not rt.errors:

Modified: python/trunk/Lib/lib2to3/refactor.py
==============================================================================
--- python/trunk/Lib/lib2to3/refactor.py	(original)
+++ python/trunk/Lib/lib2to3/refactor.py	Thu Oct 16 01:10:28 2008
@@ -36,9 +36,7 @@
     pkg = __import__(fixer_pkg, [], [], ["*"])
     fixer_dir = os.path.dirname(pkg.__file__)
     fix_names = []
-    names = os.listdir(fixer_dir)
-    names.sort()
-    for name in names:
+    for name in sorted(os.listdir(fixer_dir)):
         if name.startswith("fix_") and name.endswith(".py"):
             if remove_prefix:
                 name = name[4:]
@@ -253,7 +251,7 @@
             there were errors during the parse.
         """
         try:
-            tree = self.driver.parse_string(data,1)
+            tree = self.driver.parse_string(data)
         except Exception, err:
             self.log_error("Can't parse %s: %s: %s",
                            name, err.__class__.__name__, err)
@@ -352,23 +350,13 @@
         else:
             self.log_debug("Not writing changes to %s", filename)
 
-    def write_file(self, new_text, filename, old_text=None):
+    def write_file(self, new_text, filename, old_text):
         """Writes a string to a file.
 
         It first shows a unified diff between the old text and the new text, and
         then rewrites the file; the latter is only done if the write option is
         set.
         """
-        backup = filename + ".bak"
-        if os.path.lexists(backup):
-            try:
-                os.remove(backup)
-            except os.error, err:
-                self.log_message("Can't remove backup %s", backup)
-        try:
-            os.rename(filename, backup)
-        except os.error, err:
-            self.log_message("Can't rename %s to %s", filename, backup)
         try:
             f = open(filename, "w")
         except os.error, err:

Modified: python/trunk/Lib/lib2to3/tests/data/README
==============================================================================
--- python/trunk/Lib/lib2to3/tests/data/README	(original)
+++ python/trunk/Lib/lib2to3/tests/data/README	Thu Oct 16 01:10:28 2008
@@ -1,5 +1,6 @@
-Files in this directory:
+In this directory:
 - py2_test_grammar.py -- test file that exercises most/all of Python 2.x's grammar.
 - py3_test_grammar.py -- test file that exercises most/all of Python 3.x's grammar.
 - infinite_recursion.py -- test file that causes lib2to3's faster recursive pattern matching
   scheme to fail, but passes when lib2to3 falls back to iterative pattern matching.
+- fixes/ -- for use by test_refactor.py

Modified: python/trunk/Lib/lib2to3/tests/test_fixers.py
==============================================================================
--- python/trunk/Lib/lib2to3/tests/test_fixers.py	(original)
+++ python/trunk/Lib/lib2to3/tests/test_fixers.py	Thu Oct 16 01:10:28 2008
@@ -3385,6 +3385,134 @@
         """
         self.check_both(b, a)
 
+
+class Test_set_literal(FixerTestCase):
+
+    fixer = "set_literal"
+
+    def test_basic(self):
+        b = """set([1, 2, 3])"""
+        a = """{1, 2, 3}"""
+        self.check(b, a)
+
+        b = """set((1, 2, 3))"""
+        a = """{1, 2, 3}"""
+        self.check(b, a)
+
+        b = """set((1,))"""
+        a = """{1}"""
+        self.check(b, a)
+
+        b = """set([1])"""
+        self.check(b, a)
+
+        b = """set((a, b))"""
+        a = """{a, b}"""
+        self.check(b, a)
+
+        b = """set([a, b])"""
+        self.check(b, a)
+
+        b = """set((a*234, f(args=23)))"""
+        a = """{a*234, f(args=23)}"""
+        self.check(b, a)
+
+        b = """set([a*23, f(23)])"""
+        a = """{a*23, f(23)}"""
+        self.check(b, a)
+
+        b = """set([a-234**23])"""
+        a = """{a-234**23}"""
+        self.check(b, a)
+
+    def test_listcomps(self):
+        b = """set([x for x in y])"""
+        a = """{x for x in y}"""
+        self.check(b, a)
+
+        b = """set([x for x in y if x == m])"""
+        a = """{x for x in y if x == m}"""
+        self.check(b, a)
+
+        b = """set([x for x in y for a in b])"""
+        a = """{x for x in y for a in b}"""
+        self.check(b, a)
+
+        b = """set([f(x) - 23 for x in y])"""
+        a = """{f(x) - 23 for x in y}"""
+        self.check(b, a)
+
+    def test_whitespace(self):
+        b = """set( [1, 2])"""
+        a = """{1, 2}"""
+        self.check(b, a)
+
+        b = """set([1 ,  2])"""
+        a = """{1 ,  2}"""
+        self.check(b, a)
+
+        b = """set([ 1 ])"""
+        a = """{ 1 }"""
+        self.check(b, a)
+
+        b = """set( [1] )"""
+        a = """{1}"""
+        self.check(b, a)
+
+        b = """set([  1,  2  ])"""
+        a = """{  1,  2  }"""
+        self.check(b, a)
+
+        b = """set([x  for x in y ])"""
+        a = """{x  for x in y }"""
+        self.check(b, a)
+
+        b = """set(
+                   [1, 2]
+               )
+            """
+        a = """{1, 2}\n"""
+        self.check(b, a)
+
+    def test_comments(self):
+        b = """set((1, 2)) # Hi"""
+        a = """{1, 2} # Hi"""
+        self.check(b, a)
+
+        # This isn't optimal behavior, but the fixer is optional.
+        b = """
+            # Foo
+            set( # Bar
+               (1, 2)
+            )
+            """
+        a = """
+            # Foo
+            {1, 2}
+            """
+        self.check(b, a)
+
+    def test_unchanged(self):
+        s = """set()"""
+        self.unchanged(s)
+
+        s = """set(a)"""
+        self.unchanged(s)
+
+        s = """set(a, b, c)"""
+        self.unchanged(s)
+
+        # Don't transform generators because they might have to be lazy.
+        s = """set(x for x in y)"""
+        self.unchanged(s)
+
+        s = """set(x for x in y if z)"""
+        self.unchanged(s)
+
+        s = """set(a*823-23**2 + f(23))"""
+        self.unchanged(s)
+
+
 class Test_sys_exc(FixerTestCase):
     fixer = "sys_exc"
 

Modified: python/trunk/Lib/lib2to3/tests/test_pytree.py
==============================================================================
--- python/trunk/Lib/lib2to3/tests/test_pytree.py	(original)
+++ python/trunk/Lib/lib2to3/tests/test_pytree.py	Thu Oct 16 01:10:28 2008
@@ -353,29 +353,29 @@
         # Build a pattern matching a leaf
         pl = pytree.LeafPattern(100, "foo", name="pl")
         r = {}
-        self.assertEqual(pl.match(root, results=r), False)
+        self.assertFalse(pl.match(root, results=r))
         self.assertEqual(r, {})
-        self.assertEqual(pl.match(n1, results=r), False)
+        self.assertFalse(pl.match(n1, results=r))
         self.assertEqual(r, {})
-        self.assertEqual(pl.match(n2, results=r), False)
+        self.assertFalse(pl.match(n2, results=r))
         self.assertEqual(r, {})
-        self.assertEqual(pl.match(l1, results=r), True)
+        self.assertTrue(pl.match(l1, results=r))
         self.assertEqual(r, {"pl": l1})
         r = {}
-        self.assertEqual(pl.match(l2, results=r), False)
+        self.assertFalse(pl.match(l2, results=r))
         self.assertEqual(r, {})
         # Build a pattern matching a node
         pn = pytree.NodePattern(1000, [pl], name="pn")
-        self.assertEqual(pn.match(root, results=r), False)
+        self.assertFalse(pn.match(root, results=r))
         self.assertEqual(r, {})
-        self.assertEqual(pn.match(n1, results=r), False)
+        self.assertFalse(pn.match(n1, results=r))
         self.assertEqual(r, {})
-        self.assertEqual(pn.match(n2, results=r), True)
+        self.assertTrue(pn.match(n2, results=r))
         self.assertEqual(r, {"pn": n2, "pl": l3})
         r = {}
-        self.assertEqual(pn.match(l1, results=r), False)
+        self.assertFalse(pn.match(l1, results=r))
         self.assertEqual(r, {})
-        self.assertEqual(pn.match(l2, results=r), False)
+        self.assertFalse(pn.match(l2, results=r))
         self.assertEqual(r, {})
 
     def testWildcardPatterns(self):
@@ -391,11 +391,11 @@
         pn = pytree.NodePattern(1000, [pl], name="pn")
         pw = pytree.WildcardPattern([[pn], [pl, pl]], name="pw")
         r = {}
-        self.assertEqual(pw.match_seq([root], r), False)
+        self.assertFalse(pw.match_seq([root], r))
         self.assertEqual(r, {})
-        self.assertEqual(pw.match_seq([n1], r), False)
+        self.assertFalse(pw.match_seq([n1], r))
         self.assertEqual(r, {})
-        self.assertEqual(pw.match_seq([n2], r), True)
+        self.assertTrue(pw.match_seq([n2], r))
         # These are easier to debug
         self.assertEqual(sorted(r.keys()), ["pl", "pn", "pw"])
         self.assertEqual(r["pl"], l1)
@@ -404,7 +404,7 @@
         # But this is equivalent
         self.assertEqual(r, {"pl": l1, "pn": n2, "pw": [n2]})
         r = {}
-        self.assertEqual(pw.match_seq([l1, l3], r), True)
+        self.assertTrue(pw.match_seq([l1, l3], r))
         self.assertEqual(r, {"pl": l3, "pw": [l1, l3]})
         self.assert_(r["pl"] is l3)
         r = {}

Modified: python/trunk/Lib/lib2to3/tests/test_refactor.py
==============================================================================
--- python/trunk/Lib/lib2to3/tests/test_refactor.py	(original)
+++ python/trunk/Lib/lib2to3/tests/test_refactor.py	Thu Oct 16 01:10:28 2008
@@ -123,7 +123,6 @@
 
     def test_refactor_file(self):
         test_file = os.path.join(FIXER_DIR, "parrot_example.py")
-        backup = test_file + ".bak"
         old_contents = open(test_file, "r").read()
         rt = self.rt()
 
@@ -133,14 +132,8 @@
         rt.refactor_file(test_file, True)
         try:
             self.assertNotEqual(old_contents, open(test_file, "r").read())
-            self.assertTrue(os.path.exists(backup))
-            self.assertEqual(old_contents, open(backup, "r").read())
         finally:
             open(test_file, "w").write(old_contents)
-            try:
-                os.unlink(backup)
-            except OSError:
-                pass
 
     def test_refactor_docstring(self):
         rt = self.rt()


More information about the Python-checkins mailing list