Skip to content

Commit

Permalink
Merge 8864-safe_str-unicode: safe_str encodes unicode
Browse files Browse the repository at this point in the history
Author: markrwilliams
Reviewer: Julian
Fixes: twisted#8864

twisted.python.reflect.safe_str encodes unicode as ascii with backslashreplace error handling on Python 2.
  • Loading branch information
markrwilliams authored Oct 22, 2016
2 parents 01611cb + 0300377 commit aa3a7a7
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 6 deletions.
7 changes: 7 additions & 0 deletions src/twisted/python/reflect.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,13 @@ def safe_str(o):
return o.decode('utf-8')
except:
pass
if not _PY3:
# On Python 2, attempt to encode a unicode representation
# first.
try:
return unicode(o).encode('ascii', 'backslashreplace')
except:
pass
try:
return str(o)
except:
Expand Down
11 changes: 5 additions & 6 deletions src/twisted/test/test_log.py
Original file line number Diff line number Diff line change
Expand Up @@ -390,20 +390,19 @@ def testMultipleString(self):

def test_singleUnicode(self):
"""
L{log.LogPublisher.msg} does not accept non-ASCII Unicode on Python 2,
logging an error instead.
L{log.LogPublisher.msg} encodes Unicode as ``ascii`` with
``backslashreplace`` error handling on Python 2.
On Python 3, where Unicode is default message type, the message is
logged normally.
On Python 3, where Unicode is default message type, the
message is logged normally.
"""
message = u"Hello, \N{VULGAR FRACTION ONE HALF} world."
self.lp.msg(message)
self.assertEqual(len(self.out), 1)
if _PY3:
self.assertIn(message, self.out[0])
else:
self.assertIn('with str error', self.out[0])
self.assertIn('UnicodeEncodeError', self.out[0])
self.assertIn(r"Hello, \xbd world", self.out[0])



Expand Down
14 changes: 14 additions & 0 deletions src/twisted/test/test_reflect.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,20 @@ class X(BTBase):
self.assertIn("RuntimeError: str!", xStr)


def test_unicode(self):
"""
A unicode string is encoded to ``ascii`` with
``backslashreplace`` error handling on Python 2.
"""
unicodeString = u'\N{DOUBLE EXCLAMATION MARK} !!'
safe = reflect.safe_str(unicodeString)
self.assertEqual(safe, b'\u203c !!')

if _PY3:
test_unicode.skip = (
"Skip Python 2 specific test for unicode encoding")



class FilenameToModuleTests(TestCase):
"""
Expand Down
1 change: 1 addition & 0 deletions src/twisted/topfiles/8864.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
twisted.python.reflect.safe_str encodes unicode as ascii with backslashreplace error handling on Python 2.

0 comments on commit aa3a7a7

Please sign in to comment.