[Python-checkins] r58066 - in sandbox/trunk/2to3: fixes/basefix.py refactor.py tests/test_fixers.py

collin.winter python-checkins at python.org
Mon Sep 10 01:35:30 CEST 2007


Author: collin.winter
Date: Mon Sep 10 01:35:30 2007
New Revision: 58066

Modified:
   sandbox/trunk/2to3/fixes/basefix.py
   sandbox/trunk/2to3/refactor.py
   sandbox/trunk/2to3/tests/test_fixers.py
Log:
Display fixer warnings at the end of a refactoring run, rather than inline during the run. This will make the messages much, much easier to find/read.

Modified: sandbox/trunk/2to3/fixes/basefix.py
==============================================================================
--- sandbox/trunk/2to3/fixes/basefix.py	(original)
+++ sandbox/trunk/2to3/fixes/basefix.py	Mon Sep 10 01:35:30 2007
@@ -40,13 +40,16 @@
     # Shortcut for access to Python grammar symbols
     syms = pygram.python_symbols
 
-    def __init__(self, options):
+    def __init__(self, options, log):
         """Initializer.  Subclass may override.
 
-        The argument is an optparse.Values instance which can be used
-        to inspect the command line options.
+        Args:
+            options: an optparse.Values instance which can be used
+                to inspect the command line options.
+            log: a list to append warnings and other messages to.
         """
         self.options = options
+        self.log = log
         self.compile_pattern()
 
     def compile_pattern(self):
@@ -109,6 +112,12 @@
         self.used_names.add(name)
         return name
 
+    def log_message(self, message):
+        if self.first_log:
+            self.first_log = False
+            self.log.append("### In file %s ###" % self.filename)
+        self.log.append(message)
+
     def cannot_convert(self, node, reason=None):
         """Warn the user that a given chunk of code is not valid Python 3,
         but that it cannot be converted automatically.
@@ -119,10 +128,10 @@
         lineno = node.get_lineno()
         for_output = node.clone()
         for_output.set_prefix("")
-        msg = "At line %d: could not convert: %s"
-        self.logger.warning(msg % (lineno, for_output))
+        msg = "Line %d: could not convert: %s"
+        self.log_message(msg % (lineno, for_output))
         if reason:
-            self.logger.warning(reason)
+            self.log_message(reason)
 
     def warning(self, node, reason):
         """Used for warning the user about possible uncertainty in the
@@ -132,7 +141,7 @@
         Optional second argument is why it can't be converted.
         """
         lineno = node.get_lineno()
-        self.logger.warning("At line %d: %s" % (lineno, reason))
+        self.log_message("Line %d: %s" % (lineno, reason))
 
     def start_tree(self, tree, filename):
         """Some fixers need to maintain tree-wide state.
@@ -144,6 +153,7 @@
         self.used_names = tree.used_names
         self.set_filename(filename)
         self.numbers = itertools.count(1)
+        self.first_log = True
 
     def finish_tree(self, tree, filename):
         """Some fixers need to maintain tree-wide state.

Modified: sandbox/trunk/2to3/refactor.py
==============================================================================
--- sandbox/trunk/2to3/refactor.py	(original)
+++ sandbox/trunk/2to3/refactor.py	Mon Sep 10 01:35:30 2007
@@ -106,6 +106,7 @@
         self.options = options
         self.errors = []
         self.logger = logging.getLogger("RefactoringTool")
+        self.fixer_log = []
         if self.options.print_function:
             del pygram.python_grammar.keywords["print"]
         self.driver = driver.Driver(pygram.python_grammar,
@@ -142,7 +143,7 @@
                                fix_name, class_name)
                 continue
             try:
-                fixer = fix_class(self.options)
+                fixer = fix_class(self.options, self.fixer_log)
             except Exception, err:
                 self.log_error("Can't instantiate fixes.fix_%s.%s()",
                                fix_name, class_name, exc_info=True)
@@ -456,6 +457,10 @@
             self.log_message("Files that %s modified:", were)
             for file in self.files:
                 self.log_message(file)
+        if self.fixer_log:
+            self.log_message("Warnings/messages while refactoring:")
+            for message in self.fixer_log:
+                self.log_message(message)
         if self.errors:
             if len(self.errors) == 1:
                 self.log_message("There was 1 error:")

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 10 01:35:30 2007
@@ -9,8 +9,6 @@
     import support
 
 # Python imports
-from StringIO import StringIO
-import logging
 import unittest
 
 # Local imports
@@ -18,22 +16,6 @@
 import pytree
 import refactor
 
-# We wrap the RefactoringTool's fixer objects so we can intercept
-#  the call to start_tree() and so modify the fixers' logging objects.
-# This allows us to make sure that certain code chunks produce certain
-#  warnings.
-class Fixer(object):
-    def __init__(self, fixer, handler):
-        self.fixer = fixer
-        self.handler = handler
-
-    def __getattr__(self, attr):
-        return getattr(self.fixer, attr)
-
-    def start_tree(self, tree, filename):
-        self.fixer.start_tree(tree, filename)
-        self.fixer.logger.handlers[:] = [self.handler]
-
 class Options:
     def __init__(self, **kwargs):
         for k, v in kwargs.items():
@@ -45,17 +27,11 @@
     def setUp(self):
         options = Options(fix=[self.fixer], print_function=False)
         self.refactor = refactor.RefactoringTool(options)
+        self.fixer_log = []
 
-        self.logging_stream = StringIO()
-        sh = logging.StreamHandler(self.logging_stream)
-        sh.setFormatter(logging.Formatter("%(message)s"))
-        self.refactor.pre_order = [Fixer(f, sh) for f
-                                                in self.refactor.pre_order]
-        self.refactor.post_order = [Fixer(f, sh) for f
-                                                 in self.refactor.post_order]
-
-    def tearDown(self):
-        self.logging_stream = None
+        for order in (self.refactor.pre_order, self.refactor.post_order):
+            for fixer in order:
+                fixer.log = self.fixer_log
 
     def _check(self, before, after):
         before = support.reformat(before)
@@ -68,11 +44,11 @@
         tree = self._check(before, after)
         self.failUnless(tree.was_changed)
         if not ignore_warnings:
-            self.failUnlessEqual(self.logging_stream.getvalue(), "")
+            self.failUnlessEqual(self.fixer_log, [])
 
     def warns(self, before, after, message, unchanged=False):
         tree = self._check(before, after)
-        self.failUnless(message in self.logging_stream.getvalue())
+        self.failUnless(message in "".join(self.fixer_log))
         if not unchanged:
             self.failUnless(tree.was_changed)
 
@@ -82,7 +58,7 @@
     def unchanged(self, before, ignore_warnings=False):
         self._check(before, before)
         if not ignore_warnings:
-            self.failUnlessEqual(self.logging_stream.getvalue(), "")
+            self.failUnlessEqual(self.fixer_log, [])
 
 
 class Test_ne(FixerTestCase):


More information about the Python-checkins mailing list