[Python-checkins] r57914 - in sandbox/trunk/2to3: pygram.py refactor.py tests/test_all_fixers.py tests/test_fixers.py tests/test_refactor.py

collin.winter python-checkins at python.org
Mon Sep 3 07:42:20 CEST 2007


Author: collin.winter
Date: Mon Sep  3 07:42:19 2007
New Revision: 57914

Added:
   sandbox/trunk/2to3/tests/test_refactor.py
Modified:
   sandbox/trunk/2to3/pygram.py
   sandbox/trunk/2to3/refactor.py
   sandbox/trunk/2to3/tests/test_all_fixers.py
   sandbox/trunk/2to3/tests/test_fixers.py
Log:
Drop the -p option to refactor.py in favor of having the tool automatically figure out when you're using print statements and when you're using print functions.

Modified: sandbox/trunk/2to3/pygram.py
==============================================================================
--- sandbox/trunk/2to3/pygram.py	(original)
+++ sandbox/trunk/2to3/pygram.py	Mon Sep  3 07:42:19 2007
@@ -29,6 +29,8 @@
 
 python_grammar = driver.load_grammar(_GRAMMAR_FILE)
 python_symbols = Symbols(python_grammar)
+printless_python_grammar = driver.load_grammar(_GRAMMAR_FILE)
+del printless_python_grammar.keywords["print"]
 
 
 def parenthesize(node):

Modified: sandbox/trunk/2to3/refactor.py
==============================================================================
--- sandbox/trunk/2to3/refactor.py	(original)
+++ sandbox/trunk/2to3/refactor.py	Mon Sep  3 07:42:19 2007
@@ -23,6 +23,8 @@
 import pytree
 import patcomp
 from pgen2 import driver
+from pgen2 import parse
+from pgen2 import token
 from pgen2 import tokenize
 import fixes
 import pygram
@@ -52,8 +54,6 @@
                       help="Each FIX specifies a transformation; default all")
     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",
