Skip to content

Commit c53bcde

Browse files
committed
Use unicode() directly to decode an object.
1 parent 6bdaf17 commit c53bcde

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

fluent/handler.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,19 @@ def _build_structure(self, record):
6363
def _decode(self, value):
6464
if value is None:
6565
return None
66-
elif isinstance(value, str):
67-
return unicode(value, self.encoding, errors='replace')
6866
elif isinstance(value, unicode):
6967
return value
68+
elif isinstance(value, basestring):
69+
return unicode(value, self.encoding, errors='replace')
7070
else:
71-
return self._decode(str(value))
71+
try:
72+
return getattr(value, '__unicode__', None)()
73+
except:
74+
pass
75+
try:
76+
return self._decode(unicode(value))
77+
except (TypeError, UnicodeDecodeError):
78+
return self._decode(str(value).encode('string_escape'))
7279

7380
def _fsdecode(self, value):
7481
if value is None:
@@ -94,7 +101,7 @@ def _format_exception(self, exc_info):
94101
if exc_info is not None and exc_info[0] is not None:
95102
return {
96103
'type': exc_info[0].__name__,
97-
'value': [self._decode(str(arg)) for arg in exc_info[1].args],
104+
'value': [self._decode(arg) for arg in exc_info[1].args],
98105
'traceback': traceback.extract_tb(exc_info[2])
99106
}
100107
else:

tests/test_decode.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,23 @@ def test_decode_obj(self):
4343
self.assertTrue(isinstance(result, unicode), type(result).__name__)
4444

4545
self.assertEqual(result, str(marker))
46+
47+
def test_decode_more(self):
48+
handler = self._makeOne('app.follow', encoding='ascii')
49+
self.assertEqual(handler._decode('a'), u'a')
50+
self.assertEqual(handler._decode(u'\u2600'), u'\u2600')
51+
self.assertEqual(handler._decode([1, 2, '3']), u"[1, 2, '3']")
52+
self.assertEqual(handler._decode((1, 2, [3])), u"(1, 2, [3])")
53+
self.assertEqual(handler._decode({'a': u'\u2600', 'c': [1, 2, {'c': 'd'}]}), u"{'a': u'\\u2600', 'c': [1, 2, {'c': 'd'}]}")
54+
55+
class Something(object):
56+
def __unicode__(self):
57+
return u'123'
58+
59+
self.assertEqual(handler._decode(Something()), u'123')
60+
61+
class Something(object):
62+
def __str__(self):
63+
return '\xe3\x98\x80'
64+
65+
self.assertEqual(handler._decode(Something()), u'\\xe3\\x98\\x80')

0 commit comments

Comments
 (0)