summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorVinay Sajip <vinay_sajip@yahoo.co.uk>2010-10-26 13:16:11 (GMT)
committerVinay Sajip <vinay_sajip@yahoo.co.uk>2010-10-26 13:16:11 (GMT)
commit6a65c5df869f2526711ff00c07ca28e2dc394372 (patch)
treec02ab0cdb45c1995b2b64d622635f639666a47d4 /Lib
parentba488d150492aa6ded31da7b055cd85a152dd611 (diff)
downloadcpython-6a65c5df869f2526711ff00c07ca28e2dc394372.zip
cpython-6a65c5df869f2526711ff00c07ca28e2dc394372.tar.gz
cpython-6a65c5df869f2526711ff00c07ca28e2dc394372.tar.bz2
logging: Improved Formatter implementation.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/logging/__init__.py80
-rw-r--r--Lib/test/test_logging.py17
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"