mirror of
https://github.com/beetbox/beets.git
synced 2025-12-12 03:24:44 +01:00
Logging: pass through non-problematic values
9b83cef was a little too aggressive; we need most objects to go through
unconverted so '{0.title}' and such still work in format strings. This is now
just a targeted workaround for the case I encountered.
This commit is contained in:
parent
9b83cef0de
commit
7e21c68487
1 changed files with 17 additions and 5 deletions
|
|
@ -24,6 +24,7 @@ from __future__ import absolute_import
|
|||
from copy import copy
|
||||
from logging import * # noqa
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
|
||||
# We need special hacks for Python 2.6 due to logging.Logger being an
|
||||
|
|
@ -31,8 +32,9 @@ import sys
|
|||
PY26 = sys.version_info[:2] == (2, 6)
|
||||
|
||||
|
||||
def as_unicode(val):
|
||||
"""Coerce a value to Unicode for displaying in a log message.
|
||||
def logsafe(val):
|
||||
"""Coerce a potentially "problematic" value so it can be formatted
|
||||
in a Unicode log string.
|
||||
|
||||
This works around a number of pitfalls when logging objects in
|
||||
Python 2:
|
||||
|
|
@ -42,15 +44,20 @@ def as_unicode(val):
|
|||
`unicode(v)` while `str(v)` works fine. CalledProcessError is an
|
||||
example.
|
||||
"""
|
||||
# Already Unicode.
|
||||
if isinstance(val, unicode):
|
||||
return val
|
||||
|
||||
# Bytestring: needs decoding.
|
||||
elif isinstance(val, bytes):
|
||||
# Blindly convert with UTF-8. Eventually, it would be nice to
|
||||
# (a) only do this for paths, if they can be given a distinct
|
||||
# type, and (b) warn the developer if they do this for other
|
||||
# bytestrings.
|
||||
return val.decode('utf8', 'replace')
|
||||
else:
|
||||
|
||||
# A "problem" object: needs a workaround.
|
||||
elif isinstance(val, subprocess.CalledProcessError):
|
||||
try:
|
||||
return unicode(val)
|
||||
except UnicodeDecodeError:
|
||||
|
|
@ -58,6 +65,11 @@ def as_unicode(val):
|
|||
# instead.
|
||||
return str(val).decode('utf8', 'replace')
|
||||
|
||||
# Other objects are used as-is so field access, etc., still works in
|
||||
# the format string.
|
||||
else:
|
||||
return val
|
||||
|
||||
|
||||
class StrFormatLogger(Logger):
|
||||
"""A version of `Logger` that uses `str.format`-style formatting
|
||||
|
|
@ -71,8 +83,8 @@ class StrFormatLogger(Logger):
|
|||
self.kwargs = kwargs
|
||||
|
||||
def __str__(self):
|
||||
args = [as_unicode(a) for a in self.args]
|
||||
kwargs = dict((k, as_unicode(v)) for (k, v) in self.kwargs.items())
|
||||
args = [logsafe(a) for a in self.args]
|
||||
kwargs = dict((k, logsafe(v)) for (k, v) in self.kwargs.items())
|
||||
return self.msg.format(*args, **kwargs)
|
||||
|
||||
def _log(self, level, msg, args, exc_info=None, extra=None, **kwargs):
|
||||
|
|
|
|||
Loading…
Reference in a new issue