[pypy-svn] r7972 - in pypy/branch/src-pytest/pypy: . tool/pytest

arigo at codespeak.net arigo at codespeak.net
Wed Dec 22 18:49:31 CET 2004


Author: arigo
Date: Wed Dec 22 18:49:30 2004
New Revision: 7972

Modified:
   pypy/branch/src-pytest/pypy/conftest.py
   pypy/branch/src-pytest/pypy/tool/pytest/support.py
Log:
A pile of hacks that more or less allow nice app-level tracebacks to be 
displayed.  For some reason it more or less works with magic already, but in 
case of trouble, you'll need to use --nomagic.



Modified: pypy/branch/src-pytest/pypy/conftest.py
==============================================================================
--- pypy/branch/src-pytest/pypy/conftest.py	(original)
+++ pypy/branch/src-pytest/pypy/conftest.py	Wed Dec 22 18:49:30 2004
@@ -1,5 +1,6 @@
 import py
 from pypy.interpreter.gateway import app2interp_temp 
+from pypy.interpreter.error import OperationError
 from pypy.objspace.std import StdObjSpace 
 
 #
@@ -67,34 +68,105 @@
         py.test.skip('test requires object space %r' % (name,))
     return space
 
-class IntTestFunction(py.test.Item): 
+
+class AppRunnerFrame(py.code.InspectableFrame):
+
+    def __init__(self, pyframe):
+        lineno = pyframe.get_last_lineno() - 1
+        super(AppRunnerFrame, self).__init__(pyframe.code, lineno)
+        self.space = pyframe.space
+        self.w_globals = pyframe.w_globals
+        self.w_locals = pyframe.getdictscope()
+
+    def eval(self, code, **vars):
+        space = self.space
+        for key, w_value in vars.items():
+            space.setitem(self.w_locals, space.wrap(key), w_value)
+        return space.eval(code, self.w_globals, self.w_locals)
+
+    def exec_(self, code, **vars):
+        space = self.space
+        for key, w_value in vars.items():
+            space.setitem(self.w_locals, space.wrap(key), w_value)
+        space.exec_(code, self.w_globals, self.w_locals)
+
+    def repr(self, w_value):
+        return self.space.unwrap(self.space.repr(w_value))
+
+    def is_true(self, w_value):
+        return self.space.is_true(w_value)
+
+
+class AppExceptionInfo(py.code.ExceptionInfo):
+    """An ExceptionInfo object representing an app-level exception."""
+
+    def __init__(self, space, operr):
+        self.space = space
+        self.operr = operr
+        # XXX this is all a hackish forced integration with the not-yet-
+        #     finished API of py.code.ExceptionInfo.
+        w_type, w_value = operr.w_type, operr.w_value
+        if not space.is_true(space.isinstance(w_type, space.w_str)):
+            w_type = space.getattr(w_type, space.wrap('__name__'))
+        t = space.unwrap(space.str(w_type))
+        v = space.unwrap(space.str(w_value))
+        if v:
+            operrtext = '(app-level) %s: %s' % (t, v)
+        else:
+            operrtext = '(app-level) %s' % (t,)
+        tup = (operr.__class__, operrtext, operr.application_traceback)
+        super(AppExceptionInfo, self).__init__(tup)
+
+    def __iter__(self):
+        tb = self.tb
+        while tb is not None:
+            iframe = AppRunnerFrame(tb.frame)
+            iframe.f_locals = {}   # XXX remove me
+            yield AppTracebackEntry(iframe, tb.lineno - 1)
+            tb = tb.next
+
+class AppTracebackEntry(py.__impl__.code.excinfo.TracebackEntry):
+    def __init__(self, frame, lineno):
+        self.frame = frame
+        self.lineno = lineno
+
+
+class PyPyItem(py.test.Item):
+    # All PyPy test items catch and display OperationErrors specially.
+    def execute_in_space(self, space, target, *args):
+        try:
+            target(*args)
+        except OperationError, e:
+            raise self.Failed(excinfo=AppExceptionInfo(space, e))
+
+class IntTestFunction(PyPyItem):
     def execute(self, target, *args):
         co = target.func_code
-        if 'space' in co.co_varnames[:co.co_argcount]:
+        if 'space' in co.co_varnames[:co.co_argcount]: 
             name = target.func_globals.get('objspacename', None) 
             space = gettestobjspace(name) 
-            return target(space, *args)
+            self.execute_in_space(space, target, space, *args)
         else:
-            return target(*args)
+            target(*args)
 
-class AppTestFunction(py.test.Item): 
-    def execute(self, target, *args): 
+class AppTestFunction(PyPyItem): 
+    def execute(self, target, *args):
         assert not args 
         name = target.func_globals.get('objspacename', None) 
         space = gettestobjspace(name) 
-        func = app2interp_temp(target, target.__name__) 
-        func(space) 
+        func = app2interp_temp(target, target.__name__)
+        self.execute_in_space(space, target, space)
 
-class IntTestMethod(py.test.Item): 
+class IntTestMethod(PyPyItem): 
     def execute(self, target, *args):
         name = target.func_globals.get('objspacename', None) 
         if name is None: 
             name = getattr(target.im_class, 'objspacename', None)
         instance = target.im_self
-        instance.space = gettestobjspace(name)
-        return target(*args)
+        instance.space = space = gettestobjspace(name)
+        self.execute_in_space(space, target, *args)
 
-class AppTestMethod(py.test.Item): 
+class AppTestMethod(PyPyItem): 
     def execute(self, target, *args): 
         assert not args 
         name = target.func_globals.get('objspacename', None) 
@@ -102,7 +174,7 @@
             name = getattr(target.im_class, 'objspacename', None)
         space = gettestobjspace(name)
         func = app2interp_temp(target.im_func, target.__name__) 
-        func(space, space.w_None) 
+        self.execute_in_space(space, func, space, space.w_None)
 
 class AppClassCollector(py.test.collect.Class): 
     Item = AppTestMethod 

Modified: pypy/branch/src-pytest/pypy/tool/pytest/support.py
==============================================================================
--- pypy/branch/src-pytest/pypy/tool/pytest/support.py	(original)
+++ pypy/branch/src-pytest/pypy/tool/pytest/support.py	Wed Dec 22 18:49:30 2004
@@ -10,7 +10,7 @@
 class AppRunnerFrame(InspectableFrame):
 
     def __init__(self, pyframe):
-        lineno = pyframe.get_last_lineno()
+        lineno = pyframe.get_last_lineno() - 1
         super(AppRunnerFrame, self).__init__(pyframe.code, lineno)
         self.space = pyframe.space
         self.w_globals = pyframe.w_globals



More information about the Pypy-commit mailing list