[Pytest-commit] commit/py: hpk42: fix unicode related issues -- but this changing two things currently.

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Jan 22 17:37:52 CET 2014


1 new commit in py:

https://bitbucket.org/hpk42/py/commits/a890a2fd1e8b/
Changeset:   a890a2fd1e8b
User:        hpk42
Date:        2014-01-22 17:37:22
Summary:     fix unicode related issues -- but this changing two things currently.
Affected #:  7 files

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,12 @@
 
 - ignore unicode decode errors in xmlescape.  Thanks Anatoly Bubenkoff.
 
+- on python2 modify traceback.format_exception_only to match python3 
+  behaviour, namely trying to print unicode for Exception instances
+
+- use a safer way for serializing exception reports (helps to fix
+  pytest issue413)
+
 Changes between 1.4.18 and 1.4.19
 ==================================================
 

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 py/__init__.py
--- a/py/__init__.py
+++ b/py/__init__.py
@@ -8,7 +8,7 @@
 
 (c) Holger Krekel and others, 2004-2013
 """
-__version__ = '1.4.20'
+__version__ = '1.4.20.dev2'
 
 from py import _apipkg
 

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 py/_code/code.py
--- a/py/_code/code.py
+++ b/py/_code/code.py
@@ -6,6 +6,35 @@
 
 reprlib = py.builtin._tryimport('repr', 'reprlib')
 
+if sys.version_info[0] >= 3:
+    from traceback import format_exception_only
+else:
+    import traceback
+    def format_exception_only(etype, evalue):
+        """ return list of unicode strings if possible (otherwise bytestrings)
+        """
+        # we patch traceback._some_str to try return unicode to have nicer
+        # printing of exceptions with unicode attributes in tracebacks.
+        # Alternative to monkeypatching we would need to copy
+        # python-2.7's format_exception_only and its induced functions
+        # -- which seems like overkill.
+        def somestr(value):
+            try:
+                return unicode(value)
+            except Exception:
+                try:
+                    return str(value)
+                except Exception:
+                    pass
+            return '<unprintable %s object>' % type(value).__name__
+
+        old = traceback._some_str
+        traceback._some_str = somestr
+        try:
+            return traceback.format_exception_only(etype, evalue)
+        finally:
+            traceback._some_str = old
+
 class Code(object):
     """ wrapper around Python code objects """
     def __init__(self, rawcode):
@@ -374,7 +403,7 @@
         if isinstance(value, AssertionError) and hasattr(value, 'msg'):
             return ['AssertionError: ' + value.msg]
         else:
-            return py.std.traceback.format_exception_only(etype, value)
+            return format_exception_only(etype, value)
 
     def errisinstance(self, exc):
         """ return True if the exception is an instance of exc """
@@ -594,22 +623,16 @@
         return s
 
     def __unicode__(self):
-        l = []
-        tw = py.io.TerminalWriter(l.append)
+        # FYI this is called from pytest-xdist's serialization of exception
+        # information.
+        io = py.io.TextIO()
+        tw = py.io.TerminalWriter(file=io)
         self.toterminal(tw)
-        l = map(unicode_or_repr, l)
-        return "".join(l).strip()
+        return io.getvalue().strip()
 
     def __repr__(self):
         return "<%s instance at %0x>" %(self.__class__, id(self))
 
-def unicode_or_repr(obj):
-    try:
-        return py.builtin._totext(obj)
-    except KeyboardInterrupt:
-        raise
-    except Exception:
-        return "<print-error: %r>" % py.io.saferepr(obj)
 
 class ReprExceptionInfo(TerminalRepr):
     def __init__(self, reprtraceback, reprcrash):

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 setup.py
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@
         name='py',
         description='library with cross-python path, ini-parsing, io, code, log facilities',
         long_description = open('README.txt').read(),
-        version='1.4.20',
+        version='1.4.20.dev2',
         url='http://pylib.readthedocs.org/',
         license='MIT license',
         platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 testing/code/test_code.py
--- a/testing/code/test_code.py
+++ b/testing/code/test_code.py
@@ -89,23 +89,6 @@
     if sys.version_info[0] < 3:
         u = unicode(excinfo)
 
-def test_unicode_or_repr():
-    from py._code.code import unicode_or_repr
-    assert unicode_or_repr('hello') == "hello"
-    if sys.version_info[0] < 3:
-        s = unicode_or_repr('\xf6\xc4\x85')
-    else:
-        s = eval("unicode_or_repr(b'\\f6\\xc4\\x85')")
-    assert 'print-error' in s
-    assert 'c4' in s
-    class A:
-        def __repr__(self):
-            raise ValueError()
-    s = unicode_or_repr(A())
-    assert 'print-error' in s
-    assert 'ValueError' in s
-
-
 def test_code_getargs():
     def f1(x):
         pass

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 testing/code/test_excinfo.py
--- a/testing/code/test_excinfo.py
+++ b/testing/code/test_excinfo.py
@@ -727,6 +727,14 @@
                 assert isinstance(repr, ReprExceptionInfo)
                 assert repr.reprtraceback.style == style
 
+    def test_reprexcinfo_unicode(self):
+        from py._code.code import TerminalRepr
+        class MyRepr(TerminalRepr):
+            def toterminal(self, tw):
+                tw.line(py.builtin._totext("я", "utf-8"))
+        x = py.builtin._totext(MyRepr())
+        assert x == py.builtin._totext("я", "utf-8")
+
     def test_toterminal_long(self, importasmod):
         mod = importasmod("""
             def g(x):

diff -r 509aef38de37c70f12d1b706f8b69b0e712bbfe2 -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 testing/io_/test_saferepr.py
--- a/testing/io_/test_saferepr.py
+++ b/testing/io_/test_saferepr.py
@@ -76,18 +76,3 @@
     if sys.version_info[0] < 3:
         u = unicode(excinfo)
 
-def test_unicode_or_repr():
-    from py._code.code import unicode_or_repr
-    assert unicode_or_repr('hello') == "hello"
-    if sys.version_info[0] < 3:
-        s = unicode_or_repr('\xf6\xc4\x85')
-    else:
-        s = eval("unicode_or_repr(b'\\f6\\xc4\\x85')")
-    assert 'print-error' in s
-    assert 'c4' in s
-    class A:
-        def __repr__(self):
-            raise ValueError()
-    s = unicode_or_repr(A())
-    assert 'print-error' in s
-    assert 'ValueError' in s

Repository URL: https://bitbucket.org/hpk42/py/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the pytest-commit mailing list