Author: Philip Jenvey <[email protected]>
Branch:
Changeset: r78198:04afcba2a748
Date: 2013-02-24 10:51 -0800
http://bitbucket.org/pypy/pypy/changeset/04afcba2a748/
Log: hide app_main's frames. this breaks sys.exc_info but py3 offers a
workaround (grafted from 894b0fa3245b1584e5f8b7404d8c3206f7ab9f2d)
diff --git a/pypy/interpreter/app_main.py b/pypy/interpreter/app_main.py
--- a/pypy/interpreter/app_main.py
+++ b/pypy/interpreter/app_main.py
@@ -40,6 +40,10 @@
PYPYLOG: If set to a non-empty value, enable logging.
"""
+try:
+ from __pypy__ import hidden_applevel
+except ImportError:
+ hidden_applevel = lambda f: f
import sys
DEBUG = False # dump exceptions before calling the except hook
@@ -63,6 +67,7 @@
exitcode = 1
raise SystemExit(exitcode)
+@hidden_applevel
def run_toplevel(f, *fargs, **fkwds):
"""Calls f() and handles all OperationErrors.
Intended use is to run the main program or one interactive statement.
@@ -87,13 +92,13 @@
except SystemExit as e:
handle_sys_exit(e)
- except:
- display_exception()
+ except BaseException as e:
+ display_exception(e)
return False
return True # success
-def display_exception():
- etype, evalue, etraceback = sys.exc_info()
+def display_exception(e):
+ etype, evalue, etraceback = type(e), e, e.__traceback__
try:
# extra debugging info in case the code below goes very wrong
if DEBUG and hasattr(sys, 'stderr'):
@@ -119,11 +124,11 @@
hook(etype, evalue, etraceback)
return # done
- except:
+ except BaseException as e:
try:
stderr = sys.stderr
print >> stderr, 'Error calling sys.excepthook:'
- originalexcepthook(*sys.exc_info())
+ originalexcepthook(type(e), e, e.__traceback__)
print >> stderr
print >> stderr, 'Original exception was:'
except:
@@ -597,6 +602,7 @@
# Put '' on sys.path
sys.path.insert(0, '')
+ @hidden_applevel
def run_it():
exec run_command in mainmodule.__dict__
success = run_toplevel(run_it)
@@ -634,6 +640,7 @@
print >> sys.stderr, "Could not open PYTHONSTARTUP"
print >> sys.stderr, "IOError:", e
else:
+ @hidden_applevel
def run_it():
co_python_startup = compile(startup,
python_startup,
@@ -650,6 +657,7 @@
inspect = True
else:
# If not interactive, just read and execute stdin normally.
+ @hidden_applevel
def run_it():
co_stdin = compile(sys.stdin.read(), '<stdin>', 'exec',
PyCF_ACCEPT_NULL_BYTES)
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -71,6 +71,7 @@
'debug_print_once' : 'interp_debug.debug_print_once',
'debug_flush' : 'interp_debug.debug_flush',
'builtinify' : 'interp_magic.builtinify',
+ 'hidden_applevel' : 'interp_magic.hidden_applevel',
'lookup_special' : 'interp_magic.lookup_special',
'do_what_I_mean' : 'interp_magic.do_what_I_mean',
'validate_fd' : 'interp_magic.validate_fd',
diff --git a/pypy/module/__pypy__/interp_magic.py
b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -59,6 +59,13 @@
bltn = BuiltinFunction(func)
return space.wrap(bltn)
+def hidden_applevel(space, w_func):
+ """Decorator that hides a function's frame from app-level"""
+ from pypy.interpreter.function import Function
+ func = space.interp_w(Function, w_func)
+ func.getcode().hidden_applevel = True
+ return w_func
+
@unwrap_spec(meth=str)
def lookup_special(space, w_obj, meth):
"""Lookup up a special method on an object."""
diff --git a/pypy/module/__pypy__/test/test_special.py
b/pypy/module/__pypy__/test/test_special.py
--- a/pypy/module/__pypy__/test/test_special.py
+++ b/pypy/module/__pypy__/test/test_special.py
@@ -27,6 +27,39 @@
assert A.a is not A.__dict__['a']
assert A.b is A.__dict__['b']
+ def test_hidden_applevel(self):
+ import __pypy__
+ import sys
+
+ @__pypy__.hidden_applevel
+ def sneak(): (lambda: 1/0)()
+ try:
+ sneak()
+ except ZeroDivisionError as e:
+ tb = e.__traceback__
+ assert tb.tb_frame == sys._getframe()
+ assert tb.tb_next.tb_frame.f_code.co_name == '<lambda>'
+ else:
+ assert False, 'Expected ZeroDivisionError'
+
+ def test_hidden_applevel_frames(self):
+ import __pypy__
+ import sys
+
+ @__pypy__.hidden_applevel
+ def test_hidden():
+ assert sys._getframe().f_code.co_name != 'test_hidden'
+ def e(): 1/0
+ try: e()
+ except ZeroDivisionError as e:
+ assert sys.exc_info() == (None, None, None)
+ frame = e.__traceback__.tb_frame
+ assert frame != sys._getframe()
+ assert frame.f_code.co_name == 'e'
+ else: assert False
+ return 2
+ assert test_hidden() == 2
+
def test_lookup_special(self):
from __pypy__ import lookup_special
class X(object):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit