[Python-checkins] r85848 - in python/branches/py3k/Lib: logging/__init__.py test/test_logging.py

vinay.sajip python-checkins at python.org
Tue Oct 26 15:16:12 CEST 2010


Author: vinay.sajip
Date: Tue Oct 26 15:16:11 2010
New Revision: 85848

Log:
logging: Improved Formatter implementation.

Modified:
   python/branches/py3k/Lib/logging/__init__.py
   python/branches/py3k/Lib/test/test_logging.py

Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py	(original)
+++ python/branches/py3k/Lib/logging/__init__.py	Tue Oct 26 15:16:11 2010
@@ -24,6 +24,7 @@
 """
 
 import sys, os, time, io, traceback, warnings, weakref
+from string import Template
 
 __all__ = ['BASIC_FORMAT', 'BufferingFormatter', 'CRITICAL', 'DEBUG', 'ERROR',
            'FATAL', 'FileHandler', 'Filter', 'Formatter', 'Handler', 'INFO',
@@ -351,6 +352,49 @@
 #   Formatter classes and functions
 #---------------------------------------------------------------------------
 
+class PercentStyle(object):
+
+    default_format = '%(message)s'
+    asctime_format = '%(asctime)s'
+
+    def __init__(self, fmt):
+        self._fmt = fmt or self.default_format
+
+    def usesTime(self):
+        return self._fmt.find(self.asctime_format) >= 0
+
+    def format(self, record):
+        return self._fmt % record.__dict__
+
+class StrFormatStyle(PercentStyle):
+    default_format = '{message}'
+    asctime_format = '{asctime}'
+
+    def format(self, record):
+        return self._fmt.format(**record.__dict__)
+
+
+class StringTemplateStyle(PercentStyle):
+    default_format = '${message}'
+    asctime_format = '${asctime}'
+
+    def __init__(self, fmt):
+        self._fmt = fmt or self.default_format
+        self._tpl = Template(self._fmt)
+
+    def usesTime(self):
+        fmt = self._fmt
+        return fmt.find('$asctime') >= 0 or fmt.find(self.asctime_format) >= 0
+
+    def format(self, record):
+        return self._tpl.substitute(**record.__dict__)
+
+_STYLES = {
+    '%': PercentStyle,
+    '{': StrFormatStyle,
+    '$': StringTemplateStyle
+}
+
 class Formatter(object):
     """
     Formatter instances are used to convert a LogRecord to text.
@@ -410,18 +454,11 @@
         .. versionchanged: 3.2
            Added the ``style`` parameter.
         """
-        if style not in ('%', '$', '{'):
-            style = '%'
-        self._style = style
-        if fmt:
-            self._fmt = fmt
-        else:
-            if style == '%':
-                self._fmt = "%(message)s"
-            elif style == '{':
-                self._fmt = '{message}'
-            else:
-                self._fmt = '${message}'
+        if style not in _STYLES:
+            raise ValueError('Style must be one of: %s' % ','.join(
+                             _STYLES.keys()))
+        self._style = _STYLES[style](fmt)
+        self._fmt = self._style._fmt
         self.datefmt = datefmt
 
     def formatTime(self, record, datefmt=None):
@@ -473,25 +510,10 @@
         """
         Check if the format uses the creation time of the record.
         """
-        if self._style == '%':
-            result = self._fmt.find("%(asctime)") >= 0
-        elif self._style == '$':
-            result = self._fmt.find("{asctime}") >= 0
-        else:
-            result = self._fmt.find("$asctime") >= 0 or \
-                     self._fmt.find("${asctime}") >= 0
-        return result
+        return self._style.usesTime()
 
     def formatMessage(self, record):
-        style = self._style
-        if style == '%':
-            s = self._fmt % record.__dict__
-        elif style == '{':
-            s = self._fmt.format(**record.__dict__)
-        else:
-            from string import Template
-            s = Template(self._fmt).substitute(**record.__dict__)
-        return s
+        return self._style.format(record)
 
     def format(self, record):
         """

Modified: python/branches/py3k/Lib/test/test_logging.py
==============================================================================
--- python/branches/py3k/Lib/test/test_logging.py	(original)
+++ python/branches/py3k/Lib/test/test_logging.py	Tue Oct 26 15:16:11 2010
@@ -1891,6 +1891,11 @@
         self.assertEqual(f.format(r), '${Message with 2 placeholders}')
         f = logging.Formatter('%(random)s')
         self.assertRaises(KeyError, f.format, r)
+        self.assertFalse(f.usesTime())
+        f = logging.Formatter('%(asctime)s')
+        self.assertTrue(f.usesTime())
+        f = logging.Formatter('asctime')
+        self.assertFalse(f.usesTime())
 
     def test_braces(self):
         "Test {}-formatting"
@@ -1899,6 +1904,11 @@
         self.assertEqual(f.format(r), '$%Message with 2 placeholders%$')
         f = logging.Formatter('{random}', style='{')
         self.assertRaises(KeyError, f.format, r)
+        self.assertFalse(f.usesTime())
+        f = logging.Formatter('{asctime}', style='{')
+        self.assertTrue(f.usesTime())
+        f = logging.Formatter('asctime', style='{')
+        self.assertFalse(f.usesTime())
 
     def test_dollars(self):
         "Test $-formatting"
@@ -1909,6 +1919,13 @@
         self.assertEqual(f.format(r), '$%Message with 2 placeholders%$')
         f = logging.Formatter('${random}', style='$')
         self.assertRaises(KeyError, f.format, r)
+        self.assertFalse(f.usesTime())
+        f = logging.Formatter('${asctime}', style='$')
+        self.assertTrue(f.usesTime())
+        f = logging.Formatter('$asctime', style='$')
+        self.assertTrue(f.usesTime())
+        f = logging.Formatter('asctime', style='$')
+        self.assertFalse(f.usesTime())
 
 class BaseFileTest(BaseTest):
     "Base class for handler tests that write log files"


More information about the Python-checkins mailing list