[py-svn] r56984 - in py/branch/event/py/code: . testing

hpk at codespeak.net hpk at codespeak.net
Mon Aug 4 23:10:57 CEST 2008


Author: hpk
Date: Mon Aug  4 23:10:55 2008
New Revision: 56984

Removed:
   py/branch/event/py/code/format_excinfo.py
   py/branch/event/py/code/testing/test_format_excinfo.py
Modified:
   py/branch/event/py/code/code.py
   py/branch/event/py/code/excinfo.py
   py/branch/event/py/code/testing/test_excinfo.py
   py/branch/event/py/code/traceback2.py
Log:
merge traceback formatting into excinfo.py and
add a format() method that returns a nicely formatted traceback. 


Modified: py/branch/event/py/code/code.py
==============================================================================
--- py/branch/event/py/code/code.py	(original)
+++ py/branch/event/py/code/code.py	Mon Aug  4 23:10:55 2008
@@ -62,7 +62,11 @@
         try:
             return self.raw.co_filename.__path__
         except AttributeError:
-            return py.path.local(self.raw.co_filename)
+            p = py.path.local(self.raw.co_filename)
+            if not p.check() and self.raw.co_filename == "<string>":
+                p = "<string>"
+            return p
+                
     path = property(path, None, None, "path of this code object")
 
     def fullsource(self):

Modified: py/branch/event/py/code/excinfo.py
==============================================================================
--- py/branch/event/py/code/excinfo.py	(original)
+++ py/branch/event/py/code/excinfo.py	Mon Aug  4 23:10:55 2008
@@ -1,6 +1,11 @@
-from __future__ import generators
-import sys
+"""
+
+Exception Info representation + formatting 
+
+"""
 import py
+from py.__.code import safe_repr
+from sys import exc_info 
 
 class ExceptionInfo(object):
     """ wraps sys.exc_info() objects and offers
@@ -11,7 +16,7 @@
         # NB. all attributes are private!  Subclasses or other
         #     ExceptionInfo-like classes may have different attributes.
         if tup is None:
-            tup = sys.exc_info()
+            tup = exc_info()
             if exprinfo is None and isinstance(tup[1], py.magic.AssertionError):
                 exprinfo = tup[1].msg
                 if exprinfo and exprinfo.startswith('assert '):
@@ -42,7 +47,172 @@
         """ return True if the exception is an instance of exc """
         return isinstance(self.value, exc) 
 
+    def _formatrepr(self, **kwargs):
+        formatter = FormattedExcinfo(**kwargs)
+        formatter.repr_tb(self)
+        return formatter
+
+    def format(self, **kwargs):
+        repr = self._formatrepr(**kwargs)
+        tw = py.io.TerminalWriter()
+        repr.writeterminal(tw)
+        return tw.stringio.getvalue()
+
+    def __str__(self):
+        entry = self.traceback[-1]
+        loc = LocationRepr(entry.path, entry.lineno + 1, self.exconly())
+        return str(loc)
+
+class FormattedExcinfo(object):
+    """ presenting information about failing Functions and Generators. """ 
+    # for traceback entries 
+    flow_marker = ">"    
+    fail_marker = "E"
+    
+    def __init__(self, showlocals=False, style="long"):
+        self.lines = []
+        self.showlocals = showlocals
+        self.style = style
+
+    def writeterminal(self, tw):
+        for line in self.lines:
+            if isinstance(line, LineSep):
+                tw.sep(line.sep, line.line)
+            else:
+                tw.line(str(line))
+
+    def _getindent(self, source):
+        # figure out indent 
+        try:
+            s = str(source.getstatement(len(source)-1))
+        except KeyboardInterrupt: 
+            raise 
+        except:
+            s = str(source[-1])
+        return 4 + (len(s) - len(s.lstrip()))
+
+
+    def _getentrysource(self, entry):
+        try:
+            source = entry.getsource()
+        except py.error.ENOENT:
+            source = "???"
+        return source.deindent()
+
+    def _saferepr(self, obj):
+        return safe_repr._repr(obj)
+
+
+    def repr_source(self, source, line_index=-1, excinfo=None):
+        """ represent source with with marker at given index. """
+        if source is None:
+            source = py.code.Source("???")
+            line_index = 0 
+        if line_index < 0:
+            line_index += len(source)
+        for i in range(len(source)):
+            if i == line_index:
+                prefix = self.flow_marker + "   "
+            else:
+                prefix = "    "
+            line = prefix + source[i]
+            self._line(line)
+
+        if excinfo is not None:
+            indent = self._getindent(source)
+            self.repr_exconly(excinfo, indent=indent, markall=True)
+
+    def repr_exconly(self, excinfo, indent=4, markall=False):
+        indent = " " * indent 
+        # get the real exception information out 
+        lines = excinfo.exconly(tryshort=True).split('\n')
+        failindent = self.fail_marker + indent[1:]
+        for line in lines:
+            self._line(failindent + line)
+            if not markall:
+                failindent = indent 
+
+    def repr_locals(self, f_locals):
+        if self.showlocals: 
+            self._sepline('- ', 'locals')
+            for name, value in f_locals.items():
+                if name == '__builtins__': 
+                    self._line("__builtins__ = <builtins>")
+                else:
+                    # This formatting could all be handled by the _repr() function, which is 
+                    # only repr.Repr in disguise, so is very configurable.
+                    str_repr = safe_repr._repr(value)
+                    if len(str_repr) < 70 or not isinstance(value,
+                                                (list, tuple, dict)):
+                        self._line("%-10s = %s" %(name, str_repr))
+                    else:
+                        self._line("%-10s =\\" % (name,))
+                        py.std.pprint.pprint(value, stream=self.excinfowriter)
+
+    def repr_tb_entry(self, entry, excinfo=None):
+        # excinfo is not None if this is the last tb entry 
+        source = self._getentrysource(entry)
+        line_index = entry.lineno - entry.getfirstlinesource()
+
+        if self.style == "long":
+            self.repr_source(source, line_index, excinfo)
+            self._line("") 
+            message = excinfo and excinfo.exconly() or ""
+            self._line(LocationRepr(entry.path, entry.lineno+1, message))
+            self.repr_locals(entry.locals)
+        else: 
+            if self.style == "short":
+                line = source[line_index].lstrip()
+                self._line('  File "%s", line %d, in %s' % (
+                    entry.path.basename, entry.lineno+1, entry.name))
+                self._line("    " + line) 
+            if excinfo: 
+                self.repr_exconly(excinfo, indent=4)
+
+    def repr_sep(self, sep):
+        if self.style == "long":
+            self._sepline(sep)
+
+    def repr_tb(self, excinfo): 
+        traceback = excinfo.traceback 
+        recursionindex = traceback.recursionindex()
+        last = traceback[-1]
+        for index, entry in py.builtin.enumerate(traceback): 
+            if last != entry: 
+                self.repr_tb_entry(entry)
+                self.repr_sep("_ ")
+            else:
+                self.repr_tb_entry(entry, excinfo) 
+                self.repr_sep("_")
+            if index == recursionindex:
+                self._line("Recursion detected (same locals & position)")
+                self._sepline("!")
+                break
+
+    def _sepline(self, sep, line=""):
+        self.lines.append(LineSep(sep, line))
+    def _line(self, line):
+        self.lines.append(line)
     def __str__(self):
-        # XXX wrong str
-        return self.exconly() 
+        return "\n".join([str(x) for x in self.lines])
 
+class LineSep:
+    def __init__(self, sep, line):
+        self.sep = sep 
+        self.line = line
+    def __str__(self):
+        sep = self.sep * 10 
+        return self.line.join([sep, sep])
+
+class LocationRepr:
+    def __init__(self, path, lineno, message):
+        self.path = str(path)
+        self.lineno = lineno
+        self.message = message
+    def __str__(self):
+        # filename and lineno output for each entry,
+        # using an output format that most editors unterstand
+        msg = self.message 
+        if msg.find("\n") != -1:
+            msg = repr(msg)
+        return ("%s:%s: %s" %(self.path, self.lineno, msg))

Deleted: /py/branch/event/py/code/format_excinfo.py
==============================================================================
--- /py/branch/event/py/code/format_excinfo.py	Mon Aug  4 23:10:55 2008
+++ (empty file)
@@ -1,155 +0,0 @@
-""" 
-    Present Python tracebacks in a nice way. 
-"""
-import py
-from py.__.code import safe_repr
-
-class TBReprWriter:
-    def __init__(self):
-        self.lines = []
-    def sep(self, sep, line=""):
-        self.lines.append(LineSep(sep, line))
-    def line(self, line):
-        self.lines.append(line)
-    def __str__(self):
-        return "\n".join([str(x) for x in self.lines])
-
-class LineSep:
-    def __init__(self, sep, line):
-        self.sep = sep
-        self.line = line
-    def __str__(self):
-        sep = self.sep * 10
-        return self.line.join([sep, sep])
-
-class LocationRepr:
-    def __init__(self, path, lineno, message):
-        self.path = str(path)
-        self.lineno = lineno
-        self.message = message
-    def __str__(self):
-        # filename and lineno output for each entry,
-        # using an output format that most editors unterstand
-        msg = self.message 
-        if msg.find("\n") != -1:
-            msg = repr(msg)
-        return ("%s:%s: %s" %(self.path, self.lineno, msg))
-
-class FormattedExcinfo(object):
-    """ presenting information about failing Functions and Generators. """ 
-    # for traceback entries 
-    flow_marker = ">"    
-    fail_marker = "E"
-    
-    def __init__(self, showlocals=False, style="long"):
-        self.out = TBReprWriter()
-        self.showlocals = showlocals
-        self.style = style
-
-    def _getindent(self, source):
-        # figure out indent 
-        try:
-            s = str(source.getstatement(len(source)-1))
-        except KeyboardInterrupt: 
-            raise 
-        except:
-            s = str(source[-1])
-        return 4 + (len(s) - len(s.lstrip()))
-
-
-    def _getentrysource(self, entry):
-        try:
-            source = entry.getsource()
-        except py.error.ENOENT:
-            source = "???"
-        return source.deindent()
-
-    def _saferepr(self, obj):
-        return safe_repr._repr(obj)
-
-
-    def repr_source(self, source, line_index=-1, excinfo=None):
-        """ represent source with with marker at given index. """
-        if source is None:
-            source = py.code.Source("???")
-            line_index = 0 
-        if line_index < 0:
-            line_index += len(source)
-        for i in range(len(source)):
-            if i == line_index:
-                prefix = self.flow_marker + "   "
-            else:
-                prefix = "    "
-            line = prefix + source[i]
-            self.out.line(line)
-
-        if excinfo is not None:
-            indent = self._getindent(source)
-            self.repr_exconly(excinfo, indent=indent, markall=True)
-
-    def repr_exconly(self, excinfo, indent=4, markall=False):
-        indent = " " * indent 
-        # get the real exception information out 
-        lines = excinfo.exconly(tryshort=True).split('\n')
-        failindent = self.fail_marker + indent[1:]
-        for line in lines:
-            self.out.line(failindent + line)
-            if not markall:
-                failindent = indent 
-
-    def repr_locals(self, f_locals):
-        if self.showlocals: 
-            self.out.sep('- ', 'locals')
-            for name, value in f_locals.items():
-                if name == '__builtins__': 
-                    self.out.line("__builtins__ = <builtins>")
-                else:
-                    # This formatting could all be handled by the _repr() function, which is 
-                    # only repr.Repr in disguise, so is very configurable.
-                    str_repr = safe_repr._repr(value)
-                    if len(str_repr) < 70 or not isinstance(value,
-                                                (list, tuple, dict)):
-                        self.out.line("%-10s = %s" %(name, str_repr))
-                    else:
-                        self.out.line("%-10s =\\" % (name,))
-                        py.std.pprint.pprint(value, stream=self.out)
-
-    def repr_tb_entry(self, entry, excinfo=None):
-        # excinfo is not None if this is the last tb entry 
-        source = self._getentrysource(entry)
-        line_index = entry.lineno - entry.getfirstlinesource()
-
-        if self.style == "long":
-            self.repr_source(source, line_index, excinfo)
-            self.out.line("") 
-            message = excinfo and excinfo.exconly() or ""
-            self.out.line(LocationRepr(entry.path, entry.lineno+1, message))
-            self.repr_locals(entry.locals)
-        else: 
-            if self.style == "short":
-                line = source[line_index].lstrip()
-                self.out.line('  File "%s", line %d, in %s' % (
-                    entry.path.basename, entry.lineno+1, entry.name))
-                self.out.line("    " + line) 
-            if excinfo: 
-                self.repr_exconly(excinfo, indent=4)
-
-    def repr_sep(self, sep):
-        if self.style == "long":
-            self.out.sep(sep)
-
-    def repr_tb(self, excinfo): 
-        traceback = excinfo.traceback 
-        recursionindex = traceback.recursionindex()
-        last = traceback[-1]
-        for index, entry in py.builtin.enumerate(traceback): 
-            if last != entry: 
-                self.repr_tb_entry(entry)
-                self.repr_sep("_ ")
-            else:
-                self.repr_tb_entry(entry, excinfo) 
-                self.repr_sep("_")
-            if index == recursionindex:
-                self.out.line("Recursion detected (same locals & position)")
-                self.out.sep("!")
-                break

Modified: py/branch/event/py/code/testing/test_excinfo.py
==============================================================================
--- py/branch/event/py/code/testing/test_excinfo.py	(original)
+++ py/branch/event/py/code/testing/test_excinfo.py	Mon Aug  4 23:10:55 2008
@@ -1,5 +1,5 @@
 import py
-mypath = py.magic.autopath()
+from py.__.code.excinfo import FormattedExcinfo
 
 def test_excinfo_simple():
     try:
@@ -184,18 +184,18 @@
     msg = tbentry.reinterpret() 
     assert msg.startswith("TypeError: ('hello' + 5)") 
 
-#def test_excinfo_getentries_type_error():
-#    excinfo = py.test.raises(ValueError, h)
-#    entries = excinfo.getentries(
-#            lambda x: x.frame.code.name != 'raises',
-#            lambda x: x.frame.code.name != 'f')
-#    names = [x.frame.code.name for x in entries]
-#    assert names == ['h','g']
-
 def test_excinfo_exconly():
     excinfo = py.test.raises(ValueError, h)
     assert excinfo.exconly().startswith('ValueError')
 
+def test_excinfo_str():
+    excinfo = py.test.raises(ValueError, h)
+    s = str(excinfo)
+    print s
+    assert s.startswith(__file__[:-1]) # pyc file 
+    assert s.endswith("ValueError")
+    assert len(s.split(":")) == 3
+
 def test_excinfo_errisinstance():
     excinfo = py.test.raises(ValueError, h)
     assert excinfo.errisinstance(ValueError) 
@@ -206,3 +206,221 @@
     except ValueError: 
         excinfo = py.code.ExceptionInfo()
     s = str(excinfo.traceback[-1])
+    assert s == "  File '<string>':1 in <module>\n  ???\n"
+
+class TestFormattedExcinfo: 
+    def setup_method(self, method):
+        self.tmpdir = py.test2.ensuretemp("%s_%s" %(
+            self.__class__.__name__, method.__name__))
+
+    def importasmod(self, source):
+        source = py.code.Source(source)
+        modpath = self.tmpdir.join("mod.py")
+        self.tmpdir.ensure("__init__.py")
+        modpath.write(source)
+        return modpath.pyimport()
+
+    def test_repr_source(self):
+        pr = FormattedExcinfo()
+        source = py.code.Source("""
+            def f(x):
+                pass
+        """).strip()
+        pr.flow_marker = "|"
+        pr.repr_source(source, 0)
+        lines = pr.lines 
+        assert len(lines) == 2
+        assert lines[0] == "|   def f(x):"
+        assert lines[1] == "        pass"
+
+    def test_repr_source_excinfo(self):
+        """ check if indentation is right """
+        def f():
+            def g():
+                1/0
+            try:
+                g()
+            except:
+                e = py.code.ExceptionInfo()
+            return e
+    
+        pr = FormattedExcinfo()
+        source = py.code.Source(f)
+        e = f()
+        pr.repr_source(source, 1, e)
+        assert pr.lines[-1].startswith("E       ZeroDivisionError:")
+
+    def test_repr_local(self):
+        p = FormattedExcinfo(showlocals=True)
+        loc = locals()
+        p.repr_locals(loc) 
+        result = str(p)
+        for key in loc.keys(): 
+            assert result.find(key) != -1 
+
+    def test_repr_tbentry(self):
+        mod = self.importasmod("""
+            def func1():
+                raise ValueError("hello\\nworld")
+            def entry():
+                func1()
+        """)
+        excinfo = py.test.raises(ValueError, mod.entry)
+        p = FormattedExcinfo()
+        p.repr_tb_entry(excinfo.traceback[-2])
+        lines = p.lines
+
+        # test intermittent entries 
+
+        assert lines[0] == "    def entry():"
+        assert lines[1] == ">       func1()"
+        assert not lines[2]
+        loc = lines[3]
+        assert loc.path == mod.__file__
+        assert loc.lineno == 5
+        assert not loc.message 
+
+        # test last entry 
+        p = FormattedExcinfo()
+        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
+        lines = p.lines
+        assert lines[0] == "    def func1():"
+        assert lines[1] == '>       raise ValueError("hello\\nworld")'
+        assert lines[2] == "E       ValueError: hello"
+        assert lines[3] == "E       world"
+        loc = lines[5]
+        assert loc.path == mod.__file__
+        assert loc.lineno == 3
+        assert loc.message == "ValueError: hello\nworld"
+        assert str(loc) == "%s:3: 'ValueError: hello\\nworld'" %(mod.__file__,)
+
+    def test_repr_tbentry_short(self):
+        mod = self.importasmod("""
+            def func1():
+                raise ValueError("hello")
+            def entry():
+                func1()
+        """)
+        excinfo = py.test.raises(ValueError, mod.entry)
+        p = FormattedExcinfo(style="short")
+        p.repr_tb_entry(excinfo.traceback[-2])
+        lines = p.lines
+        basename = py.path.local(mod.__file__).basename
+        assert lines[0] == '  File "%s", line 5, in entry' % basename 
+        assert lines[1] == '    func1()' 
+
+        # test last entry 
+        p = FormattedExcinfo(style="short")
+        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
+        lines = p.lines
+        assert lines[0] == '  File "%s", line 3, in func1' % basename 
+        assert lines[1] == '    raise ValueError("hello")'
+        assert lines[2] == 'E   ValueError: hello'
+
+    def test_repr_tbentry_no(self):
+        mod = self.importasmod("""
+            def func1():
+                raise ValueError("hello")
+            def entry():
+                func1()
+        """)
+        excinfo = py.test.raises(ValueError, mod.entry)
+        p = FormattedExcinfo(style="no")
+        p.repr_tb_entry(excinfo.traceback[-2])
+        assert not p.lines
+
+        p = FormattedExcinfo(style="no")
+        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
+        lines = p.lines
+        assert lines[0] == 'E   ValueError: hello'
+
+    def test_format(self):
+        mod = self.importasmod("""
+            def f(x):
+                raise ValueError(x)
+            def entry():
+                f(0)
+        """)
+        p = FormattedExcinfo(style="short")
+        excinfo = py.test.raises(ValueError, mod.entry)
+        l = []
+        p.repr_tb_entry = lambda entry, excinfo=None: l.append((entry,excinfo))
+        p.repr_sep = lambda sep: l.append(sep)
+        s = p.repr_tb(excinfo)
+        print l
+        assert l[-1] == "_"
+        entry, excinfo2 = l[-2]
+        assert excinfo == excinfo2
+        assert entry == excinfo.traceback[-1]
+        assert l[-3] == "_ "
+        entry, excinfo2 = l[-4]
+        assert excinfo2 is None
+        assert entry == excinfo.traceback[-2]
+        
+    def test_repr_tb_recursion(self):
+        mod = self.importasmod("""
+            def rec2(x):
+                return rec1(x+1)
+            def rec1(x):
+                return rec2(x-1)
+            def entry():
+                rec1(42)
+        """)
+        excinfo = py.test.raises(RuntimeError, mod.entry)
+
+        for style in ("short", "long"):
+            p = FormattedExcinfo(style="short")
+            l = []
+            p.repr_tb_entry = lambda entry, excinfo=None: l.append((entry,excinfo))
+            p.repr_sep = lambda sep: l.append(sep)
+            p.repr_tb(excinfo)
+            s = str(p)
+            print l
+            #assert re.search(".*return rec1.*x\+1", s)
+            #assert re.search(".*return rec2.*x-1.*", s)
+            assert len(l) < 20 
+            assert s.find("Recursion detected") != -1
+            assert l[-1] == "_ "
+            assert l[-2][0].lineno == 4
+
+    def test_tb_entry_AssertionError(self):
+        # probably this test is a bit redundant 
+        # as py/magic/testing/test_assertion.py
+        # already tests correctness of
+        # assertion-reinterpretation  logic 
+        mod = self.importasmod("""
+            def somefunc():
+                x = 1
+                assert x == 2
+        """)
+        py.magic.invoke(assertion=True)
+        try:
+            excinfo = py.test.raises(AssertionError, mod.somefunc)
+        finally:
+            py.magic.revoke(assertion=True)
+            
+        p = FormattedExcinfo()
+        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
+        lines = p.lines
+        assert lines[-3] == "E       assert 1 == 2"
+
+    def test_excinfo_formatted(self):
+        mod = self.importasmod("""
+            def f(x):
+                raise ValueError(x)
+            def entry():
+                f(0)
+        """)
+        excinfo = py.test.raises(ValueError, mod.entry)
+        repr = excinfo._formatrepr()
+        fex = FormattedExcinfo()
+        for line1, line2 in zip(repr.lines, fex.lines):
+            assert str(line1) == str(line2)
+
+        tw = py.io.TerminalWriter()
+        fex.writeterminal(tw)
+        lines1 = tw.stringio.getvalue().split("\n")
+        lines2 = excinfo.format().split("\n")
+        for line1, line2 in zip(repr.lines, fex.lines):
+            assert line1 == line2
+        

Deleted: /py/branch/event/py/code/testing/test_format_excinfo.py
==============================================================================
--- /py/branch/event/py/code/testing/test_format_excinfo.py	Mon Aug  4 23:10:55 2008
+++ (empty file)
@@ -1,204 +0,0 @@
-
-import py
-import re
-from py.__.code.format_excinfo import FormattedExcinfo
-
-class TestFormattedExcinfo: 
-
-    def setup_method(self, method):
-        self.tmpdir = py.test2.ensuretemp("%s_%s" %(
-            self.__class__.__name__, method.__name__))
-
-    def importasmod(self, source):
-        source = py.code.Source(source)
-        modpath = self.tmpdir.join("mod.py")
-        self.tmpdir.ensure("__init__.py")
-        modpath.write(source)
-        return modpath.pyimport()
-
-    def getpresenter(self, **kwargs):
-        return FormattedExcinfo(**kwargs)
-
-    def test_repr_source(self):
-        pr = self.getpresenter()
-        source = py.code.Source("""
-            def f(x):
-                pass
-        """).strip()
-        pr.flow_marker = "|"
-        pr.repr_source(source, 0)
-        lines = pr.out.lines 
-        assert len(lines) == 2
-        assert lines[0] == "|   def f(x):"
-        assert lines[1] == "        pass"
-
-    def test_repr_source_excinfo(self):
-        """ check if indentation is right """
-        def f():
-            def g():
-                1/0
-            try:
-                g()
-            except:
-                e = py.code.ExceptionInfo()
-            return e
-    
-        pr = self.getpresenter()
-        source = py.code.Source(f)
-        e = f()
-        pr.repr_source(source, 1, e)
-        assert pr.out.lines[-1].startswith("E       ZeroDivisionError:")
-
-    def test_repr_local(self):
-        p = self.getpresenter(showlocals=True)
-        loc = locals()
-        p.repr_locals(loc) 
-        result = str(p.out)
-        for key in loc.keys(): 
-            assert result.find(key) != -1 
-
-    def test_repr_tbentry(self):
-        mod = self.importasmod("""
-            def func1():
-                raise ValueError("hello\\nworld")
-            def entry():
-                func1()
-        """)
-        excinfo = py.test.raises(ValueError, mod.entry)
-        p = self.getpresenter()
-        p.repr_tb_entry(excinfo.traceback[-2])
-        lines = p.out.lines
-
-        # test intermittent entries 
-
-        assert lines[0] == "    def entry():"
-        assert lines[1] == ">       func1()"
-        assert not lines[2]
-        loc = lines[3]
-        assert loc.path == mod.__file__
-        assert loc.lineno == 5
-        assert not loc.message 
-
-        # test last entry 
-        p = self.getpresenter()
-        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
-        lines = p.out.lines
-        assert lines[0] == "    def func1():"
-        assert lines[1] == '>       raise ValueError("hello\\nworld")'
-        assert lines[2] == "E       ValueError: hello"
-        assert lines[3] == "E       world"
-        loc = lines[5]
-        assert loc.path == mod.__file__
-        assert loc.lineno == 3
-        assert loc.message == "ValueError: hello\nworld"
-        assert str(loc) == "%s:3: 'ValueError: hello\\nworld'" %(mod.__file__,)
-
-    def test_repr_tbentry_short(self):
-        mod = self.importasmod("""
-            def func1():
-                raise ValueError("hello")
-            def entry():
-                func1()
-        """)
-        excinfo = py.test.raises(ValueError, mod.entry)
-        p = self.getpresenter(style="short")
-        p.repr_tb_entry(excinfo.traceback[-2])
-        lines = p.out.lines
-        basename = py.path.local(mod.__file__).basename
-        assert lines[0] == '  File "%s", line 5, in entry' % basename 
-        assert lines[1] == '    func1()' 
-
-        # test last entry 
-        p = self.getpresenter(style="short")
-        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
-        lines = p.out.lines
-        assert lines[0] == '  File "%s", line 3, in func1' % basename 
-        assert lines[1] == '    raise ValueError("hello")'
-        assert lines[2] == 'E   ValueError: hello'
-
-    def test_repr_tbentry_no(self):
-        mod = self.importasmod("""
-            def func1():
-                raise ValueError("hello")
-            def entry():
-                func1()
-        """)
-        excinfo = py.test.raises(ValueError, mod.entry)
-        p = self.getpresenter(style="no")
-        p.repr_tb_entry(excinfo.traceback[-2])
-        assert not p.out.lines
-
-        p = self.getpresenter(style="no")
-        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
-        lines = p.out.lines
-        assert lines[0] == 'E   ValueError: hello'
-
-    def test_repr_tb(self):
-        mod = self.importasmod("""
-            def f(x):
-                raise ValueError(x)
-            def entry():
-                f(0)
-        """)
-        p = self.getpresenter(style="short")
-        excinfo = py.test.raises(ValueError, mod.entry)
-        l = []
-        p.repr_tb_entry = lambda entry, excinfo=None: l.append((entry,excinfo))
-        p.repr_sep = lambda sep: l.append(sep)
-        s = p.repr_tb(excinfo)
-        print l
-        assert l[-1] == "_"
-        entry, excinfo2 = l[-2]
-        assert excinfo == excinfo2
-        assert entry == excinfo.traceback[-1]
-        assert l[-3] == "_ "
-        entry, excinfo2 = l[-4]
-        assert excinfo2 is None
-        assert entry == excinfo.traceback[-2]
-        
-    def test_repr_tb_recursion(self):
-        mod = self.importasmod("""
-            def rec2(x):
-                return rec1(x+1)
-            def rec1(x):
-                return rec2(x-1)
-            def entry():
-                rec1(42)
-        """)
-        excinfo = py.test.raises(RuntimeError, mod.entry)
-
-        for style in ("short", "long"):
-            p = self.getpresenter(style="short")
-            l = []
-            p.repr_tb_entry = lambda entry, excinfo=None: l.append((entry,excinfo))
-            p.repr_sep = lambda sep: l.append(sep)
-            p.repr_tb(excinfo)
-            s = str(p.out)
-            print l
-            #assert re.search(".*return rec1.*x\+1", s)
-            #assert re.search(".*return rec2.*x-1.*", s)
-            assert len(l) < 20 
-            assert re.search("Recursion detected", s)
-            assert l[-1] == "_ "
-            assert l[-2][0].lineno == 4
-
-    def test_tb_entry_AssertionError(self):
-        # probably this test is a bit redundant 
-        # as py/magic/testing/test_assertion.py
-        # already tests correctness of
-        # assertion-reinterpretation  logic 
-        mod = self.importasmod("""
-            def somefunc():
-                x = 1
-                assert x == 2
-        """)
-        py.magic.invoke(assertion=True)
-        try:
-            excinfo = py.test.raises(AssertionError, mod.somefunc)
-        finally:
-            py.magic.revoke(assertion=True)
-            
-        p = self.getpresenter()
-        p.repr_tb_entry(excinfo.traceback[-1], excinfo)
-        lines = p.out.lines
-        assert lines[-3] == "E       assert 1 == 2"

Modified: py/branch/event/py/code/traceback2.py
==============================================================================
--- py/branch/event/py/code/traceback2.py	(original)
+++ py/branch/event/py/code/traceback2.py	Mon Aug  4 23:10:55 2008
@@ -90,8 +90,10 @@
         name = self.frame.code.name 
         try: 
             line = str(self.statement).lstrip()
-        except EnvironmentError, e: 
-            line = "<could not get sourceline>"
+        except KeyboardInterrupt:
+            raise
+        except:
+            line = "???"
         return "  File %r:%d in %s\n  %s\n" %(fn, self.lineno+1, name, line) 
 
     def name(self):



More information about the pytest-commit mailing list