Port beets.logging to python 2.6

Multiple hacks :-)
This commit is contained in:
Bruno Cauet 2015-01-05 09:15:18 +01:00
parent 45db930457
commit 06f0e1dee1
2 changed files with 40 additions and 5 deletions

View file

@ -2,11 +2,15 @@
Provide everything the "logging" module does, the only difference is that when
getLogger(name) instantiates a logger that logger uses {}-style formatting.
It requires special hacks for python 2.6 due to logging.Logger being an old-
style class and having no loggerClass attribute.
"""
from __future__ import absolute_import
from copy import copy
from logging import * # noqa
import sys
# create a str.format-based logger
@ -23,8 +27,21 @@ class StrFormatLogger(Logger):
def _log(self, level, msg, args, exc_info=None, extra=None, **kwargs):
"""Log msg.format(*args, **kwargs)"""
m = self._LogMessage(msg, args, kwargs)
return super(StrFormatLogger, self)._log(level, m, (), exc_info, extra)
return Logger._log(self, level, m, (), exc_info, extra)
# we cannot call super(StrFormatLogger, self) because it is not
# allowed on old-style classes (py2) which Logger is in python 2.6
# moreover we cannot make StrFormatLogger a new-style class (by
# declaring 'class StrFormatLogger(Logger, object)' because the class-
# patching stmt 'logger.__class__ = StrFormatLogger' would not work:
# both prev & new __class__ values must be either old- or new- style,
# no mixing allowed.
if sys.version_info[:2] == (2, 6):
def getChild(self, suffix):
"""Shameless copy from cpython's Lib/logging/__init__.py"""
if self.root is not self:
suffix = '.'.join((self.name, suffix))
return self.manager.getLogger(suffix)
my_manager = copy(Logger.manager)
my_manager.loggerClass = StrFormatLogger
@ -35,3 +52,21 @@ def getLogger(name=None):
return my_manager.getLogger(name)
else:
return root
if sys.version_info[:2] == (2, 6):
# no Manager.loggerClass so we dynamically change the logger class
# we must be careful to do that on new loggers only to avoid side-effects.
# Wrap Manager.getLogger
old_getLogger = my_manager.getLogger
def new_getLogger(name):
change_its_type = not isinstance(my_manager.loggerDict.get(name),
Logger)
# it either does not exist or is a placeholder
logger = old_getLogger(name)
if change_its_type:
logger.__class__ = StrFormatLogger
return logger
my_manager.getLogger = new_getLogger

View file

@ -11,15 +11,15 @@ class LoggingTest(TestCase):
l1 = log.getLogger("foo123")
l2 = blog.getLogger("foo123")
self.assertEqual(l1, l2)
self.assertEqual(type(l1), log.Logger)
self.assertEqual(l1.__class__, log.Logger)
l3 = blog.getLogger("bar123")
l4 = log.getLogger("bar123")
self.assertEqual(l3, l4)
self.assertEqual(type(l3), blog.StrFormatLogger)
self.assertEqual(l3.__class__, blog.StrFormatLogger)
l5 = l3.getChild("shalala")
self.assertEqual(type(l5), blog.StrFormatLogger)
self.assertEqual(l5.__class__, blog.StrFormatLogger)
def test_str_format_logging(self):
l = blog.getLogger("baz123")
@ -29,7 +29,7 @@ class LoggingTest(TestCase):
l.addHandler(handler)
l.propagate = False
l.warning("foo {} {bar}", "oof", bar="baz")
l.warning("foo {0} {bar}", "oof", bar="baz")
handler.flush()
self.assertTrue(stream.getvalue(), "foo oof baz")