[Pytest-commit] commit/py: hpk42: rather than monkeypatching use a copy of the involved

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Jan 22 18:09:22 CET 2014


1 new commit in py:

https://bitbucket.org/hpk42/py/commits/13d9af95547e/
Changeset:   13d9af95547e
User:        hpk42
Date:        2014-01-22 18:08:50
Summary:     rather than monkeypatching use a copy of the involved
code for traceback.format_exception_only and simplify
invocation places.
Affected #:  2 files

diff -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 -r 13d9af95547ea14b2e33e2994ff96e182da225c4 py/_code/_py2traceback.py
--- /dev/null
+++ b/py/_code/_py2traceback.py
@@ -0,0 +1,79 @@
+# copied from python-2.7.3's traceback.py
+# CHANGES:
+# - some_str is replaced, trying to create unicode strings
+#
+import types
+
+def format_exception_only(etype, value):
+    """Format the exception part of a traceback.
+
+    The arguments are the exception type and value such as given by
+    sys.last_type and sys.last_value. The return value is a list of
+    strings, each ending in a newline.
+
+    Normally, the list contains a single string; however, for
+    SyntaxError exceptions, it contains several lines that (when
+    printed) display detailed information about where the syntax
+    error occurred.
+
+    The message indicating which exception occurred is always the last
+    string in the list.
+
+    """
+
+    # An instance should not have a meaningful value parameter, but
+    # sometimes does, particularly for string exceptions, such as
+    # >>> raise string1, string2  # deprecated
+    #
+    # Clear these out first because issubtype(string1, SyntaxError)
+    # would throw another exception and mask the original problem.
+    if (isinstance(etype, BaseException) or
+        isinstance(etype, types.InstanceType) or
+        etype is None or type(etype) is str):
+        return [_format_final_exc_line(etype, value)]
+
+    stype = etype.__name__
+
+    if not issubclass(etype, SyntaxError):
+        return [_format_final_exc_line(stype, value)]
+
+    # It was a syntax error; show exactly where the problem was found.
+    lines = []
+    try:
+        msg, (filename, lineno, offset, badline) = value.args
+    except Exception:
+        pass
+    else:
+        filename = filename or "<string>"
+        lines.append('  File "%s", line %d\n' % (filename, lineno))
+        if badline is not None:
+            lines.append('    %s\n' % badline.strip())
+            if offset is not None:
+                caretspace = badline.rstrip('\n')[:offset].lstrip()
+                # non-space whitespace (likes tabs) must be kept for alignment
+                caretspace = ((c.isspace() and c or ' ') for c in caretspace)
+                # only three spaces to account for offset1 == pos 0
+                lines.append('   %s^\n' % ''.join(caretspace))
+        value = msg
+
+    lines.append(_format_final_exc_line(stype, value))
+    return lines
+
+def _format_final_exc_line(etype, value):
+    """Return a list of a single line -- normal case for format_exception_only"""
+    valuestr = _some_str(value)
+    if value is None or not valuestr:
+        line = "%s\n" % etype
+    else:
+        line = "%s: %s\n" % (etype, valuestr)
+    return line
+
+def _some_str(value):
+    try:
+        return unicode(value)
+    except Exception:
+        try:
+            return str(value)
+        except Exception:
+            pass
+    return '<unprintable %s object>' % type(value).__name__

diff -r a890a2fd1e8b3004cec17fce5c363241ca1161f7 -r 13d9af95547ea14b2e33e2994ff96e182da225c4 py/_code/code.py
--- a/py/_code/code.py
+++ b/py/_code/code.py
@@ -9,31 +9,7 @@
 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
+    from py._code._py2traceback import format_exception_only
 
 class Code(object):
     """ wrapper around Python code objects """
@@ -386,7 +362,7 @@
             the exception representation is returned (so 'AssertionError: ' is
             removed from the beginning)
         """
-        lines = self._format_exception_only(self.type, self.value)
+        lines = format_exception_only(self.type, self.value)
         text = ''.join(lines)
         text = text.rstrip()
         if tryshort:
@@ -394,17 +370,6 @@
                 text = text[len(self._striptext):]
         return text
 
-    def _format_exception_only(self, etype, value):
-        """Format the exception part of a traceback
-
-        Since traceback.format_exception_only() destroys unicode on
-        python 2 we handle plain AsssertionErrors separately here.
-        """
-        if isinstance(value, AssertionError) and hasattr(value, 'msg'):
-            return ['AssertionError: ' + value.msg]
-        else:
-            return format_exception_only(etype, value)
-
     def errisinstance(self, exc):
         """ return True if the exception is an instance of exc """
         return isinstance(self.value, exc)

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