[Python-Dev] Change to logging Formatters: support for alternative format styles

Nick Coghlan ncoghlan at gmail.com
Tue Oct 26 13:08:24 CEST 2010


On Tue, Oct 26, 2010 at 12:28 AM, Vinay Sajip <vinay_sajip at yahoo.co.uk> wrote:
> Comments welcome. Assuming there are no strong objections asking for reversion
> of this change, I'll publicise to the wider community in a few days.

It strikes me as a solid, pragmatic solution to a thorny problem.

Looking at your checkin though, I wonder if it might be worth
implementing some little formatting style classes to get rid of the
if/elif chains from the Formatter code. Something like:

# Style objects
class PercentStyle(object):
  default_format = "%(message)"
  def is_asctime_in_format(fmt):
    return fmt.find("%(asctime)") >= 0
  def format_record(fmt, record):
    return fmt % record.__dict__

class StrFormatStyle(object):
  default_format = "{message}"
  def is_asctime_in_format(fmt):
    return fmt.find("{asctime}") >= 0
  def format_record(fmt, record):
    return fmt.format(**record.__dict__)

from string import Template # Top level, embedding may cause import
deadlock issues
class StringTemplateStyle(object):
  def __init__(self):
    self._fmt = self._tmpl = None # Setup for format_record
  default_format = "${message}"
  def is_asctime_in_format(fmt):
    return fmt.find("$asctime") >= 0 or fmt.find("${asctime}") >= 0
  def format_record(fmt, record):
    if fmt != self._fmt:
      self._fmt = fmt
      self._tmpl = Template(fmt)
    return self._tmpl.substitute(**record.__dict__)

# Build style map
_STYLE_CODES = tuple("% { $".split())
_STYLES = PercentStyle, StrFormatStyle, StringTemplateStyle
_STYLE_MAP = dict(zip(_STYLE_CODES, _STYLES))

# Interpretation of the style parameter in Formatter.__init__
if style not in _STYLE_CODES:
  # Preserve option to allow arbitrary style objects at some point in the future
  raise ValueError("Style must be one of {!r}".format(_STYLE_CODES))
self._style = _STYLE_MAP[style]()

# self._fmt initialisation if/elif chain replacement
self._fmt = self._style.default_format

# Time check if/elif chain replacement
result = self._style.is_asctime_in_format(self._fmt)

# Record formatting if/elif chain replacement
s = self._style.format_record(self._fmt, record)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia


More information about the Python-Dev mailing list