Author: Philip Jenvey <[email protected]>
Branch: py3k
Changeset: r61742:894b0fa3245b
Date: 2013-02-24 10:51 -0800
http://bitbucket.org/pypy/pypy/changeset/894b0fa3245b/
Log: hide app_main's frames. this breaks sys.exc_info but py3 offers a
workaround
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
@@ -20,6 +20,10 @@
from __future__ import print_function, unicode_literals
+try:
+ from __pypy__ import hidden_applevel
+except ImportError:
+ hidden_applevel = lambda f: f
import errno
import sys
@@ -44,6 +48,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.
@@ -55,13 +60,13 @@
f(*fargs, **fkwds)
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'):
@@ -87,14 +92,14 @@
hook(etype, evalue, etraceback)
return # done
- except:
+ except BaseException as e:
try:
stderr = sys.stderr
except AttributeError:
pass # too bad
else:
print('Error calling sys.excepthook:', file=stderr)
- originalexcepthook(*sys.exc_info())
+ originalexcepthook(type(e), e, e.__traceback__)
print(file=stderr)
print('Original exception was:', file=stderr)
@@ -463,6 +468,7 @@
# this indirection is needed to be able to import this module on python2, else
# we have a SyntaxError: unqualified exec in a nested function
+@hidden_applevel
def exec_(src, dic):
exec(src, dic)
@@ -540,6 +546,7 @@
# Put '' on sys.path
sys.path.insert(0, '')
+ @hidden_applevel
def run_it():
exec_(run_command, mainmodule.__dict__)
success = run_toplevel(run_it)
@@ -574,6 +581,7 @@
print("Could not open PYTHONSTARTUP", file=sys.stderr)
print("IOError:", e, file=sys.stderr)
else:
+ @hidden_applevel
def run_it():
co_python_startup = compile(startup,
python_startup,
@@ -590,6 +598,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')
exec_(co_stdin, mainmodule.__dict__)
@@ -624,6 +633,7 @@
args = (runpy._run_module_as_main, '__main__', False)
else:
# no. That's the normal path, "pypy stuff.py".
+ @hidden_applevel
def execfile(filename, namespace):
with open(filename, 'rb') as f:
code = f.read()
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
@@ -49,6 +49,7 @@
'debug_stop' : 'interp_debug.debug_stop',
'debug_print_once' : 'interp_debug.debug_print_once',
'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',
'list_strategy' : 'interp_magic.list_strategy',
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
@@ -56,6 +56,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(ObjSpace, W_Root, 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
@@ -26,6 +26,39 @@
assert A.a is 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]
http://mail.python.org/mailman/listinfo/pypy-commit