Browse files

Fixed logging of mixes of strings and unicode

If the format and the message are not of the same type, try to make them
uniform before trying again.

If a string reaches the format_and_encode() method, assume it is in the right
encoding and don't try to "encode" it (because str.encode() implies an ascii
strict decoding, which will break at the first non-ascii char)
  • Loading branch information...
1 parent 7d0dea3 commit 3fdc11f2d4cee479d25f400dc72596ef095c4629 @dvarrazzo dvarrazzo committed Dec 5, 2012
Showing with 14 additions and 2 deletions.
  1. +14 −2 logbook/
@@ -357,7 +357,18 @@ def _set_format_string(self, value):
del _get_format_string, _set_format_string
def format_record(self, record, handler):
- return self._formatter.format(record=record, handler=handler)
+ try:
+ return self._formatter.format(record=record, handler=handler)
+ except UnicodeEncodeError:
+ # self._formatter is a str, but some of the record items
+ # are unicode
+ fmt = self._formatter.decode('ascii', 'replace')
+ return fmt.format(record=record, handler=handler)
+ except UnicodeDecodeError:
+ # self._formatter is unicode, but some of the record items
+ # are non-ascii str
+ fmt = self._formatter.encode('ascii', 'replace')
+ return fmt.format(record=record, handler=handler)
def format_exception(self, record):
return record.formatted_exception
@@ -538,7 +549,8 @@ def format_and_encode(self, record):
"""Formats the record and encodes it to the stream encoding."""
stream =
rv = self.format(record) + '\n'
- if not _py3 or not _is_text_stream(stream):
+ if isinstance(rv, unicode) \
+ and (not _py3 or not _is_text_stream(stream)):
enc = self.encoding
if enc is None:
enc = getattr(stream, 'encoding', None) or 'utf-8'

0 comments on commit 3fdc11f

Please sign in to comment.