-                      help="Modify the grammar so that print() is a function")
     parser.add_option("-v", "--verbose", action="store_true",
                       help="More verbose logging")
     parser.add_option("-w", "--write", action="store_true",
@@ -106,11 +106,14 @@
         self.options = options
         self.errors = []
         self.logger = logging.getLogger("RefactoringTool")
-        if self.options.print_function:
-            del pygram.python_grammar.keywords["print"]
+        # Set up two parser drivers: one that expects print statements and a
+        # second that expects print functions.
         self.driver = driver.Driver(pygram.python_grammar,
                                     convert=pytree.convert,
                                     logger=self.logger)
+        self.printless_driver = driver.Driver(pygram.printless_python_grammar,
+                                              convert=pytree.convert,
+                                              logger=self.logger)
         self.pre_order, self.post_order = self.get_fixers()
         self.files = []  # List of files that were or should be modified
 
@@ -210,10 +213,7 @@
             self.log_error("Can't open %s: %s", filename, err)
             return
         try:
-            if self.options.doctests_only:
-                input = f.read()
-            else:
-                tree = self.refactor_stream(f, filename)
+            input = f.read()
         finally:
             f.close()
         if self.options.doctests_only:
@@ -225,24 +225,31 @@
             elif self.options.verbose:
                 self.log_message("No doctest changes in %s", filename)
         else:
+            tree = self.refactor_string(input, filename)
             if tree.was_changed:
                 self.write_file(str(tree), filename)
             elif self.options.verbose:
                 self.log_message("No changes in %s", filename)
 
-    def refactor_stream(self, stream, name):
-        """Refactor an stream, pullin from a given file-like object.
+    def refactor_string(self, data, name):
+        """Refactor a given input string.
         
         Args:
-            stream: a file-like object to pull data from.
-            name: a human-readable name for the stream.
+            data: a string holding the code to be refactored.
+            name: a human-readable name for use in error/log messages.
             
         Returns:
             An AST corresponding to the refactored input stream; None if
             there were errors during the parse.
         """
         try:
-            tree = self.driver.parse_stream(stream)
+            try:
+                tree = self.driver.parse_string(data)
+            except parse.ParseError, e:
+                if e.type == token.EQUAL:
+                    tree = self.printless_driver.parse_string(data)
+                else:
+                    raise
         except Exception, err:
             self.log_error("Can't parse %s: %s: %s",
                            name, err.__class__.__name__, err)
@@ -256,8 +263,8 @@
         if self.options.write:
             self.log_error("Can't write changes back to stdin")
             return
+        input = sys.stdin.read()
         if self.options.doctests_only:
-            input = sys.stdin.read()
             if self.options.verbose:
                 self.log_message("Refactoring doctests in stdin")
             output = self.refactor_docstring(input, "<stdin>")
@@ -266,7 +273,7 @@
             elif self.options.verbose:
                 self.log_message("No doctest changes in stdin")
         else:
-            tree = self.refactor_stream(sys.stdin, "<stdin>")
+            tree = self.refactor_string(input, "<stdin>")
             if tree.was_changed:
                 self.write_file(str(tree), "<stdin>", input)
             elif self.options.verbose:

Modified: sandbox/trunk/2to3/tests/test_all_fixers.py
==============================================================================
--- sandbox/trunk/2to3/tests/test_all_fixers.py	(original)
+++ sandbox/trunk/2to3/tests/test_all_fixers.py	Mon Sep  3 07:42:19 2007
@@ -7,7 +7,10 @@
 # Author: Collin Winter
 
 # Testing imports
-from tests import support
+try:
+    from tests import support
+except ImportError:
+    import support
 
 # Python imports
 from StringIO import StringIO
@@ -25,24 +28,17 @@
         for k, v in kwargs.items():
             setattr(self, k, v)
         self.verbose = False
+        self.doctests_only = False
 
 class Test_all(support.TestCase):
     def setUp(self):
-        options = Options(fix=["all"], print_function=False)
+        options = Options(fix=["all"], write=False)
         self.refactor = refactor.RefactoringTool(options)
 
-    def refactor_stream(self, stream_name, stream):
-        try:
-            tree = self.refactor.driver.parse_stream(stream)
-        except Exception, err:
-            raise
-        self.refactor.refactor_tree(tree, stream_name)
-        return str(tree)
-
     def test_all_project_files(self):
         for filepath in support.all_project_files():
             print "Fixing %s..." % filepath
-            self.refactor_stream(filepath, open(filepath))
+            self.refactor.refactor_file(filepath)
 
 
 if __name__ == "__main__":

Modified: sandbox/trunk/2to3/tests/test_fixers.py
==============================================================================
--- sandbox/trunk/2to3/tests/test_fixers.py	(original)
+++ sandbox/trunk/2to3/tests/test_fixers.py	Mon Sep  3 07:42:19 2007
@@ -62,7 +62,7 @@
     def _check(self, before, after):
         before = support.reformat(before)
         after = support.reformat(after)
-        tree = self.refactor.refactor_stream(StringIO(before), "<string>")
+        tree = self.refactor.refactor_string(before, "<string>")
         self.failUnlessEqual(after, str(tree))
         return tree
 

Added: sandbox/trunk/2to3/tests/test_refactor.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/2to3/tests/test_refactor.py	Mon Sep  3 07:42:19 2007
@@ -0,0 +1,62 @@
+#!/usr/bin/env python2.5
+""" Test suite for refactor.py """
+# Author: Collin Winter
+
+# Testing imports
+try:
+    from tests import support
+except ImportError:
+    import support
+
+# Python imports
+from StringIO import StringIO
+import logging
+import os
+import os.path
+import unittest
+
+# Local imports
+import refactor
+
+
+class Options:
+    def __init__(self, **kwargs):
+        for k, v in kwargs.items():
+            setattr(self, k, v)
+        self.verbose = False
+        self.doctests_only = False
+
+
+class TestAutomaticPrintDetection(unittest.TestCase):
+
+    def setUp(self):
+        self.refactor = refactor.RefactoringTool(Options(fix=["print"]))
+
+    def _check(self, before, after):
+        before = support.reformat(before)
+        after = support.reformat(after)
+        tree = self.refactor.refactor_string(before, "<stream>")
+        self.failUnlessEqual(str(tree), after)
+        return tree
+
+    def check(self, before, after):
+        tree = self._check(before, after)
+        self.failUnless(tree.was_changed)
+
+    def unchanged(self, before):
+        tree = self._check(before, before)
+        self.failIf(tree.was_changed)
+
+    def test_print_statement(self):
+        b = """print >>b, c"""
+        a = """print(c, file=b)"""
+        self.check(b, a)
+
+    def test_print_function(self):
+        s = """print(c, file=b)"""
+        self.unchanged(s)
+
+
+if __name__ == "__main__":
+    import __main__
+    support.run_all_tests(__main__)


More information about the Python-checkins mailing list