Author: Ronan Lamy <[email protected]>
Branch:
Changeset: r97044:c5d1731e67ad
Date: 2019-08-01 16:33 +0000
http://bitbucket.org/pypy/pypy/changeset/c5d1731e67ad/
Log: Merged in apptest-file (pull request #659)
New mechanism for app-level testing
diff too long, truncating to 2000 out of 7533 lines
diff --git a/pypy/config/pypyoption.py b/pypy/config/pypyoption.py
--- a/pypy/config/pypyoption.py
+++ b/pypy/config/pypyoption.py
@@ -213,6 +213,10 @@
BoolOption("newshortcut",
"cache and shortcut calling __new__ from builtin types",
default=False),
+ BoolOption("reinterpretasserts",
+ "Perform reinterpretation when an assert fails "
+ "(only relevant for tests)",
+ default=False),
]),
])
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -1,6 +1,8 @@
import py, pytest, sys, textwrap
from inspect import isclass
+APPLEVEL_FN = 'apptest_*.py'
+
# pytest settings
rsyncdirs = ['.', '../lib-python', '../lib_pypy', '../demo']
rsyncignore = ['_cache']
@@ -36,28 +38,39 @@
def pytest_report_header():
return "pytest-%s from %s" % (pytest.__version__, pytest.__file__)
-def pytest_addhooks(pluginmanager):
- from rpython.conftest import LeakFinder
- pluginmanager.register(LeakFinder())
[email protected](tryfirst=True)
+def pytest_cmdline_preparse(config, args):
+ if not (set(args) & {'-D', '--direct-apptest'}):
+ args.append('--assert=reinterp')
def pytest_configure(config):
global option
option = config.option
+ mode_A = config.getoption('runappdirect')
+ mode_D = config.getoption('direct_apptest')
+ if mode_D or not mode_A:
+ config.addinivalue_line('python_files', APPLEVEL_FN)
+ if not mode_A and not mode_D: # 'own' tests
+ from rpython.conftest import LeakFinder
+ config.pluginmanager.register(LeakFinder())
def pytest_addoption(parser):
- from rpython.conftest import pytest_addoption
- pytest_addoption(parser)
-
group = parser.getgroup("pypy options")
group.addoption('-A', '--runappdirect', action="store_true",
default=False, dest="runappdirect",
- help="run applevel tests directly on python interpreter (not
through PyPy)")
+ help="run legacy applevel tests directly on python interpreter (not
through PyPy)")
+ group.addoption('-D', '--direct-apptest', action="store_true",
+ default=False, dest="direct_apptest",
+ help="run applevel_XXX.py tests directly on host interpreter")
group.addoption('--direct', action="store_true",
default=False, dest="rundirect",
help="run pexpect tests directly")
group.addoption('--raise-operr', action="store_true",
default=False, dest="raise_operr",
help="Show the interp-level OperationError in app-level tests")
+ group.addoption('--applevel-rewrite', action="store_true",
+ default=False, dest="applevel_rewrite",
+ help="Use assert rewriting in app-level test files (slow)")
@pytest.fixture(scope='function')
def space(request):
@@ -88,14 +101,21 @@
ensure_pytest_builtin_helpers()
def pytest_pycollect_makemodule(path, parent):
- return PyPyModule(path, parent)
+ if path.fnmatch(APPLEVEL_FN):
+ if parent.config.getoption('direct_apptest'):
+ return
+ from pypy.tool.pytest.apptest2 import AppTestModule
+ rewrite = parent.config.getoption('applevel_rewrite')
+ return AppTestModule(path, parent, rewrite_asserts=rewrite)
+ else:
+ return PyPyModule(path, parent)
def is_applevel(item):
from pypy.tool.pytest.apptest import AppTestFunction
return isinstance(item, AppTestFunction)
def pytest_collection_modifyitems(config, items):
- if config.option.runappdirect:
+ if config.getoption('runappdirect') or config.getoption('direct_apptest'):
return
for item in items:
if isinstance(item, py.test.Function):
@@ -104,17 +124,17 @@
else:
item.add_marker('interplevel')
-class PyPyModule(py.test.collect.Module):
+
+class PyPyModule(pytest.Module):
""" we take care of collecting classes both at app level
and at interp-level (because we need to stick a space
at the class) ourselves.
"""
def accept_regular_test(self):
if self.config.option.runappdirect:
- # only collect regular tests if we are in an 'app_test' directory,
- # or in test_lib_pypy
+ # only collect regular tests if we are in test_lib_pypy
for name in self.listnames():
- if "app_test" in name or "test_lib_pypy" in name:
+ if "test_lib_pypy" in name:
return True
return False
return True
@@ -186,6 +206,8 @@
appclass.obj.space = LazyObjSpaceGetter()
appclass.obj.runappdirect = option.runappdirect
-
-def pytest_ignore_collect(path):
+def pytest_ignore_collect(path, config):
+ if (config.getoption('direct_apptest') and not path.isdir()
+ and not path.fnmatch(APPLEVEL_FN)):
+ return True
return path.check(link=1)
diff --git a/pypy/doc/coding-guide.rst b/pypy/doc/coding-guide.rst
--- a/pypy/doc/coding-guide.rst
+++ b/pypy/doc/coding-guide.rst
@@ -456,13 +456,10 @@
Testing modules in ``lib_pypy/``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-You can go to the :source:`pypy/module/test_lib_pypy/` directory and invoke
the testing tool
-("py.test" or "python ../../pypy/test_all.py") to run tests against the
-lib_pypy hierarchy. Note, that tests in :source:`pypy/module/test_lib_pypy/`
are allowed
-and encouraged to let their tests run at interpreter level although
-:source:`lib_pypy/` modules eventually live at PyPy's application level.
-This allows us to quickly test our python-coded reimplementations
-against CPython.
+You can go to the :source:`pypy/module/test_lib_pypy/` directory and invoke the
+testing tool ("py.test" or "python ../../pypy/test_all.py") to run tests
+against the lib_pypy hierarchy. This allows us to quickly test our
+python-coded reimplementations against CPython.
Testing modules in ``pypy/module``
@@ -585,25 +582,42 @@
module global level and use plain 'assert' statements thanks to the
usage of the `py.test`_ tool.
-
-Application Level tests
+Application level tests
~~~~~~~~~~~~~~~~~~~~~~~
For testing the conformance and well-behavedness of PyPy it
is often sufficient to write "normal" application-level
Python code that doesn't need to be aware of any particular
-coding style or restrictions. If we have a choice we often
-use application level tests which usually look like this::
+coding style or restrictions. If we have a choice we often
+use application level tests which are in files whose name starts with the
+`apptest_` prefix and look like this::
- def app_test_something():
+ def test_this():
# application level test code
+These application level test functions will run on top
+of PyPy, i.e. they have no access to interpreter details.
+
+By default, they run on top of an untranslated PyPy which runs on top of the
+host interpreter. When passing the `-D` option, they run directly on top of the
+host interpreter, which is usually a translated pypy executable in this case::
+
+ pypy3 -m pytest -D pypy/
+
+Note that in interpreted mode, only a small subset of pytest's functionality is
+available.
+
+Mixed-level tests (deprecated)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Mixed-level tests are similar to application-level tests, the difference being
+that they're just snippets of app-level code embedded in an interp-level test
+file, like this::
+
class AppTestSomething(object):
def test_this(self):
# application level test code
-These application level test functions will run on top
-of PyPy, i.e. they have no access to interpreter details.
You cannot use imported modules from global level because
they are imported at interpreter-level while you test code
runs at application level. If you need to use modules
diff --git a/pypy/doc/contributing.rst b/pypy/doc/contributing.rst
--- a/pypy/doc/contributing.rst
+++ b/pypy/doc/contributing.rst
@@ -329,11 +329,18 @@
Testing After Translation
^^^^^^^^^^^^^^^^^^^^^^^^^
-While the usual invocation of `pytest` translates a piece of RPython code and
-runs it, we have a test extension to run tests without translation, directly
-on the host python. This is very convenient for modules such as `cpyext`, to
-compare and contrast test results between CPython and PyPy. Untranslated tests
-are invoked by using the `-A` or `--runappdirect` option to `pytest`::
+While the usual invocation of `pytest` runs app-level tests on an untranslated
+PyPy that runs on top of CPython, we have a test extension to run tests
+directly on the host python. This is very convenient for modules such as
+`cpyext`, to compare and contrast test results between CPython and PyPy.
+
+App-level tests run directly on the host interpreter when passing `-D` or
+`--direct-apptest` to `pytest`::
+
+ pypy3 -m pytest -D pypy/interpreter/test/apptest_pyframe.py
+
+Mixed-level tests are invoked by using the `-A` or `--runappdirect` option to
+`pytest`::
python2 pytest.py -A pypy/module/cpyext/test
diff --git a/pypy/goal/targetpypystandalone.py
b/pypy/goal/targetpypystandalone.py
--- a/pypy/goal/targetpypystandalone.py
+++ b/pypy/goal/targetpypystandalone.py
@@ -328,10 +328,10 @@
translate.log_config(config.objspace, "PyPy config object")
# obscure hack to stuff the translation options into the translated
PyPy
- import pypy.module.sys
+ from pypy.module.sys.moduledef import Module as SysModule
options = make_dict(config)
- wrapstr = 'space.wrap(%r)' % (options) # import time
- pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] =
wrapstr
+ wrapstr = 'space.wrap(%r)' % (options) # import time
+ SysModule.interpleveldefs['pypy_translation_info'] = wrapstr
if config.objspace.usemodules._cffi_backend:
self.hack_for_cffi_modules(driver)
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -520,13 +520,14 @@
return self.__class__.__name__
@not_rpython
- def setbuiltinmodule(self, importname):
+ def setbuiltinmodule(self, pkgname):
"""load a lazy pypy/module and put it into sys.modules"""
- if '.' in importname:
- fullname = importname
- importname = fullname.rsplit('.', 1)[1]
+ if '.' in pkgname:
+ fullname = "%s.moduledef" % (pkgname,)
+ importname = pkgname.rsplit('.', 1)[1]
else:
- fullname = "pypy.module.%s" % importname
+ fullname = "pypy.module.%s.moduledef" % pkgname
+ importname = pkgname
Module = __import__(fullname,
None, None, ["Module"]).Module
@@ -623,22 +624,22 @@
def make_builtins(self):
"only for initializing the space."
- from pypy.module.exceptions import Module
+ from pypy.module.exceptions.moduledef import Module
w_name = self.newtext('exceptions')
self.exceptions_module = Module(self, w_name)
self.exceptions_module.install()
- from pypy.module.sys import Module
+ from pypy.module.imp.moduledef import Module
+ w_name = self.newtext('imp')
+ mod = Module(self, w_name)
+ mod.install()
+
+ from pypy.module.sys.moduledef import Module
w_name = self.newtext('sys')
self.sys = Module(self, w_name)
self.sys.install()
- from pypy.module.imp import Module
- w_name = self.newtext('imp')
- mod = Module(self, w_name)
- mod.install()
-
- from pypy.module.__builtin__ import Module
+ from pypy.module.__builtin__.moduledef import Module
w_name = self.newtext('__builtin__')
self.builtin = Module(self, w_name)
w_builtin = self.wrap(self.builtin)
diff --git a/pypy/interpreter/main.py b/pypy/interpreter/main.py
--- a/pypy/interpreter/main.py
+++ b/pypy/interpreter/main.py
@@ -32,7 +32,7 @@
try:
if space is None:
- from pypy.objspace.std import StdObjSpace
+ from pypy.objspace.std.objspace import StdObjSpace
space = StdObjSpace()
pycode = compilecode(space, source, filename or '<string>', cmd)
@@ -79,7 +79,7 @@
implementation.
"""
if space is None:
- from pypy.objspace.std import StdObjSpace
+ from pypy.objspace.std.objspace import StdObjSpace
space = StdObjSpace()
argv = [module_name]
if args is not None:
diff --git a/pypy/interpreter/mixedmodule.py b/pypy/interpreter/mixedmodule.py
--- a/pypy/interpreter/mixedmodule.py
+++ b/pypy/interpreter/mixedmodule.py
@@ -28,17 +28,21 @@
@not_rpython
def install(self):
- """install this module, and it's submodules into
+ """Install this module, and its submodules into
space.builtin_modules"""
Module.install(self)
if hasattr(self, "submodules"):
space = self.space
- name = space.unwrap(self.w_name)
+ pkgname = space.text_w(self.w_name)
for sub_name, module_cls in self.submodules.iteritems():
if module_cls.submodule_name is None:
module_cls.submodule_name = sub_name
- module_name = space.newtext("%s.%s" % (name, sub_name))
- m = module_cls(space, module_name)
+ else:
+ assert module_cls.submodule_name == sub_name
+ name = "%s.%s" % (pkgname, sub_name)
+ module_cls.applevel_name = name
+ w_name = space.newtext(name)
+ m = module_cls(space, w_name)
m.install()
self.submodules_w.append(m)
@@ -70,8 +74,7 @@
if cls.applevel_name is not None:
return cls.applevel_name
else:
- pkgroot = cls.__module__
- return pkgroot.split('.')[-1]
+ return cls.__module__.split('.')[-2]
def get(self, name):
space = self.space
@@ -140,10 +143,8 @@
# build a constant dictionary out of
# applevel/interplevel definitions
cls.loaders = loaders = {}
- pkgroot = cls.__module__
+ pkgroot = cls.__module__.rsplit('.', 1)[0]
appname = cls.get_applevel_name()
- if cls.submodule_name is not None:
- appname += '.%s' % (cls.submodule_name,)
for name, spec in cls.interpleveldefs.items():
loaders[name] = getinterpevalloader(pkgroot, spec)
for name, spec in cls.appleveldefs.items():
@@ -154,7 +155,7 @@
def extra_interpdef(self, name, spec):
cls = self.__class__
- pkgroot = cls.__module__
+ pkgroot = cls.__module__.rsplit('.', 1)[0]
loader = getinterpevalloader(pkgroot, spec)
space = self.space
w_obj = loader(space)
diff --git a/pypy/interpreter/test/apptest_pyframe.py
b/pypy/interpreter/test/apptest_pyframe.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/test/apptest_pyframe.py
@@ -0,0 +1,575 @@
+import pytest
+
[email protected]
+def tempfile(tmpdir):
+ return str(tmpdir / 'tempfile1')
+
+def test_f_locals():
+ import sys
+ f = sys._getframe()
+ assert f.f_locals is locals()
+
+def test_f_globals():
+ import sys
+ f = sys._getframe()
+ assert f.f_globals is globals()
+ pytest.raises(TypeError, "f.f_globals = globals()")
+
+def test_f_builtins():
+ import sys, __builtin__
+ f = sys._getframe()
+ assert f.f_builtins is __builtin__.__dict__
+
+def test_f_code():
+ def g():
+ import sys
+ f = sys._getframe()
+ return f.f_code
+ assert g() is g.func_code
+
+def test_f_trace_del():
+ import sys
+ f = sys._getframe()
+ del f.f_trace
+ assert f.f_trace is None
+
+def test_f_lineno():
+ def g():
+ import sys
+ f = sys._getframe()
+ x = f.f_lineno
+ y = f.f_lineno
+ z = f.f_lineno
+ return [x, y, z]
+ origin = g.func_code.co_firstlineno
+ assert g() == [origin+3, origin+4, origin+5]
+
+def test_f_lineno_set(tempfile):
+ def tracer(f, *args):
+ def y(f, *args):
+ return y
+ def x(f, *args):
+ f.f_lineno += 1
+ return y # "return None" should have the same effect, but see
+ # test_local_trace_function_returning_None_ignored
+ return x
+
+ open # force fetching of this name now
+
+ def function():
+ xyz
+ with open(tempfile, 'w') as f:
+ pass
+ return 3
+
+ import sys
+ sys.settrace(tracer)
+ function()
+ sys.settrace(None)
+ # assert did not crash
+
+def test_f_lineno_set_firstline():
+ seen = []
+ def tracer(f, event, *args):
+ seen.append((event, f.f_lineno))
+ if len(seen) == 5:
+ f.f_lineno = 1 # bug shown only when setting lineno to 1
+ return tracer
+
+ def g():
+ import sys
+ sys.settrace(tracer)
+ exec "x=1\ny=x+1\nz=y+1\nt=z+1\ns=t+1\n" in {}
+ sys.settrace(None)
+
+ g()
+ assert seen == [('call', 1),
+ ('line', 1),
+ ('line', 2),
+ ('line', 3),
+ ('line', 4),
+ ('line', 2),
+ ('line', 3),
+ ('line', 4),
+ ('line', 5),
+ ('return', 5)]
+
+def test_f_back():
+ import sys
+ def f():
+ assert sys._getframe().f_code.co_name == g()
+ def g():
+ return sys._getframe().f_back.f_code.co_name
+ f()
+
+def test_f_back_virtualref():
+ import sys
+ def f():
+ return g()
+ def g():
+ return sys._getframe()
+ frame = f()
+ assert frame.f_back.f_code.co_name == 'f'
+
+def test_f_exc_xxx():
+ import sys
+
+ class OuterException(Exception):
+ pass
+ class InnerException(Exception):
+ pass
+
+ def g(exc_info):
+ f = sys._getframe()
+ assert f.f_exc_type is None
+ assert f.f_exc_value is None
+ assert f.f_exc_traceback is None
+ try:
+ raise InnerException
+ except:
+ assert f.f_exc_type is exc_info[0]
+ assert f.f_exc_value is exc_info[1]
+ assert f.f_exc_traceback is exc_info[2]
+ try:
+ raise OuterException
+ except:
+ g(sys.exc_info())
+
+def test_virtualref_through_traceback():
+ import sys
+ def g():
+ try:
+ raise ValueError
+ except:
+ _, _, tb = sys.exc_info()
+ return tb
+ def f():
+ return g()
+ #
+ tb = f()
+ assert tb.tb_frame.f_code.co_name == 'g'
+ assert tb.tb_frame.f_back.f_code.co_name == 'f'
+
+def test_trace_basic():
+ import sys
+ l = []
+ class Tracer:
+ def __init__(self, i):
+ self.i = i
+ def trace(self, frame, event, arg):
+ l.append((self.i, frame.f_code.co_name, event, arg))
+ if frame.f_code.co_name == 'g2':
+ return None # don't trace g2
+ return Tracer(self.i+1).trace
+ def g3(n):
+ n -= 5
+ return n
+ def g2(n):
+ n += g3(2)
+ n += g3(7)
+ return n
+ def g(n):
+ n += g2(3)
+ return n
+ def f(n):
+ n = g(n)
+ return n * 7
+ sys.settrace(Tracer(0).trace)
+ x = f(4)
+ sys.settrace(None)
+ assert x == 42
+ print l
+ assert l == [(0, 'f', 'call', None),
+ (1, 'f', 'line', None),
+ (0, 'g', 'call', None),
+ (1, 'g', 'line', None),
+ (0, 'g2', 'call', None),
+ (0, 'g3', 'call', None),
+ (1, 'g3', 'line', None),
+ (2, 'g3', 'line', None),
+ (3, 'g3', 'return', -3),
+ (0, 'g3', 'call', None),
+ (1, 'g3', 'line', None),
+ (2, 'g3', 'line', None),
+ (3, 'g3', 'return', 2),
+ (2, 'g', 'line', None),
+ (3, 'g', 'return', 6),
+ (2, 'f', 'line', None),
+ (3, 'f', 'return', 42)]
+
+def test_trace_exc():
+ import sys
+ l = []
+ def ltrace(a,b,c):
+ if b == 'exception':
+ l.append(c)
+ return ltrace
+ def trace(a,b,c): return ltrace
+ def f():
+ try:
+ raise Exception
+ except:
+ pass
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert isinstance(l[0][1], Exception)
+
+def test_trace_ignore_hidden():
+ import sys
+ import _testing
+
+ l = []
+ def trace(a,b,c):
+ l.append((a,b,c))
+
+ def f():
+ h = _testing.Hidden()
+ r = h.meth()
+ return r
+
+ sys.settrace(trace)
+ res = f()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert l[0][1] == 'call'
+ assert res == 'hidden' # sanity
+
+def test_trace_hidden_prints(tempfile):
+ import sys
+
+ l = []
+ def trace(a,b,c):
+ l.append((a,b,c))
+ return trace
+
+ outputf = open(tempfile, 'w')
+ def f():
+ print >> outputf, 1
+ print >> outputf, 2
+ print >> outputf, 3
+ return "that's the return value"
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ outputf.close()
+ # should get 1 "call", 3 "line" and 1 "return" events, and no call
+ # or return for the internal app-level implementation of 'print'
+ assert len(l) == 6
+ assert [what for (frame, what, arg) in l] == [
+ 'call', 'line', 'line', 'line', 'line', 'return']
+ assert l[-1][2] == "that's the return value"
+
+def test_trace_return_exc():
+ import sys
+ l = []
+ def trace(a,b,c):
+ if b in ('exception', 'return'):
+ l.append((b, c))
+ return trace
+
+ def g():
+ raise Exception
+ def f():
+ try:
+ g()
+ except:
+ pass
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 4
+ assert l[0][0] == 'exception'
+ assert isinstance(l[0][1][1], Exception)
+ assert l[1] == ('return', None)
+ assert l[2][0] == 'exception'
+ assert isinstance(l[2][1][1], Exception)
+ assert l[3] == ('return', None)
+
+def test_trace_raises_on_return():
+ import sys
+ def trace(frame, event, arg):
+ if event == 'return':
+ raise ValueError
+ else:
+ return trace
+
+ def f(): return 1
+
+ for i in xrange(sys.getrecursionlimit() + 1):
+ sys.settrace(trace)
+ try:
+ f()
+ except ValueError:
+ pass
+
+def test_trace_try_finally():
+ import sys
+ l = []
+ def trace(frame, event, arg):
+ if event == 'exception':
+ l.append(arg)
+ return trace
+
+ def g():
+ try:
+ raise Exception
+ finally:
+ pass
+
+ def f():
+ try:
+ g()
+ except:
+ pass
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 2
+ assert issubclass(l[0][0], Exception)
+ assert issubclass(l[1][0], Exception)
+
+def test_trace_raise_three_arg():
+ import sys
+ l = []
+ def trace(frame, event, arg):
+ if event == 'exception':
+ l.append(arg)
+ return trace
+
+ def g():
+ try:
+ raise Exception
+ except Exception as e:
+ import sys
+ raise Exception, e, sys.exc_info()[2]
+
+ def f():
+ try:
+ g()
+ except:
+ pass
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 2
+ assert issubclass(l[0][0], Exception)
+ assert issubclass(l[1][0], Exception)
+
+def test_trace_generator_finalisation():
+ import sys
+ l = []
+ got_exc = []
+ def trace(frame, event, arg):
+ l.append((frame.f_lineno, event))
+ if event == 'exception':
+ got_exc.append(arg)
+ return trace
+
+ d = {}
+ exec """if 1:
+ def g():
+ try:
+ yield True
+ finally:
+ pass
+
+ def f():
+ try:
+ gen = g()
+ gen.next()
+ gen.close()
+ except:
+ pass
+ """ in d
+ f = d['f']
+
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(got_exc) == 1
+ assert issubclass(got_exc[0][0], GeneratorExit)
+ assert l == [(8, 'call'),
+ (9, 'line'),
+ (10, 'line'),
+ (11, 'line'),
+ (2, 'call'),
+ (3, 'line'),
+ (4, 'line'),
+ (4, 'return'),
+ (12, 'line'),
+ (4, 'call'),
+ (4, 'exception'),
+ (6, 'line'),
+ (6, 'return'),
+ (12, 'return')]
+
+def test_dont_trace_on_reraise():
+ import sys
+ l = []
+ def ltrace(a,b,c):
+ if b == 'exception':
+ l.append(c)
+ return ltrace
+ def trace(a,b,c): return ltrace
+ def f():
+ try:
+ 1/0
+ except:
+ try:
+ raise
+ except:
+ pass
+ sys.settrace(trace)
+ f()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert issubclass(l[0][0], Exception)
+
+def test_dont_trace_on_raise_with_tb():
+ import sys
+ l = []
+ def ltrace(a,b,c):
+ if b == 'exception':
+ l.append(c)
+ return ltrace
+ def trace(a,b,c): return ltrace
+ def f():
+ try:
+ raise Exception
+ except:
+ return sys.exc_info()
+ def g():
+ exc, val, tb = f()
+ try:
+ raise exc, val, tb
+ except:
+ pass
+ sys.settrace(trace)
+ g()
+ sys.settrace(None)
+ assert len(l) == 1
+ assert isinstance(l[0][1], Exception)
+
+def test_trace_changes_locals():
+ import sys
+ def trace(frame, what, arg):
+ frame.f_locals['x'] = 42
+ return trace
+ def f(x):
+ return x
+ sys.settrace(trace)
+ res = f(1)
+ sys.settrace(None)
+ assert res == 42
+
+def test_set_unset_f_trace():
+ import sys
+ seen = []
+ def trace1(frame, what, arg):
+ seen.append((1, frame, frame.f_lineno, what, arg))
+ return trace1
+ def trace2(frame, what, arg):
+ seen.append((2, frame, frame.f_lineno, what, arg))
+ return trace2
+ def set_the_trace(f):
+ f.f_trace = trace1
+ sys.settrace(trace2)
+ len(seen) # take one line: should not be traced
+ f = sys._getframe()
+ set_the_trace(f)
+ len(seen) # take one line: should not be traced
+ len(seen) # take one line: should not be traced
+ sys.settrace(None) # and this line should be the last line traced
+ len(seen) # take one line
+ del f.f_trace
+ len(seen) # take one line
+ firstline = set_the_trace.func_code.co_firstlineno
+ assert seen == [(1, f, firstline + 6, 'line', None),
+ (1, f, firstline + 7, 'line', None),
+ (1, f, firstline + 8, 'line', None)]
+
+def test_locals2fast_freevar_bug():
+ import sys
+ def f(n):
+ class A(object):
+ def g(self):
+ return n
+ n = 42
+ return A()
+ res = f(10).g()
+ assert res == 10
+ #
+ def trace(*args):
+ return trace
+ sys.settrace(trace)
+ res = f(10).g()
+ sys.settrace(None)
+ assert res == 10
+
+def test_throw_trace_bug():
+ import sys
+ def f():
+ yield 5
+ gen = f()
+ assert next(gen) == 5
+ seen = []
+ def trace_func(frame, event, *args):
+ seen.append(event)
+ return trace_func
+ sys.settrace(trace_func)
+ try:
+ gen.throw(ValueError)
+ except ValueError:
+ pass
+ sys.settrace(None)
+ assert seen == ['call', 'exception', 'return']
+
+def test_generator_trace_stopiteration():
+ import sys
+ def f():
+ yield 5
+ gen = f()
+ assert next(gen) == 5
+ seen = []
+ def trace_func(frame, event, *args):
+ print('TRACE:', frame, event, args)
+ seen.append(event)
+ return trace_func
+ def g():
+ for x in gen:
+ never_entered
+ sys.settrace(trace_func)
+ g()
+ sys.settrace(None)
+ print 'seen:', seen
+ # on Python 3 we get an extra 'exception' when 'for' catches
+ # StopIteration
+ assert seen == ['call', 'line', 'call', 'return', 'return']
+
+def test_local_trace_function_returning_None_ignored():
+ # behave the same as CPython does, and in contradiction with
+ # the documentation.
+ def tracer(f, event, arg):
+ assert event == 'call'
+ return local_tracer
+
+ seen = []
+ def local_tracer(f, event, arg):
+ seen.append(event)
+ return None # but 'local_tracer' will be called again
+
+ def function():
+ a = 1
+ a = 2
+ a = 3
+
+ import sys
+ sys.settrace(tracer)
+ function()
+ sys.settrace(None)
+ assert seen == ["line", "line", "line", "return"]
diff --git a/pypy/interpreter/test/demomixedmod/__init__.py
b/pypy/interpreter/test/demomixedmod/__init__.py
--- a/pypy/interpreter/test/demomixedmod/__init__.py
+++ b/pypy/interpreter/test/demomixedmod/__init__.py
@@ -1,15 +0,0 @@
-from pypy.interpreter.mixedmodule import MixedModule
-
-class Module(MixedModule):
- interpleveldefs = {
- '__name__' : '(space.wrap("mixedmodule"))',
- '__doc__' : '(space.wrap("mixedmodule doc"))',
- 'somefunc' : 'file1.somefunc',
- 'value' : '(space.w_None)',
- 'path' : 'file1.initpath(space)',
- 'cpypath' : 'space.wrap(sys.path)'
- }
-
- appleveldefs = {
- 'someappfunc' : 'file2_app.someappfunc',
- }
diff --git a/pypy/interpreter/test/demomixedmod/__init__.py
b/pypy/interpreter/test/demomixedmod/moduledef.py
copy from pypy/interpreter/test/demomixedmod/__init__.py
copy to pypy/interpreter/test/demomixedmod/moduledef.py
diff --git a/pypy/interpreter/test/fixtures.py
b/pypy/interpreter/test/fixtures.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/test/fixtures.py
@@ -0,0 +1,5 @@
+from _pytest.tmpdir import TempdirFactory
+
+def tempfile(space, config):
+ tmpdir = TempdirFactory(config).getbasetemp()
+ return space.newtext(str(tmpdir / 'tempfile1'))
diff --git a/pypy/interpreter/test/test_appinterp.py
b/pypy/interpreter/test/test_appinterp.py
--- a/pypy/interpreter/test/test_appinterp.py
+++ b/pypy/interpreter/test/test_appinterp.py
@@ -3,32 +3,32 @@
from pypy.interpreter.gateway import appdef, ApplevelClass, applevel_temp
from pypy.interpreter.error import OperationError
-def test_execwith_novars(space):
- val = space.appexec([], """
- ():
- return 42
- """)
+def test_execwith_novars(space):
+ val = space.appexec([], """
+ ():
+ return 42
+ """)
assert space.eq_w(val, space.wrap(42))
-def test_execwith_withvars(space):
+def test_execwith_withvars(space):
val = space.appexec([space.wrap(7)], """
- (x):
- y = 6 * x
- return y
- """)
+ (x):
+ y = 6 * x
+ return y
+ """)
assert space.eq_w(val, space.wrap(42))
-def test_execwith_compile_error(space):
+def test_execwith_compile_error(space):
excinfo = py.test.raises(OperationError, space.appexec, [], """
- ():
- y y
+ ():
+ y y
""")
# NOTE: the following test only works because excinfo.value is not
# normalized so far
- assert str(excinfo.value.get_w_value(space)).find('y y') != -1
+ assert str(excinfo.value.get_w_value(space)).find('y y') != -1
def test_simple_applevel(space):
- app = appdef("""app(x,y):
+ app = appdef("""app(x,y):
return x + y
""")
assert app.func_name == 'app'
@@ -36,15 +36,15 @@
assert space.eq_w(w_result, space.wrap(42))
def test_applevel_with_one_default(space):
- app = appdef("""app(x,y=1):
+ app = appdef("""app(x,y=1):
return x + y
""")
assert app.func_name == 'app'
- w_result = app(space, space.wrap(41))
+ w_result = app(space, space.wrap(41))
assert space.eq_w(w_result, space.wrap(42))
def test_applevel_with_two_defaults(space):
- app = appdef("""app(x=1,y=2):
+ app = appdef("""app(x=1,y=2):
return x + y
""")
w_result = app(space, space.wrap(41), space.wrap(1))
@@ -58,19 +58,19 @@
def test_applevel_noargs(space):
- app = appdef("""app():
- return 42
+ app = appdef("""app():
+ return 42
""")
assert app.func_name == 'app'
- w_result = app(space)
+ w_result = app(space)
assert space.eq_w(w_result, space.wrap(42))
-def somefunc(arg2=42):
- return arg2
+def somefunc(arg2=42):
+ return arg2
-def test_app2interp_somefunc(space):
- app = appdef(somefunc)
- w_result = app(space)
+def test_app2interp_somefunc(space):
+ app = appdef(somefunc)
+ w_result = app(space)
assert space.eq_w(w_result, space.wrap(42))
def test_applevel_functions(space, applevel_temp = applevel_temp):
@@ -87,48 +87,49 @@
def test_applevel_class(space, applevel_temp = applevel_temp):
app = applevel_temp('''
class C(object):
- clsattr = 42
- def __init__(self, x=13):
- self.attr = x
+ clsattr = 42
+ def __init__(self, x=13):
+ self.attr = x
''')
C = app.interphook('C')
- c = C(space, space.wrap(17))
+ c = C(space, space.wrap(17))
w_attr = space.getattr(c, space.wrap('clsattr'))
assert space.eq_w(w_attr, space.wrap(42))
w_clsattr = space.getattr(c, space.wrap('attr'))
assert space.eq_w(w_clsattr, space.wrap(17))
-def app_test_something_at_app_level():
+def app_test_something_at_app_level():
x = 2
assert x/2 == 1
-class AppTestMethods:
- def test_some_app_test_method(self):
+class AppTestMethods:
+ def test_some_app_test_method(self):
assert 2 == 2
-class TestMixedModule:
- def test_accesses(self):
+class TestMixedModule:
+ def test_accesses(self):
space = self.space
- import demomixedmod
- w_module = demomixedmod.Module(space, space.wrap('mixedmodule'))
+ from .demomixedmod.moduledef import Module
+ w_module = Module(space, space.wrap('mixedmodule'))
space.appexec([w_module], """
- (module):
- assert module.value is None
+ (module):
+ assert module.value is None
assert module.__doc__ == 'mixedmodule doc'
- assert module.somefunc is module.somefunc
- result = module.somefunc()
- assert result == True
+ assert module.somefunc is module.somefunc
+ result = module.somefunc()
+ assert result == True
- assert module.someappfunc is module.someappfunc
- appresult = module.someappfunc(41)
- assert appresult == 42
+ assert module.someappfunc is module.someappfunc
+ appresult = module.someappfunc(41)
+ assert appresult == 42
assert module.__dict__ is module.__dict__
- for name in ('somefunc', 'someappfunc', '__doc__',
'__name__'):
+ for name in ('somefunc', 'someappfunc', '__doc__', '__name__'):
assert name in module.__dict__
""")
assert space.is_true(w_module.call('somefunc'))
+ assert Module.get_applevel_name() == 'demomixedmod'
def test_whacking_at_loaders(self):
"""Some MixedModules change 'self.loaders' in __init__(), but doing
diff --git a/pypy/interpreter/test/test_extmodules.py
b/pypy/interpreter/test/test_extmodules.py
--- a/pypy/interpreter/test/test_extmodules.py
+++ b/pypy/interpreter/test/test_extmodules.py
@@ -2,10 +2,10 @@
import pytest
from pypy.config.pypyoption import get_pypy_config
-from pypy.objspace.std import StdObjSpace
+from pypy.objspace.std.objspace import StdObjSpace
from rpython.tool.udir import udir
-mod_init = """
+mod_def = """
from pypy.interpreter.mixedmodule import MixedModule
import time
@@ -45,8 +45,9 @@
pkg.join("__init__.py").write("# package")
mod = pkg.join("extmod")
mod.ensure(dir=True)
- mod.join("__init__.py").write(mod_init)
+ mod.join("__init__.py").write("#")
mod.join("interp_time.py").write(mod_interp)
+ mod.join("moduledef.py").write(mod_def)
class AppTestExtModules(object):
def setup_class(cls):
diff --git a/pypy/interpreter/test/test_mixedmodule.py
b/pypy/interpreter/test/test_mixedmodule.py
--- a/pypy/interpreter/test/test_mixedmodule.py
+++ b/pypy/interpreter/test/test_mixedmodule.py
@@ -29,7 +29,10 @@
m.install()
assert self.space.builtin_modules["test_module"] is m
- assert isinstance(self.space.builtin_modules["test_module.sub"],
SubModule)
+ submod = self.space.builtin_modules["test_module.sub"]
+ assert isinstance(submod, SubModule)
+ assert submod.get_applevel_name() == "test_module.sub"
+
class AppTestMixedModule(object):
pytestmark = py.test.mark.skipif("config.option.runappdirect")
diff --git a/pypy/interpreter/test/test_pyframe.py
b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -1,4 +1,3 @@
-from rpython.tool import udir
from pypy.conftest import option
from pypy.interpreter.gateway import interp2app
@@ -9,8 +8,6 @@
def setup_class(cls):
space = cls.space
- cls.w_udir = cls.space.wrap(str(udir.udir))
- cls.w_tempfile1 = cls.space.wrap(str(udir.udir.join('tempfile1')))
if not option.runappdirect:
w_call_further = cls.space.appexec([], """():
def call_further(f):
@@ -25,113 +22,6 @@
# test for the presence of the attributes, not functionality
- def test_f_locals(self):
- import sys
- f = sys._getframe()
- assert f.f_locals is locals()
-
- def test_f_globals(self):
- import sys
- f = sys._getframe()
- assert f.f_globals is globals()
- raises(TypeError, "f.f_globals = globals()")
-
- def test_f_builtins(self):
- import sys, __builtin__
- f = sys._getframe()
- assert f.f_builtins is __builtin__.__dict__
-
- def test_f_code(self):
- def g():
- import sys
- f = sys._getframe()
- return f.f_code
- assert g() is g.func_code
-
- def test_f_trace_del(self):
- import sys
- f = sys._getframe()
- del f.f_trace
- assert f.f_trace is None
-
- def test_f_lineno(self):
- def g():
- import sys
- f = sys._getframe()
- x = f.f_lineno
- y = f.f_lineno
- z = f.f_lineno
- return [x, y, z]
- origin = g.func_code.co_firstlineno
- assert g() == [origin+3, origin+4, origin+5]
-
- def test_f_lineno_set(self):
- def tracer(f, *args):
- def y(f, *args):
- return y
- def x(f, *args):
- f.f_lineno += 1
- return y # "return None" should have the same effect, but see
- # test_local_trace_function_returning_None_ignored
- return x
-
- open # force fetching of this name now
-
- def function():
- xyz
- with open(self.tempfile1, 'w') as f:
- pass
- return 3
-
- import sys
- sys.settrace(tracer)
- function()
- sys.settrace(None)
- # assert did not crash
-
- def test_f_lineno_set_firstline(self):
- seen = []
- def tracer(f, event, *args):
- seen.append((event, f.f_lineno))
- if len(seen) == 5:
- f.f_lineno = 1 # bug shown only when setting lineno to 1
- return tracer
-
- def g():
- import sys
- sys.settrace(tracer)
- exec "x=1\ny=x+1\nz=y+1\nt=z+1\ns=t+1\n" in {}
- sys.settrace(None)
-
- g()
- assert seen == [('call', 1),
- ('line', 1),
- ('line', 2),
- ('line', 3),
- ('line', 4),
- ('line', 2),
- ('line', 3),
- ('line', 4),
- ('line', 5),
- ('return', 5)]
-
- def test_f_back(self):
- import sys
- def f():
- assert sys._getframe().f_code.co_name == g()
- def g():
- return sys._getframe().f_back.f_code.co_name
- f()
-
- def test_f_back_virtualref(self):
- import sys
- def f():
- return g()
- def g():
- return sys._getframe()
- frame = f()
- assert frame.f_back.f_code.co_name == 'f'
-
def test_f_back_hidden(self):
if not hasattr(self, 'call_further'):
skip("not for runappdirect testing")
@@ -148,362 +38,6 @@
assert f1bis is f1
assert f0.f_back is f1
- def test_f_exc_xxx(self):
- import sys
-
- class OuterException(Exception):
- pass
- class InnerException(Exception):
- pass
-
- def g(exc_info):
- f = sys._getframe()
- assert f.f_exc_type is None
- assert f.f_exc_value is None
- assert f.f_exc_traceback is None
- try:
- raise InnerException
- except:
- assert f.f_exc_type is exc_info[0]
- assert f.f_exc_value is exc_info[1]
- assert f.f_exc_traceback is exc_info[2]
- try:
- raise OuterException
- except:
- g(sys.exc_info())
-
- def test_virtualref_through_traceback(self):
- import sys
- def g():
- try:
- raise ValueError
- except:
- _, _, tb = sys.exc_info()
- return tb
- def f():
- return g()
- #
- tb = f()
- assert tb.tb_frame.f_code.co_name == 'g'
- assert tb.tb_frame.f_back.f_code.co_name == 'f'
-
- def test_trace_basic(self):
- import sys
- l = []
- class Tracer:
- def __init__(self, i):
- self.i = i
- def trace(self, frame, event, arg):
- l.append((self.i, frame.f_code.co_name, event, arg))
- if frame.f_code.co_name == 'g2':
- return None # don't trace g2
- return Tracer(self.i+1).trace
- def g3(n):
- n -= 5
- return n
- def g2(n):
- n += g3(2)
- n += g3(7)
- return n
- def g(n):
- n += g2(3)
- return n
- def f(n):
- n = g(n)
- return n * 7
- sys.settrace(Tracer(0).trace)
- x = f(4)
- sys.settrace(None)
- assert x == 42
- print l
- assert l == [(0, 'f', 'call', None),
- (1, 'f', 'line', None),
- (0, 'g', 'call', None),
- (1, 'g', 'line', None),
- (0, 'g2', 'call', None),
- (0, 'g3', 'call', None),
- (1, 'g3', 'line', None),
- (2, 'g3', 'line', None),
- (3, 'g3', 'return', -3),
- (0, 'g3', 'call', None),
- (1, 'g3', 'line', None),
- (2, 'g3', 'line', None),
- (3, 'g3', 'return', 2),
- (2, 'g', 'line', None),
- (3, 'g', 'return', 6),
- (2, 'f', 'line', None),
- (3, 'f', 'return', 42)]
-
- def test_trace_exc(self):
- import sys
- l = []
- def ltrace(a,b,c):
- if b == 'exception':
- l.append(c)
- return ltrace
- def trace(a,b,c): return ltrace
- def f():
- try:
- raise Exception
- except:
- pass
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 1
- assert isinstance(l[0][1], Exception)
-
- def test_trace_ignore_hidden(self):
- import sys
- import _testing
-
- l = []
- def trace(a,b,c):
- l.append((a,b,c))
-
- def f():
- h = _testing.Hidden()
- r = h.meth()
- return r
-
- sys.settrace(trace)
- res = f()
- sys.settrace(None)
- assert len(l) == 1
- assert l[0][1] == 'call'
- assert res == 'hidden' # sanity
-
- def test_trace_hidden_prints(self):
- import sys
-
- l = []
- def trace(a,b,c):
- l.append((a,b,c))
- return trace
-
- outputf = open(self.tempfile1, 'w')
- def f():
- print >> outputf, 1
- print >> outputf, 2
- print >> outputf, 3
- return "that's the return value"
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- outputf.close()
- # should get 1 "call", 3 "line" and 1 "return" events, and no call
- # or return for the internal app-level implementation of 'print'
- assert len(l) == 6
- assert [what for (frame, what, arg) in l] == [
- 'call', 'line', 'line', 'line', 'line', 'return']
- assert l[-1][2] == "that's the return value"
-
- def test_trace_return_exc(self):
- import sys
- l = []
- def trace(a,b,c):
- if b in ('exception', 'return'):
- l.append((b, c))
- return trace
-
- def g():
- raise Exception
- def f():
- try:
- g()
- except:
- pass
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 4
- assert l[0][0] == 'exception'
- assert isinstance(l[0][1][1], Exception)
- assert l[1] == ('return', None)
- assert l[2][0] == 'exception'
- assert isinstance(l[2][1][1], Exception)
- assert l[3] == ('return', None)
-
- def test_trace_raises_on_return(self):
- import sys
- def trace(frame, event, arg):
- if event == 'return':
- raise ValueError
- else:
- return trace
-
- def f(): return 1
-
- for i in xrange(sys.getrecursionlimit() + 1):
- sys.settrace(trace)
- try:
- f()
- except ValueError:
- pass
-
- def test_trace_try_finally(self):
- import sys
- l = []
- def trace(frame, event, arg):
- if event == 'exception':
- l.append(arg)
- return trace
-
- def g():
- try:
- raise Exception
- finally:
- pass
-
- def f():
- try:
- g()
- except:
- pass
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 2
- assert issubclass(l[0][0], Exception)
- assert issubclass(l[1][0], Exception)
-
- def test_trace_raise_three_arg(self):
- import sys
- l = []
- def trace(frame, event, arg):
- if event == 'exception':
- l.append(arg)
- return trace
-
- def g():
- try:
- raise Exception
- except Exception as e:
- import sys
- raise Exception, e, sys.exc_info()[2]
-
- def f():
- try:
- g()
- except:
- pass
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 2
- assert issubclass(l[0][0], Exception)
- assert issubclass(l[1][0], Exception)
-
- def test_trace_generator_finalisation(self):
- import sys
- l = []
- got_exc = []
- def trace(frame, event, arg):
- l.append((frame.f_lineno, event))
- if event == 'exception':
- got_exc.append(arg)
- return trace
-
- d = {}
- exec """if 1:
- def g():
- try:
- yield True
- finally:
- pass
-
- def f():
- try:
- gen = g()
- gen.next()
- gen.close()
- except:
- pass
- """ in d
- f = d['f']
-
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(got_exc) == 1
- assert issubclass(got_exc[0][0], GeneratorExit)
- assert l == [(8, 'call'),
- (9, 'line'),
- (10, 'line'),
- (11, 'line'),
- (2, 'call'),
- (3, 'line'),
- (4, 'line'),
- (4, 'return'),
- (12, 'line'),
- (4, 'call'),
- (4, 'exception'),
- (6, 'line'),
- (6, 'return'),
- (12, 'return')]
-
- def test_dont_trace_on_reraise(self):
- import sys
- l = []
- def ltrace(a,b,c):
- if b == 'exception':
- l.append(c)
- return ltrace
- def trace(a,b,c): return ltrace
- def f():
- try:
- 1/0
- except:
- try:
- raise
- except:
- pass
- sys.settrace(trace)
- f()
- sys.settrace(None)
- assert len(l) == 1
- assert issubclass(l[0][0], Exception)
-
- def test_dont_trace_on_raise_with_tb(self):
- import sys
- l = []
- def ltrace(a,b,c):
- if b == 'exception':
- l.append(c)
- return ltrace
- def trace(a,b,c): return ltrace
- def f():
- try:
- raise Exception
- except:
- return sys.exc_info()
- def g():
- exc, val, tb = f()
- try:
- raise exc, val, tb
- except:
- pass
- sys.settrace(trace)
- g()
- sys.settrace(None)
- assert len(l) == 1
- assert isinstance(l[0][1], Exception)
-
- def test_trace_changes_locals(self):
- import sys
- def trace(frame, what, arg):
- frame.f_locals['x'] = 42
- return trace
- def f(x):
- return x
- sys.settrace(trace)
- res = f(1)
- sys.settrace(None)
- assert res == 42
-
def test_fast2locals_called_lazily(self):
import sys
class FrameHolder:
@@ -522,110 +56,3 @@
assert res == 2
if hasattr(self, "check_no_w_locals"): # not appdirect
assert self.check_no_w_locals(fh.frame)
-
- def test_set_unset_f_trace(self):
- import sys
- seen = []
- def trace1(frame, what, arg):
- seen.append((1, frame, frame.f_lineno, what, arg))
- return trace1
- def trace2(frame, what, arg):
- seen.append((2, frame, frame.f_lineno, what, arg))
- return trace2
- def set_the_trace(f):
- f.f_trace = trace1
- sys.settrace(trace2)
- len(seen) # take one line: should not be traced
- f = sys._getframe()
- set_the_trace(f)
- len(seen) # take one line: should not be traced
- len(seen) # take one line: should not be traced
- sys.settrace(None) # and this line should be the last line traced
- len(seen) # take one line
- del f.f_trace
- len(seen) # take one line
- firstline = set_the_trace.func_code.co_firstlineno
- assert seen == [(1, f, firstline + 6, 'line', None),
- (1, f, firstline + 7, 'line', None),
- (1, f, firstline + 8, 'line', None)]
-
- def test_locals2fast_freevar_bug(self):
- import sys
- def f(n):
- class A(object):
- def g(self):
- return n
- n = 42
- return A()
- res = f(10).g()
- assert res == 10
- #
- def trace(*args):
- return trace
- sys.settrace(trace)
- res = f(10).g()
- sys.settrace(None)
- assert res == 10
-
- def test_throw_trace_bug(self):
- import sys
- def f():
- yield 5
- gen = f()
- assert next(gen) == 5
- seen = []
- def trace_func(frame, event, *args):
- seen.append(event)
- return trace_func
- sys.settrace(trace_func)
- try:
- gen.throw(ValueError)
- except ValueError:
- pass
- sys.settrace(None)
- assert seen == ['call', 'exception', 'return']
-
- def test_generator_trace_stopiteration(self):
- import sys
- def f():
- yield 5
- gen = f()
- assert next(gen) == 5
- seen = []
- def trace_func(frame, event, *args):
- print('TRACE:', frame, event, args)
- seen.append(event)
- return trace_func
- def g():
- for x in gen:
- never_entered
- sys.settrace(trace_func)
- g()
- sys.settrace(None)
- print 'seen:', seen
- # on Python 3 we get an extra 'exception' when 'for' catches
- # StopIteration
- assert seen == ['call', 'line', 'call', 'return', 'return']
-
- def test_local_trace_function_returning_None_ignored(self):
- # behave the same as CPython does, and in contradiction with
- # the documentation.
- def tracer(f, event, arg):
- assert event == 'call'
- return local_tracer
-
- seen = []
- def local_tracer(f, event, arg):
- seen.append(event)
- return None # but 'local_tracer' will be called again
-
- def function():
- a = 1
- a = 2
- a = 3
-
- import sys
- sys.settrace(tracer)
- function()
- sys.settrace(None)
- assert seen == ["line", "line", "line", "return"]
diff --git a/pypy/interpreter/unicodehelper.py
b/pypy/interpreter/unicodehelper.py
--- a/pypy/interpreter/unicodehelper.py
+++ b/pypy/interpreter/unicodehelper.py
@@ -6,7 +6,7 @@
from rpython.rlib import rutf8
from rpython.rlib.rarithmetic import r_uint, intmask
from rpython.rtyper.lltypesystem import rffi
-from pypy.module.unicodedata import unicodedb
+from pypy.module.unicodedata.interp_ucd import unicodedb
@specialize.memo()
def decode_error_handler(space):
@@ -233,7 +233,7 @@
slen = len(s)
res = runicode.unicode_encode_mbcs(s, slen, errors, errorhandler)
return res
-
+
def str_decode_mbcs(s, errors, final, errorhandler):
from rpython.rlib import runicode
slen = len(s)
diff --git a/pypy/module/__builtin__/__init__.py
b/pypy/module/__builtin__/__init__.py
--- a/pypy/module/__builtin__/__init__.py
+++ b/pypy/module/__builtin__/__init__.py
@@ -1,132 +0,0 @@
-from pypy.interpreter.error import OperationError
-from pypy.interpreter import module
-from pypy.interpreter.mixedmodule import MixedModule
-import pypy.module.imp.importing
-
-# put builtins here that should be optimized somehow
-
-class Module(MixedModule):
- """Built-in functions, exceptions, and other objects."""
-
- appleveldefs = {
- 'execfile' : 'app_io.execfile',
- 'raw_input' : 'app_io.raw_input',
- 'input' : 'app_io.input',
- 'print' : 'app_io.print_',
-
- 'apply' : 'app_functional.apply',
- 'sorted' : 'app_functional.sorted',
- 'any' : 'app_functional.any',
- 'all' : 'app_functional.all',
- 'sum' : 'app_functional.sum',
- 'map' : 'app_functional.map',
- 'reduce' : 'app_functional.reduce',
- 'filter' : 'app_functional.filter',
- 'zip' : 'app_functional.zip',
- 'vars' : 'app_inspect.vars',
- 'dir' : 'app_inspect.dir',
-
- 'bin' : 'app_operation.bin',
-
- }
-
- interpleveldefs = {
- # constants
- '__debug__' : '(space.w_True)',
- 'None' : '(space.w_None)',
- 'False' : '(space.w_False)',
- 'True' : '(space.w_True)',
- 'bytes' : '(space.w_bytes)',
-
- 'file' : 'state.get(space).w_file',
- 'open' : 'state.get(space).w_file',
-
- # default __metaclass__: old-style class
- '__metaclass__' : 'interp_classobj.W_ClassObject',
-
- # interp-level function definitions
- 'abs' : 'operation.abs',
- 'chr' : 'operation.chr',
- 'unichr' : 'operation.unichr',
- 'len' : 'operation.len',
- 'ord' : 'operation.ord',
- 'pow' : 'operation.pow',
- 'repr' : 'operation.repr',
- 'hash' : 'operation.hash',
- 'oct' : 'operation.oct',
- 'hex' : 'operation.hex',
- 'round' : 'operation.round',
- 'cmp' : 'operation.cmp',
- 'coerce' : 'operation.coerce',
- 'divmod' : 'operation.divmod',
- 'format' : 'operation.format',
- '_issubtype' : 'operation._issubtype',
- 'issubclass' : 'abstractinst.app_issubclass',
- 'isinstance' : 'abstractinst.app_isinstance',
- 'getattr' : 'operation.getattr',
- 'setattr' : 'operation.setattr',
- 'delattr' : 'operation.delattr',
- 'hasattr' : 'operation.hasattr',
- 'iter' : 'operation.iter',
- 'next' : 'operation.next',
- 'id' : 'operation.id',
- 'intern' : 'operation.intern',
- 'callable' : 'operation.callable',
-
- 'compile' : 'compiling.compile',
- 'eval' : 'compiling.eval',
-
- '__import__' : 'pypy.module.imp.importing.importhook',
- 'reload' : 'pypy.module.imp.importing.reload',
-
- 'range' : 'functional.range_int',
- 'xrange' : 'functional.W_XRange',
- 'enumerate' : 'functional.W_Enumerate',
- 'min' : 'functional.min',
- 'max' : 'functional.max',
- 'reversed' : 'functional.reversed',
- 'super' : 'descriptor.W_Super',
- 'staticmethod' : 'pypy.interpreter.function.StaticMethod',
- 'classmethod' : 'pypy.interpreter.function.ClassMethod',
- 'property' : 'descriptor.W_Property',
-
- 'globals' : 'interp_inspect.globals',
- 'locals' : 'interp_inspect.locals',
-
- }
-
- def pick_builtin(self, w_globals):
- "Look up the builtin module to use from the __builtins__ global"
- # pick the __builtins__ roughly in the same way CPython does it
- # this is obscure and slow
- space = self.space
- try:
- w_builtin = space.getitem(w_globals, space.newtext('__builtins__'))
- except OperationError as e:
- if not e.match(space, space.w_KeyError):
- raise
- else:
- if w_builtin is space.builtin: # common case
- return space.builtin
- if space.isinstance_w(w_builtin, space.w_dict):
- return module.Module(space, None, w_builtin)
- if isinstance(w_builtin, module.Module):
- return w_builtin
- # no builtin! make a default one. Give them None, at least.
- builtin = module.Module(space, None)
- space.setitem(builtin.w_dict, space.newtext('None'), space.w_None)
- return builtin
-
- def setup_after_space_initialization(self):
- """NOT_RPYTHON"""
- space = self.space
- # install the more general version of isinstance() & co. in the space
- from pypy.module.__builtin__ import abstractinst as ab
- space.abstract_isinstance_w = ab.abstract_isinstance_w.__get__(space)
- space.abstract_issubclass_w = ab.abstract_issubclass_w.__get__(space)
- space.abstract_isclass_w = ab.abstract_isclass_w.__get__(space)
- space.abstract_getclass = ab.abstract_getclass.__get__(space)
- space.exception_is_valid_class_w =
ab.exception_is_valid_class_w.__get__(space)
- space.exception_is_valid_obj_as_class_w =
ab.exception_is_valid_obj_as_class_w.__get__(space)
- space.exception_getclass = ab.exception_getclass.__get__(space)
- space.exception_issubclass_w = ab.exception_issubclass_w.__get__(space)
diff --git a/pypy/module/__builtin__/__init__.py
b/pypy/module/__builtin__/moduledef.py
copy from pypy/module/__builtin__/__init__.py
copy to pypy/module/__builtin__/moduledef.py
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
@@ -1,163 +0,0 @@
-import sys
-
-from pypy.interpreter.mixedmodule import MixedModule
-from pypy.module.imp.importing import get_pyc_magic
-from rpython.rlib import rtime
-
-
-class BuildersModule(MixedModule):
- """ Module containing string and unicode builders """
-
- appleveldefs = {}
-
- interpleveldefs = {
- "StringBuilder": "interp_builders.W_StringBuilder",
- "UnicodeBuilder": "interp_builders.W_UnicodeBuilder",
- }
-
-class TimeModule(MixedModule):
- appleveldefs = {}
- interpleveldefs = {}
- if rtime.HAS_CLOCK_GETTIME:
- interpleveldefs["clock_gettime"] = "interp_time.clock_gettime"
- interpleveldefs["clock_getres"] = "interp_time.clock_getres"
- for name in rtime.ALL_DEFINED_CLOCKS:
- interpleveldefs[name] = "space.wrap(%d)" % getattr(rtime, name)
-
-
-class ThreadModule(MixedModule):
- appleveldefs = {
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit