Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3k
Changeset: r58768:fdfaf9044e48
Date: 2012-11-06 22:07 +0100
http://bitbucket.org/pypy/pypy/changeset/fdfaf9044e48/
Log: hg merge default
diff --git a/pypy/interpreter/error.py b/pypy/interpreter/error.py
--- a/pypy/interpreter/error.py
+++ b/pypy/interpreter/error.py
@@ -231,7 +231,8 @@
raise operationerrfmt(space.w_TypeError, msg, typename)
return w_type
- def write_unraisable(self, space, where, w_object=None):
+ def write_unraisable(self, space, where, w_object=None,
+ with_traceback=False):
if w_object is None:
objrepr = ''
else:
@@ -239,10 +240,25 @@
objrepr = space.str_w(space.repr(w_object))
except OperationError:
objrepr = '?'
- msg = 'Exception %s in %s%s ignored\n' % (
- self.errorstr(space, use_repr=True), where, objrepr)
+ #
try:
- space.call_method(space.sys.get('stderr'), 'write',
space.wrap(msg))
+ if with_traceback:
+ w_t = self.w_type
+ w_v = self.get_w_value(space)
+ w_tb = space.wrap(self.get_traceback())
+ space.appexec([space.wrap(where),
+ space.wrap(objrepr),
+ w_t, w_v, w_tb],
+ """(where, objrepr, t, v, tb):
+ import sys, traceback
+ sys.stderr.write('From %s%s:\\n' % (where, objrepr))
+ traceback.print_exception(t, v, tb)
+ """)
+ else:
+ msg = 'Exception %s in %s%s ignored\n' % (
+ self.errorstr(space, use_repr=True), where, objrepr)
+ space.call_method(space.sys.get('stderr'), 'write',
+ space.wrap(msg))
except OperationError:
pass # ignored
diff --git a/pypy/module/_cffi_backend/ccallback.py
b/pypy/module/_cffi_backend/ccallback.py
--- a/pypy/module/_cffi_backend/ccallback.py
+++ b/pypy/module/_cffi_backend/ccallback.py
@@ -92,7 +92,8 @@
def print_error(self, operr):
space = self.space
- operr.write_unraisable(space, "cffi callback", self.w_callable)
+ operr.write_unraisable(space, "callback ", self.w_callable,
+ with_traceback=True)
def write_error_return_value(self, ll_res):
fresult = self.getfunctype().ctitem
diff --git a/pypy/module/_cffi_backend/test/_backend_test_c.py
b/pypy/module/_cffi_backend/test/_backend_test_c.py
--- a/pypy/module/_cffi_backend/test/_backend_test_c.py
+++ b/pypy/module/_cffi_backend/test/_backend_test_c.py
@@ -1020,6 +1020,55 @@
e = py.test.raises(TypeError, f)
assert str(e.value) == "'int(*)(int)' expects 1 arguments, got 0"
+def test_callback_exception():
+ import cStringIO, linecache
+ def matches(str, pattern):
+ while '$' in pattern:
+ i = pattern.index('$')
+ assert str[:i] == pattern[:i]
+ j = str.find(pattern[i+1], i)
+ assert i + 1 <= j <= str.find('\n', i)
+ str = str[j:]
+ pattern = pattern[i+1:]
+ assert str == pattern
+ return True
+ def check_value(x):
+ if x == 10000:
+ raise ValueError(42)
+ def cb1(x):
+ check_value(x)
+ return x * 3
+ BShort = new_primitive_type("short")
+ BFunc = new_function_type((BShort,), BShort, False)
+ f = callback(BFunc, cb1, -42)
+ orig_stderr = sys.stderr
+ orig_getline = linecache.getline
+ try:
+ linecache.getline = lambda *args: 'LINE' # hack: speed up PyPy tests
+ sys.stderr = cStringIO.StringIO()
+ assert f(100) == 300
+ assert sys.stderr.getvalue() == ''
+ assert f(10000) == -42
+ assert matches(sys.stderr.getvalue(), """\
+From callback <function cb1 at 0x$>:
+Traceback (most recent call last):
+ File "$", line $, in cb1
+ $
+ File "$", line $, in check_value
+ $
+ValueError: 42
+""")
+ sys.stderr = cStringIO.StringIO()
+ bigvalue = 20000
+ assert f(bigvalue) == -42
+ assert matches(sys.stderr.getvalue(), """\
+From callback <function cb1 at 0x$>:
+OverflowError: integer 60000 does not fit 'short'
+""")
+ finally:
+ sys.stderr = orig_stderr
+ linecache.getline = orig_getline
+
def test_callback_return_type():
for rettype in ["signed char", "short", "int", "long", "long long",
"unsigned char", "unsigned short", "unsigned int",
diff --git a/pypy/module/_cffi_backend/test/test_c.py
b/pypy/module/_cffi_backend/test/test_c.py
--- a/pypy/module/_cffi_backend/test/test_c.py
+++ b/pypy/module/_cffi_backend/test/test_c.py
@@ -30,7 +30,7 @@
class AppTestC(object):
"""Populated below, hack hack hack."""
- spaceconfig = dict(usemodules=('_cffi_backend',))
+ spaceconfig = dict(usemodules=('_cffi_backend', 'cStringIO'))
def setup_class(cls):
testfuncs_w = []
diff --git a/pypy/tool/pytest/inttest.py b/pypy/tool/pytest/inttest.py
--- a/pypy/tool/pytest/inttest.py
+++ b/pypy/tool/pytest/inttest.py
@@ -3,6 +3,7 @@
# Most pypy tests are of this kind.
import py
+import sys
from pypy.interpreter.error import OperationError
from pypy.conftest import PyPyClassCollector
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit