Author: Amaury Forgeot d'Arc <amaur...@gmail.com> 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 pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit