[Python-checkins] r85835 - in python/branches/py3k: Doc/library/logging.rst Lib/logging/__init__.py Lib/test/test_logging.py Misc/NEWS

vinay.sajip python-checkins at python.org
Mon Oct 25 15:57:40 CEST 2010


Author: vinay.sajip
Date: Mon Oct 25 15:57:39 2010
New Revision: 85835
Log:
logging: Added style option to Formatter to allow %, {} or himBHformatting.
Modified:
 python/branches/py3k/Doc/library/logging.rst
 python/branches/py3k/Lib/logging/__init__.py
 python/branches/py3k/Lib/test/test_logging.py
 python/branches/py3k/Misc/NEWS
Modified: python/branches/py3k/Doc/library/logging.rst
==============================================================================
--- python/branches/py3k/Doc/library/logging.rst	(original)
+++ python/branches/py3k/Doc/library/logging.rst	Mon Oct 25 15:57:39 2010
@@ -301,17 +301,29 @@
 Formatter objects configure the final order, structure, and contents of the log
 message. Unlike the base :class:`logging.Handler` class, application code may
 instantiate formatter classes, although you could likely subclass the formatter
-if your application needs special behavior. The constructor takes two optional
-arguments: a message format string and a date format string. If there is no
-message format string, the default is to use the raw message. If there is no
-date format string, the default date format is::
+if your application needs special behavior. The constructor takes three
+optional arguments -- a message format string, a date format string and a style
+indicator.
+
+.. method:: logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
+
+If there is no message format string, the default is to use the
+raw message. If there is no date format string, the default date format is::
 
 %Y-%m-%d %H:%M:%S
 
-with the milliseconds tacked on at the end.
+with the milliseconds tacked on at the end. The ``style`` is one of `%`, '{'
+or '$'. If one of these is not specified, then '%' will be used.
 
-The message format string uses ``%(<dictionary key>)s`` styled string
-substitution; the possible keys are documented in :ref:`formatter-objects`.
+If the ``style`` is '%', the message format string uses
+``%(<dictionary key>)s`` styled string substitution; the possible keys are
+documented in :ref:`formatter-objects`. If the style is '{', the message format
+string is assumed to be compatible with :meth:`str.format` (using keyword
+arguments), while if the style is '$' then the message format string should
+conform to what is expected by :meth:`string.Template.substitute`.
+
+.. versionchanged:: 3.2
+ Added the ``style`` parameter.
 
 The following message format string will log the time in a human-readable
 format, the severity of the message, and the contents of the message, in that
Modified: python/branches/py3k/Lib/logging/__init__.py
==============================================================================
--- python/branches/py3k/Lib/logging/__init__.py	(original)
+++ python/branches/py3k/Lib/logging/__init__.py	Mon Oct 25 15:57:39 2010
@@ -395,18 +395,33 @@
 
 converter = time.localtime
 
- def __init__(self, fmt=None, datefmt=None):
+ def __init__(self, fmt=None, datefmt=None, style='%'):
 """
 Initialize the formatter with specified format strings.
 
 Initialize the formatter either with the specified format string, or a
 default as described above. Allow for specialized date formatting with
 the optional datefmt argument (if omitted, you get the ISO8601 format).
+
+ Use a style parameter of '%', '{' or '$' to specify that you want to
+ use one of %-formatting, :meth:`str.format` (``{}``) formatting or
+ :class:`string.Template` formatting in your format string.
+
+ .. versionchanged: 3.2
+ Added the ``style`` parameter.
 """
+ if style not in ('%', '$', '{'):
+ style = '%'
+ self._style = style
 if fmt:
 self._fmt = fmt
 else:
- self._fmt = "%(message)s"
+ if style == '%':
+ self._fmt = "%(message)s"
+ elif style == '{':
+ self._fmt = '{message}'
+ else:
+ self._fmt = '${message}'
 self.datefmt = datefmt
 
 def formatTime(self, record, datefmt=None):
@@ -432,7 +447,7 @@
 s = time.strftime(datefmt, ct)
 else:
 t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
- s = "%s,%03d" % (t, record.msecs)
+ s = "%s,%03d" % (t, record.msecs) # the use of % here is internal
 return s
 
 def formatException(self, ei):
@@ -458,7 +473,14 @@
 """
 Check if the format uses the creation time of the record.
 """
- return self._fmt.find("%(asctime)") >= 0
+ 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
 
 def format(self, record):
 """
@@ -476,7 +498,14 @@
 record.message = record.getMessage()
 if self.usesTime():
 record.asctime = self.formatTime(record, self.datefmt)
- s = self._fmt % record.__dict__
+ 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__)
 if record.exc_info:
 # Cache the traceback text to avoid converting it multiple times
 # (it's constant anyway)
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	Mon Oct 25 15:57:39 2010
@@ -1863,6 +1863,53 @@
 self.assertEqual(data.name, self.que_logger.name)
 self.assertEqual((data.msg, data.args), (msg, None))
 
+class FormatterTest(unittest.TestCase):
+ def setUp(self):
+ self.common = {
+ 'name': 'formatter.test',
+ 'level': logging.DEBUG,
+ 'pathname': os.path.join('path', 'to', 'dummy.ext'),
+ 'lineno': 42,
+ 'exc_info': None,
+ 'func': None,
+ 'msg': 'Message with %d %s',
+ 'args': (2, 'placeholders'),
+ }
+ self.variants = {
+ }
+
+ def get_record(self, name=None):
+ result = dict(self.common)
+ if name is not None:
+ result.update(self.variants[name])
+ return logging.makeLogRecord(result)
+
+ def test_percent(self):
+ "Test %-formatting"
+ r = self.get_record()
+ f = logging.Formatter('${%(message)s}')
+ self.assertEqual(f.format(r), '${Message with 2 placeholders}')
+ f = logging.Formatter('%(random)s')
+ self.assertRaises(KeyError, f.format, r)
+
+ def test_braces(self):
+ "Test {}-formatting"
+ r = self.get_record()
+ f = logging.Formatter('$%{message}%$', style='{')
+ self.assertEqual(f.format(r), '$%Message with 2 placeholders%$')
+ f = logging.Formatter('{random}', style='{')
+ self.assertRaises(KeyError, f.format, r)
+
+ def test_dollars(self):
+ "Test $-formatting"
+ r = self.get_record()
+ f = logging.Formatter('$message', style='$')
+ self.assertEqual(f.format(r), 'Message with 2 placeholders')
+ f = logging.Formatter('$$%${message}%$$', style='$')
+ self.assertEqual(f.format(r), '$%Message with 2 placeholders%$')
+ f = logging.Formatter('${random}', style='$')
+ self.assertRaises(KeyError, f.format, r)
+
 class BaseFileTest(BaseTest):
 "Base class for handler tests that write log files"
 
@@ -1945,6 +1992,7 @@
 CustomLevelsAndFiltersTest, MemoryHandlerTest,
 ConfigFileTest, SocketHandlerTest, MemoryTest,
 EncodingTest, WarningsTest, ConfigDictTest, ManagerTest,
+ FormatterTest,
 LogRecordClassTest, ChildLoggerTest, QueueHandlerTest,
 RotatingFileHandlerTest,
 #TimedRotatingFileHandlerTest
Modified: python/branches/py3k/Misc/NEWS
==============================================================================
--- python/branches/py3k/Misc/NEWS	(original)
+++ python/branches/py3k/Misc/NEWS	Mon Oct 25 15:57:39 2010
@@ -51,6 +51,8 @@
 Library
 -------
 
+- logging: Added style option to Formatter to allow %, {} or $-formatting.
+
 - Issue #5178: Added tempfile.TemporaryDirectory class that can be used
 as a context manager.
 


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /