[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