diff options
author | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2010-10-26 13:16:11 (GMT) |
---|---|---|
committer | Vinay Sajip <vinay_sajip@yahoo.co.uk> | 2010-10-26 13:16:11 (GMT) |
commit | 6a65c5df869f2526711ff00c07ca28e2dc394372 (patch) | |
tree | c02ab0cdb45c1995b2b64d622635f639666a47d4 /Lib | |
parent | ba488d150492aa6ded31da7b055cd85a152dd611 (diff) | |
download | cpython-6a65c5df869f2526711ff00c07ca28e2dc394372.zip cpython-6a65c5df869f2526711ff00c07ca28e2dc394372.tar.gz cpython-6a65c5df869f2526711ff00c07ca28e2dc394372.tar.bz2 |
logging: Improved Formatter implementation.
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/logging/__init__.py | 80 | ||||
-rw-r--r-- | Lib/test/test_logging.py | 17 |
2 files changed, 68 insertions, 29 deletions
diff --git a/Lib/logging/__init__.py b/Lib/logging/__init__.py index b6dd233..37c78cb 100644 --- a/Lib/logging/__init__.py +++ b/Lib/logging/__init__.py @@ -24,6 +24,7 @@ To use, simply 'import logging' and log away! """ 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 @@ def makeLogRecord(dict): # 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 @@ class Formatter(object): .. 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 @@ class Formatter(object): """ 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): """ diff --git a/Lib/test/test_logging.py b/Lib/test/test_logging.py index 9aa6af3..11e18d8 100644 --- a/Lib/test/test_logging.py +++ b/Lib/test/test_logging.py @@ -1891,6 +1891,11 @@ class FormatterTest(unittest.TestCase): 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 @@ class FormatterTest(unittest.TestCase): 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 @@ class FormatterTest(unittest.TestCase): 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" |