Author: Floris Bruynooghe <[email protected]>
Branch: py3tests
Changeset: r94012:6fdcb46e0b2f
Date: 2018-03-19 18:21 +0100
http://bitbucket.org/pypy/pypy/changeset/6fdcb46e0b2f/
Log: Make untranslated app tests work on a very basic level
This can collect a module and run test functions inside it, without
any fixtures or setup.
diff --git a/_pytest/assertion/rewrite.py b/_pytest/assertion/rewrite.py
--- a/_pytest/assertion/rewrite.py
+++ b/_pytest/assertion/rewrite.py
@@ -265,10 +265,10 @@
if (not source.startswith(BOM_UTF8) and
cookie_re.match(source[0:end1]) is None and
cookie_re.match(source[end1 + 1:end2]) is None):
- if hasattr(state, "_indecode"):
- # encodings imported us again, so don't rewrite.
- return None, None
- state._indecode = True
+ # if hasattr(state, "_indecode"):
+ # # encodings imported us again, so don't rewrite.
+ # return None, None
+ # state._indecode = True
try:
try:
source.decode("ascii")
@@ -293,10 +293,21 @@
except SyntaxError:
# It's possible that this error is from some bug in the
# assertion rewriting, but I don't know of a fast way to tell.
- state.trace("failed to compile: %r" % (fn,))
+ # state.trace("failed to compile: %r" % (fn,))
return None, None
return stat, co
+
+def create_module(co):
+ """Hack to create a module from a code object created by _rewrite_test()"""
+ mod = imp.new_module(co.co_filename.split('/')[-1].split('.')[0])
+ mod.__file__ = co.co_filename
+ # mod.__cached__ = pyc
+ mod.__loader__ = None
+ exec(co, mod.__dict__)
+ return mod
+
+
def _make_rewritten_pyc(state, source_stat, pyc, co):
"""Try to dump rewritten code to *pyc*."""
if sys.platform.startswith("win"):
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -9,6 +9,7 @@
PYTHON3 = os.getenv('PYTHON3') or py.path.local.sysfind(LOOK_FOR_PYTHON3)
if PYTHON3 is not None:
PYTHON3 = str(PYTHON3)
+APPLEVEL_FN = 'apptest_*.py'
# pytest settings
rsyncdirs = ['.', '../lib-python', '../lib_pypy', '../demo']
@@ -44,7 +45,7 @@
py.test.skip('[py3k] %s' % message)
py.test.py3k_skip = py3k_skip
if config.getoption('runappdirect'):
- config.addinivalue_line('python_files', 'apptest_*.py')
+ config.addinivalue_line('python_files', APPLEVEL_FN)
def pytest_addoption(parser):
group = parser.getgroup("pypy options")
@@ -94,7 +95,11 @@
def pytest_pycollect_makemodule(path, parent):
if not parent.config.getoption('runappdirect'):
- return PyPyModule(path, parent)
+ if path.fnmatch(APPLEVEL_FN):
+ from pypy.tool.pytest.apptest2 import AppTestModule
+ return AppTestModule(path, parent)
+ else:
+ return PyPyModule(path, parent)
def is_applevel(item):
from pypy.tool.pytest.apptest import AppTestFunction
@@ -110,7 +115,8 @@
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.
@@ -194,6 +200,6 @@
def pytest_ignore_collect(path, config):
- if config.getoption('runappdirect') and not path.fnmatch('apptest_*.py'):
+ if config.getoption('runappdirect') and not path.fnmatch(APPLEVEL_FN):
return True
return path.check(link=1)
diff --git a/pypy/tool/pytest/apptest2.py b/pypy/tool/pytest/apptest2.py
new file mode 100644
--- /dev/null
+++ b/pypy/tool/pytest/apptest2.py
@@ -0,0 +1,72 @@
+import sys
+
+import pytest
+import pypy.interpreter.function
+from pypy.interpreter.error import OperationError
+from pypy.tool.pytest import objspace
+from pypy.tool.pytest import appsupport
+
+
+class AppTestModule(pytest.Module):
+
+ def collect(self):
+ space = objspace.gettestobjspace()
+ w_mod = space.appexec([] ,"""():
+ import sys
+ sys.path.insert(0, '%s')
+ import _pytest.assertion.rewrite, py.path
+
+ stat, co = _pytest.assertion.rewrite._rewrite_test(None,
py.path.local('%s'))
+ mod = _pytest.assertion.rewrite.create_module(co)
+ return mod
+ """ % (self.config.rootdir, str(self.fspath)))
+ mod_dict = w_mod.getdict(space).unwrap(space)
+ items = []
+ for name, w_obj in mod_dict.items():
+ if not name.startswith('test_'):
+ continue
+ if not isinstance(w_obj, pypy.interpreter.function.Function):
+ continue
+ items.append(AppTestFunction(name, self, w_obj))
+ return items
+
+ def setup(self):
+ pass
+
+
+class AppError(Exception):
+
+ def __init__(self, excinfo):
+ self.excinfo = excinfo
+
+
+class AppTestFunction(pytest.Item):
+
+ def __init__(self, name, parent, w_obj):
+ super(AppTestFunction, self).__init__(name, parent)
+ self.w_obj = w_obj
+
+ def runtest(self):
+ target = self.w_obj
+ space = target.space
+ self.execute_appex(space, target)
+
+ def repr_failure(self, excinfo):
+ if excinfo.errisinstance(AppError):
+ excinfo = excinfo.value.excinfo
+ return super(AppTestFunction, self).repr_failure(excinfo)
+
+ def execute_appex(self, space, w_func):
+ space.getexecutioncontext().set_sys_exc_info(None)
+ try:
+ space.call_function(w_func)
+ except OperationError as e:
+ if self.config.option.raise_operr:
+ raise
+ tb = sys.exc_info()[2]
+ if e.match(space, space.w_KeyboardInterrupt):
+ raise KeyboardInterrupt, KeyboardInterrupt(), tb
+ appexcinfo = appsupport.AppExceptionInfo(space, e)
+ if appexcinfo.traceback:
+ raise AppError, AppError(appexcinfo), tb
+ raise
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit