[pypy-commit] pypy default: Merge branch 'testing-cleanup'
rlamy
pypy.commits at gmail.com
Fri Jun 10 09:45:10 EDT 2016
Author: Ronan Lamy <ronan.lamy at gmail.com>
Branch:
Changeset: r85078:18006cfc913c
Date: 2016-06-10 14:44 +0100
http://bitbucket.org/pypy/pypy/changeset/18006cfc913c/
Log: Merge branch 'testing-cleanup'
Simplify handling of interp-level tests and make it more forward-
compatible.
diff --git a/pypy/conftest.py b/pypy/conftest.py
--- a/pypy/conftest.py
+++ b/pypy/conftest.py
@@ -76,6 +76,20 @@
def pytest_pycollect_makemodule(path, parent):
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:
+ return
+ for item in items:
+ if isinstance(item, py.test.Function):
+ if is_applevel(item):
+ item.add_marker('applevel')
+ else:
+ item.add_marker('interplevel')
+
class PyPyModule(py.test.collect.Module):
""" we take care of collecting classes both at app level
and at interp-level (because we need to stick a space
@@ -110,9 +124,6 @@
if name.startswith('AppTest'):
from pypy.tool.pytest.apptest import AppClassCollector
return AppClassCollector(name, parent=self)
- else:
- from pypy.tool.pytest.inttest import IntClassCollector
- return IntClassCollector(name, parent=self)
elif hasattr(obj, 'func_code') and self.funcnamefilter(name):
if name.startswith('app_test_'):
@@ -120,11 +131,7 @@
"generator app level functions? you must be joking"
from pypy.tool.pytest.apptest import AppTestFunction
return AppTestFunction(name, parent=self)
- elif obj.func_code.co_flags & 32: # generator function
- return pytest.Generator(name, parent=self)
- else:
- from pypy.tool.pytest.inttest import IntTestFunction
- return IntTestFunction(name, parent=self)
+ return super(PyPyModule, self).makeitem(name, obj)
def skip_on_missing_buildoption(**ropts):
__tracebackhide__ = True
@@ -153,28 +160,19 @@
def pytest_runtest_setup(__multicall__, item):
if isinstance(item, py.test.collect.Function):
- appclass = item.getparent(PyPyClassCollector)
+ appclass = item.getparent(py.test.Class)
if appclass is not None:
# Make cls.space and cls.runappdirect available in tests.
spaceconfig = getattr(appclass.obj, 'spaceconfig', None)
if spaceconfig is not None:
from pypy.tool.pytest.objspace import gettestobjspace
appclass.obj.space = gettestobjspace(**spaceconfig)
+ else:
+ appclass.obj.space = LazyObjSpaceGetter()
appclass.obj.runappdirect = option.runappdirect
__multicall__.execute()
-class PyPyClassCollector(py.test.collect.Class):
- # All pypy Test classes have a "space" member.
- def setup(self):
- cls = self.obj
- if not hasattr(cls, 'spaceconfig'):
- cls.space = LazyObjSpaceGetter()
- else:
- assert hasattr(cls, 'space') # set by pytest_runtest_setup
- super(PyPyClassCollector, self).setup()
-
-
def pytest_ignore_collect(path):
return path.check(link=1)
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -458,14 +458,17 @@
decl = str(decl) + "\n"
yield self.st, decl, 'x', (1, 2, 3, 4)
+ def test_closure_error(self):
source = """if 1:
def f(a):
del a
def x():
a
"""
- exc = py.test.raises(SyntaxError, self.run, source).value
- assert exc.msg == "Can't delete variable used in nested scopes: 'a'"
+ with py.test.raises(SyntaxError) as excinfo:
+ self.run(source)
+ msg = excinfo.value.msg
+ assert msg == "Can't delete variable used in nested scopes: 'a'"
def test_try_except_finally(self):
yield self.simple_test, """
@@ -879,7 +882,20 @@
"""
self.simple_test(source, 'ok', 1)
- def test_remove_docstring(self):
+ @py.test.mark.parametrize('expr, result', [
+ ("f1.__doc__", None),
+ ("f2.__doc__", 'docstring'),
+ ("f2()", 'docstring'),
+ ("f3.__doc__", None),
+ ("f3()", 'bar'),
+ ("C1.__doc__", None),
+ ("C2.__doc__", 'docstring'),
+ ("C3.field", 'not docstring'),
+ ("C4.field", 'docstring'),
+ ("C4.__doc__", 'docstring'),
+ ("C4.__doc__", 'docstring'),
+ ("__doc__", None),])
+ def test_remove_docstring(self, expr, result):
source = '"module_docstring"\n' + """if 1:
def f1():
'docstring'
@@ -903,19 +919,7 @@
code_w.remove_docstrings(self.space)
dict_w = self.space.newdict();
code_w.exec_code(self.space, dict_w, dict_w)
-
- yield self.check, dict_w, "f1.__doc__", None
- yield self.check, dict_w, "f2.__doc__", 'docstring'
- yield self.check, dict_w, "f2()", 'docstring'
- yield self.check, dict_w, "f3.__doc__", None
- yield self.check, dict_w, "f3()", 'bar'
- yield self.check, dict_w, "C1.__doc__", None
- yield self.check, dict_w, "C2.__doc__", 'docstring'
- yield self.check, dict_w, "C3.field", 'not docstring'
- yield self.check, dict_w, "C4.field", 'docstring'
- yield self.check, dict_w, "C4.__doc__", 'docstring'
- yield self.check, dict_w, "C4.__doc__", 'docstring'
- yield self.check, dict_w, "__doc__", None
+ self.check(dict_w, expr, result)
def test_assert_skipping(self):
space = self.space
@@ -1111,7 +1115,7 @@
return d['f'](5)
""")
assert 'generator' in space.str_w(space.repr(w_generator))
-
+
def test_list_comprehension(self):
source = "def f(): [i for i in l]"
source2 = "def f(): [i for i in l for j in l]"
diff --git a/pypy/module/_socket/test/test_sock_app.py b/pypy/module/_socket/test/test_sock_app.py
--- a/pypy/module/_socket/test/test_sock_app.py
+++ b/pypy/module/_socket/test/test_sock_app.py
@@ -671,13 +671,11 @@
class AppTestSocketTCP:
HOST = 'localhost'
-
- def setup_class(cls):
- cls.space = space
+ spaceconfig = {'usemodules': ['_socket', 'array']}
def setup_method(self, method):
- w_HOST = space.wrap(self.HOST)
- self.w_serv = space.appexec([w_socket, w_HOST],
+ w_HOST = self.space.wrap(self.HOST)
+ self.w_serv =self.space.appexec([w_socket, w_HOST],
'''(_socket, HOST):
serv = _socket.socket(_socket.AF_INET, _socket.SOCK_STREAM)
serv.bind((HOST, 0))
@@ -687,7 +685,7 @@
def teardown_method(self, method):
if hasattr(self, 'w_serv'):
- space.appexec([self.w_serv], '(serv): serv.close()')
+ self.space.appexec([self.w_serv], '(serv): serv.close()')
self.w_serv = None
def test_timeout(self):
@@ -803,8 +801,7 @@
class AppTestErrno:
- def setup_class(cls):
- cls.space = space
+ spaceconfig = {'usemodules': ['_socket']}
def test_errno(self):
from socket import socket, AF_INET, SOCK_STREAM, error
diff --git a/pypy/module/_vmprof/test/test__vmprof.py b/pypy/module/_vmprof/test/test__vmprof.py
--- a/pypy/module/_vmprof/test/test__vmprof.py
+++ b/pypy/module/_vmprof/test/test__vmprof.py
@@ -3,8 +3,9 @@
from pypy.tool.pytest.objspace import gettestobjspace
class AppTestVMProf(object):
+ spaceconfig = {'usemodules': ['_vmprof', 'struct']}
+
def setup_class(cls):
- cls.space = gettestobjspace(usemodules=['_vmprof', 'struct'])
cls.w_tmpfilename = cls.space.wrap(str(udir.join('test__vmprof.1')))
cls.w_tmpfilename2 = cls.space.wrap(str(udir.join('test__vmprof.2')))
@@ -17,7 +18,7 @@
import struct, sys, gc
WORD = struct.calcsize('l')
-
+
def count(s):
i = 0
count = 0
@@ -44,7 +45,7 @@
else:
raise AssertionError(ord(s[i]))
return count
-
+
import _vmprof
gc.collect() # try to make the weakref list deterministic
gc.collect() # by freeing all dead code objects
diff --git a/pypy/module/posix/test/test_posix2.py b/pypy/module/posix/test/test_posix2.py
--- a/pypy/module/posix/test/test_posix2.py
+++ b/pypy/module/posix/test/test_posix2.py
@@ -13,14 +13,15 @@
import sys
import signal
+USEMODULES = ['binascii', 'posix', 'struct', 'time']
+if os.name != 'nt':
+ USEMODULES += ['fcntl']
+else:
+ # On windows, os.popen uses the subprocess module
+ USEMODULES += ['_rawffi', 'thread', 'signal']
+
def setup_module(mod):
- usemodules = ['binascii', 'posix', 'struct', 'time']
- if os.name != 'nt':
- usemodules += ['fcntl']
- else:
- # On windows, os.popen uses the subprocess module
- usemodules += ['_rawffi', 'thread', 'signal']
- mod.space = gettestobjspace(usemodules=usemodules)
+ mod.space = gettestobjspace(usemodules=USEMODULES)
mod.path = udir.join('posixtestfile.txt')
mod.path.write("this is a test")
mod.path2 = udir.join('test_posix2-')
@@ -49,9 +50,10 @@
class AppTestPosix:
+ spaceconfig = {'usemodules': USEMODULES}
def setup_class(cls):
- cls.space = space
+ space = cls.space
cls.w_runappdirect = space.wrap(cls.runappdirect)
cls.w_posix = space.appexec([], GET_POSIX)
cls.w_path = space.wrap(str(path))
@@ -1145,14 +1147,10 @@
class AppTestEnvironment(object):
def setup_class(cls):
- cls.space = space
- cls.w_posix = space.appexec([], "(): import %s as m ; return m" % os.name)
- cls.w_os = space.appexec([], "(): import os; return os")
cls.w_path = space.wrap(str(path))
def test_environ(self):
- posix = self.posix
- os = self.os
+ import posix
assert posix.environ['PATH']
del posix.environ['PATH']
def fn(): posix.environ['PATH']
@@ -1160,7 +1158,7 @@
if hasattr(__import__(os.name), "unsetenv"):
def test_unsetenv_nonexisting(self):
- os = self.os
+ import os
os.unsetenv("XYZABC") #does not raise
try:
os.environ["ABCABC"]
@@ -1178,8 +1176,6 @@
class AppTestPosixUnicode:
def setup_class(cls):
- cls.space = space
- cls.w_posix = space.appexec([], GET_POSIX)
if cls.runappdirect:
# Can't change encoding
try:
@@ -1187,8 +1183,8 @@
except UnicodeEncodeError:
py.test.skip("encoding not good enough")
else:
- cls.save_fs_encoding = space.sys.filesystemencoding
- space.sys.filesystemencoding = "utf-8"
+ cls.save_fs_encoding = cls.space.sys.filesystemencoding
+ cls.space.sys.filesystemencoding = "utf-8"
def teardown_class(cls):
try:
@@ -1198,22 +1194,25 @@
def test_stat_unicode(self):
# test that passing unicode would not raise UnicodeDecodeError
+ import posix
try:
- self.posix.stat(u"ą")
+ posix.stat(u"ą")
except OSError:
pass
def test_open_unicode(self):
# Ensure passing unicode doesn't raise UnicodeEncodeError
+ import posix
try:
- self.posix.open(u"ą", self.posix.O_WRONLY)
+ posix.open(u"ą", posix.O_WRONLY)
except OSError:
pass
def test_remove_unicode(self):
# See 2 above ;)
+ import posix
try:
- self.posix.remove(u"ą")
+ posix.remove(u"ą")
except OSError:
pass
diff --git a/pypy/tool/pytest/apptest.py b/pypy/tool/pytest/apptest.py
--- a/pypy/tool/pytest/apptest.py
+++ b/pypy/tool/pytest/apptest.py
@@ -13,7 +13,6 @@
from pypy.interpreter.function import Method
from pypy.tool.pytest import appsupport
from pypy.tool.pytest.objspace import gettestobjspace
-from pypy.conftest import PyPyClassCollector
from inspect import getmro
@@ -21,13 +20,8 @@
def __init__(self, excinfo):
self.excinfo = excinfo
-marker = py.test.mark.applevel
class AppTestFunction(py.test.collect.Function):
- def __init__(self, *args, **kwargs):
- super(AppTestFunction, self).__init__(*args, **kwargs)
- self._request.applymarker(marker)
-
def _prunetraceback(self, traceback):
return traceback
@@ -122,7 +116,7 @@
self.w_instance = space.call_function(w_class)
-class AppClassCollector(PyPyClassCollector):
+class AppClassCollector(py.test.Class):
Instance = AppClassInstance
def setup(self):
diff --git a/pypy/tool/pytest/inttest.py b/pypy/tool/pytest/inttest.py
deleted file mode 100644
--- a/pypy/tool/pytest/inttest.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Collects and executes interpreter-level tests.
-#
-# Most pypy tests are of this kind.
-
-import py
-import sys
-from pypy.interpreter.error import OperationError
-from pypy.conftest import PyPyClassCollector
-
-
-def check_keyboard_interrupt(e):
- # we cannot easily convert w_KeyboardInterrupt to KeyboardInterrupt
- # in general without a space -- here is an approximation
- try:
- if e.w_type.name == 'KeyboardInterrupt':
- tb = sys.exc_info()[2]
- raise KeyboardInterrupt, KeyboardInterrupt(), tb
- except AttributeError:
- pass
-
-
-marker = py.test.mark.interplevel
-
-
-class IntTestFunction(py.test.collect.Function):
- def __init__(self, *args, **kwargs):
- super(IntTestFunction, self).__init__(*args, **kwargs)
- self._request.applymarker(marker)
-
- def runtest(self):
- try:
- super(IntTestFunction, self).runtest()
- except OperationError as e:
- check_keyboard_interrupt(e)
- raise
- except Exception as e:
- cls = e.__class__
- while cls is not Exception:
- if cls.__name__ == 'DistutilsPlatformError':
- from distutils.errors import DistutilsPlatformError
- if isinstance(e, DistutilsPlatformError):
- py.test.skip('%s: %s' % (e.__class__.__name__, e))
- cls = cls.__bases__[0]
- raise
-
-
-class IntInstanceCollector(py.test.collect.Instance):
- Function = IntTestFunction
-
-
-class IntClassCollector(PyPyClassCollector):
- Instance = IntInstanceCollector
diff --git a/pypy/tool/pytest/test/test_appsupport.py b/pypy/tool/pytest/test/test_appsupport.py
--- a/pypy/tool/pytest/test/test_appsupport.py
+++ b/pypy/tool/pytest/test/test_appsupport.py
@@ -27,11 +27,11 @@
result = testdir.runpytest("--collectonly")
assert result.ret == 0
result.stdout.fnmatch_lines([
- "*IntTestFunction*test_func*",
- "*IntClassCollector*TestClassInt*",
- "*IntTestFunction*test_method*",
+ "*Function*test_func*",
+ "*Class*TestClassInt*",
+ "*Function*test_method*",
"*AppClassCollector*AppTestClass*",
- "*AppTestMethod*",
+ "*AppTestMethod*",
])
class TestSpaceConfig:
@@ -133,5 +133,5 @@
x = 43
info = raises(ZeroDivisionError, "x/0")
- assert info.type is ZeroDivisionError
- assert isinstance(info.value, ZeroDivisionError)
+ assert info.type is ZeroDivisionError
+ assert isinstance(info.value, ZeroDivisionError)
diff --git a/pypy/tool/pytest/test/test_conftest1.py b/pypy/tool/pytest/test/test_conftest1.py
--- a/pypy/tool/pytest/test/test_conftest1.py
+++ b/pypy/tool/pytest/test/test_conftest1.py
@@ -20,11 +20,3 @@
assert not skipped and not failed
assert "app_test_something" in passed[0].nodeid
assert "test_method_app" in passed[1].nodeid
-
- def test_appdirect(self, testdir):
- sorter = testdir.inline_run(innertest, '-m', 'applevel', '--runappdirect')
- passed, skipped, failed = sorter.listoutcomes()
- assert len(passed) == 2
- print passed
- assert "app_test_something" in passed[0].nodeid
- assert "test_method_app" in passed[1].nodeid
More information about the pypy-commit
mailing list