Merge remote-tracking branch 'upstream/features' into integrate-pytest-warnings
This commit is contained in:
commit
bd343ef757
|
@ -81,10 +81,10 @@ Changes
|
||||||
Thanks `@RonnyPfannschmidt`_ for the report and `@nicoddemus`_ for the PR.
|
Thanks `@RonnyPfannschmidt`_ for the report and `@nicoddemus`_ for the PR.
|
||||||
|
|
||||||
* Report teardown output on test failure (`#442`_).
|
* Report teardown output on test failure (`#442`_).
|
||||||
Thanks `@matclab`_ or the PR.
|
Thanks `@matclab`_ for the PR.
|
||||||
|
|
||||||
* Fix teardown error message in generated xUnit XML.
|
* Fix teardown error message in generated xUnit XML.
|
||||||
Thanks `@gdyuldin`_ or the PR.
|
Thanks `@gdyuldin`_ for the PR.
|
||||||
|
|
||||||
* Properly handle exceptions in ``multiprocessing`` tasks (`#1984`_).
|
* Properly handle exceptions in ``multiprocessing`` tasks (`#1984`_).
|
||||||
Thanks `@adborden`_ for the report and `@nicoddemus`_ for the PR.
|
Thanks `@adborden`_ for the report and `@nicoddemus`_ for the PR.
|
||||||
|
|
|
@ -87,6 +87,7 @@ class FastFilesCompleter:
|
||||||
completion.append(x[prefix_dir:])
|
completion.append(x[prefix_dir:])
|
||||||
return completion
|
return completion
|
||||||
|
|
||||||
|
|
||||||
if os.environ.get('_ARGCOMPLETE'):
|
if os.environ.get('_ARGCOMPLETE'):
|
||||||
try:
|
try:
|
||||||
import argcomplete.completers
|
import argcomplete.completers
|
||||||
|
|
|
@ -343,6 +343,7 @@ class Traceback(list):
|
||||||
l.append(entry.frame.f_locals)
|
l.append(entry.frame.f_locals)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2',
|
co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2',
|
||||||
'?', 'eval')
|
'?', 'eval')
|
||||||
|
|
||||||
|
@ -846,6 +847,7 @@ def getrawcode(obj, trycall=True):
|
||||||
return x
|
return x
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info[:2] >= (3, 5): # RecursionError introduced in 3.5
|
if sys.version_info[:2] >= (3, 5): # RecursionError introduced in 3.5
|
||||||
def is_recursion_error(excinfo):
|
def is_recursion_error(excinfo):
|
||||||
return excinfo.errisinstance(RecursionError) # noqa
|
return excinfo.errisinstance(RecursionError) # noqa
|
||||||
|
|
|
@ -265,6 +265,7 @@ def findsource(obj):
|
||||||
source.lines = [line.rstrip() for line in sourcelines]
|
source.lines = [line.rstrip() for line in sourcelines]
|
||||||
return source, lineno
|
return source, lineno
|
||||||
|
|
||||||
|
|
||||||
def getsource(obj, **kwargs):
|
def getsource(obj, **kwargs):
|
||||||
import _pytest._code
|
import _pytest._code
|
||||||
obj = _pytest._code.getrawcode(obj)
|
obj = _pytest._code.getrawcode(obj)
|
||||||
|
@ -275,6 +276,7 @@ def getsource(obj, **kwargs):
|
||||||
assert isinstance(strsrc, str)
|
assert isinstance(strsrc, str)
|
||||||
return Source(strsrc, **kwargs)
|
return Source(strsrc, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def deindent(lines, offset=None):
|
def deindent(lines, offset=None):
|
||||||
if offset is None:
|
if offset is None:
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
@ -288,6 +290,7 @@ def deindent(lines, offset=None):
|
||||||
if offset == 0:
|
if offset == 0:
|
||||||
return list(lines)
|
return list(lines)
|
||||||
newlines = []
|
newlines = []
|
||||||
|
|
||||||
def readline_generator(lines):
|
def readline_generator(lines):
|
||||||
for line in lines:
|
for line in lines:
|
||||||
yield line + '\n'
|
yield line + '\n'
|
||||||
|
|
|
@ -80,10 +80,12 @@ def install_importhook(config):
|
||||||
config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
|
config._assertstate.hook = hook = rewrite.AssertionRewritingHook(config)
|
||||||
sys.meta_path.insert(0, hook)
|
sys.meta_path.insert(0, hook)
|
||||||
config._assertstate.trace('installed rewrite import hook')
|
config._assertstate.trace('installed rewrite import hook')
|
||||||
|
|
||||||
def undo():
|
def undo():
|
||||||
hook = config._assertstate.hook
|
hook = config._assertstate.hook
|
||||||
if hook is not None and hook in sys.meta_path:
|
if hook is not None and hook in sys.meta_path:
|
||||||
sys.meta_path.remove(hook)
|
sys.meta_path.remove(hook)
|
||||||
|
|
||||||
config.add_cleanup(undo)
|
config.add_cleanup(undo)
|
||||||
return hook
|
return hook
|
||||||
|
|
||||||
|
|
|
@ -276,6 +276,7 @@ def _write_pyc(state, co, source_stat, pyc):
|
||||||
fp.close()
|
fp.close()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
RN = "\r\n".encode("utf-8")
|
RN = "\r\n".encode("utf-8")
|
||||||
N = "\n".encode("utf-8")
|
N = "\n".encode("utf-8")
|
||||||
|
|
||||||
|
|
|
@ -153,6 +153,7 @@ class CaptureManager:
|
||||||
item.add_report_section(when, "stdout", out)
|
item.add_report_section(when, "stdout", out)
|
||||||
item.add_report_section(when, "stderr", err)
|
item.add_report_section(when, "stderr", err)
|
||||||
|
|
||||||
|
|
||||||
error_capsysfderror = "cannot use capsys and capfd at the same time"
|
error_capsysfderror = "cannot use capsys and capfd at the same time"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,9 +65,11 @@ def main(args=None, plugins=None):
|
||||||
class cmdline: # compatibility namespace
|
class cmdline: # compatibility namespace
|
||||||
main = staticmethod(main)
|
main = staticmethod(main)
|
||||||
|
|
||||||
|
|
||||||
class UsageError(Exception):
|
class UsageError(Exception):
|
||||||
""" error in pytest usage or invocation"""
|
""" error in pytest usage or invocation"""
|
||||||
|
|
||||||
|
|
||||||
_preinit = []
|
_preinit = []
|
||||||
|
|
||||||
default_plugins = (
|
default_plugins = (
|
||||||
|
@ -594,7 +596,7 @@ class Argument:
|
||||||
if typ == 'choice':
|
if typ == 'choice':
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
'type argument to addoption() is a string %r.'
|
'type argument to addoption() is a string %r.'
|
||||||
' For parsearg this is optional and when supplied '
|
' For parsearg this is optional and when supplied'
|
||||||
' should be a type.'
|
' should be a type.'
|
||||||
' (options: %s)' % (typ, names),
|
' (options: %s)' % (typ, names),
|
||||||
DeprecationWarning,
|
DeprecationWarning,
|
||||||
|
@ -818,9 +820,11 @@ class Notset:
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<NOTSET>"
|
return "<NOTSET>"
|
||||||
|
|
||||||
|
|
||||||
notset = Notset()
|
notset = Notset()
|
||||||
FILE_OR_DIR = 'file_or_dir'
|
FILE_OR_DIR = 'file_or_dir'
|
||||||
|
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
""" access to configuration values, pluginmanager and plugin hooks. """
|
""" access to configuration values, pluginmanager and plugin hooks. """
|
||||||
|
|
||||||
|
@ -843,9 +847,11 @@ class Config(object):
|
||||||
self._warn = self.pluginmanager._warn
|
self._warn = self.pluginmanager._warn
|
||||||
self.pluginmanager.register(self, "pytestconfig")
|
self.pluginmanager.register(self, "pytestconfig")
|
||||||
self._configured = False
|
self._configured = False
|
||||||
|
|
||||||
def do_setns(dic):
|
def do_setns(dic):
|
||||||
import pytest
|
import pytest
|
||||||
setns(pytest, dic)
|
setns(pytest, dic)
|
||||||
|
|
||||||
self.hook.pytest_namespace.call_historic(do_setns, {})
|
self.hook.pytest_namespace.call_historic(do_setns, {})
|
||||||
self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))
|
self.hook.pytest_addoption.call_historic(kwargs=dict(parser=self._parser))
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,12 @@ def pytest_configure(config):
|
||||||
config.pluginmanager.register(PdbInvoke(), 'pdbinvoke')
|
config.pluginmanager.register(PdbInvoke(), 'pdbinvoke')
|
||||||
|
|
||||||
old = (pdb.set_trace, pytestPDB._pluginmanager)
|
old = (pdb.set_trace, pytestPDB._pluginmanager)
|
||||||
|
|
||||||
def fin():
|
def fin():
|
||||||
pdb.set_trace, pytestPDB._pluginmanager = old
|
pdb.set_trace, pytestPDB._pluginmanager = old
|
||||||
pytestPDB._config = None
|
pytestPDB._config = None
|
||||||
pytestPDB._pdb_cls = pdb.Pdb
|
pytestPDB._pdb_cls = pdb.Pdb
|
||||||
|
|
||||||
pdb.set_trace = pytest.set_trace
|
pdb.set_trace = pytest.set_trace
|
||||||
pytestPDB._pluginmanager = config.pluginmanager
|
pytestPDB._pluginmanager = config.pluginmanager
|
||||||
pytestPDB._config = config
|
pytestPDB._config = config
|
||||||
|
|
|
@ -32,11 +32,13 @@ scope2props["function"] = scope2props["instance"] + ("function", "keywords")
|
||||||
def scopeproperty(name=None, doc=None):
|
def scopeproperty(name=None, doc=None):
|
||||||
def decoratescope(func):
|
def decoratescope(func):
|
||||||
scopename = name or func.__name__
|
scopename = name or func.__name__
|
||||||
|
|
||||||
def provide(self):
|
def provide(self):
|
||||||
if func.__name__ in scope2props[self.scope]:
|
if func.__name__ in scope2props[self.scope]:
|
||||||
return func(self)
|
return func(self)
|
||||||
raise AttributeError("%s not available in %s-scoped context" % (
|
raise AttributeError("%s not available in %s-scoped context" % (
|
||||||
scopename, self.scope))
|
scopename, self.scope))
|
||||||
|
|
||||||
return property(provide, None, None, func.__doc__)
|
return property(provide, None, None, func.__doc__)
|
||||||
return decoratescope
|
return decoratescope
|
||||||
|
|
||||||
|
|
|
@ -41,12 +41,14 @@ def pytest_cmdline_parse():
|
||||||
config.trace.root.setwriter(debugfile.write)
|
config.trace.root.setwriter(debugfile.write)
|
||||||
undo_tracing = config.pluginmanager.enable_tracing()
|
undo_tracing = config.pluginmanager.enable_tracing()
|
||||||
sys.stderr.write("writing pytestdebug information to %s\n" % path)
|
sys.stderr.write("writing pytestdebug information to %s\n" % path)
|
||||||
|
|
||||||
def unset_tracing():
|
def unset_tracing():
|
||||||
debugfile.close()
|
debugfile.close()
|
||||||
sys.stderr.write("wrote pytestdebug information to %s\n" %
|
sys.stderr.write("wrote pytestdebug information to %s\n" %
|
||||||
debugfile.name)
|
debugfile.name)
|
||||||
config.trace.root.setwriter(None)
|
config.trace.root.setwriter(None)
|
||||||
undo_tracing()
|
undo_tracing()
|
||||||
|
|
||||||
config.add_cleanup(unset_tracing)
|
config.add_cleanup(unset_tracing)
|
||||||
|
|
||||||
def pytest_cmdline_main(config):
|
def pytest_cmdline_main(config):
|
||||||
|
|
|
@ -27,6 +27,7 @@ else:
|
||||||
class Junit(py.xml.Namespace):
|
class Junit(py.xml.Namespace):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
# We need to get the subset of the invalid unicode ranges according to
|
# We need to get the subset of the invalid unicode ranges according to
|
||||||
# XML 1.0 which are valid in this python build. Hence we calculate
|
# XML 1.0 which are valid in this python build. Hence we calculate
|
||||||
# this dynamically instead of hardcoding it. The spec range of valid
|
# this dynamically instead of hardcoding it. The spec range of valid
|
||||||
|
|
|
@ -60,6 +60,8 @@ def pytest_cmdline_main(config):
|
||||||
tw.line()
|
tw.line()
|
||||||
config._ensure_unconfigure()
|
config._ensure_unconfigure()
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
pytest_cmdline_main.tryfirst = True
|
pytest_cmdline_main.tryfirst = True
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ def pytest_addoption(parser):
|
||||||
choices=['failed', 'all'],
|
choices=['failed', 'all'],
|
||||||
help="send failed|all info to bpaste.net pastebin service.")
|
help="send failed|all info to bpaste.net pastebin service.")
|
||||||
|
|
||||||
|
|
||||||
@pytest.hookimpl(trylast=True)
|
@pytest.hookimpl(trylast=True)
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
import py
|
import py
|
||||||
|
@ -23,13 +24,16 @@ def pytest_configure(config):
|
||||||
# pastebin file will be utf-8 encoded binary file
|
# pastebin file will be utf-8 encoded binary file
|
||||||
config._pastebinfile = tempfile.TemporaryFile('w+b')
|
config._pastebinfile = tempfile.TemporaryFile('w+b')
|
||||||
oldwrite = tr._tw.write
|
oldwrite = tr._tw.write
|
||||||
|
|
||||||
def tee_write(s, **kwargs):
|
def tee_write(s, **kwargs):
|
||||||
oldwrite(s, **kwargs)
|
oldwrite(s, **kwargs)
|
||||||
if py.builtin._istext(s):
|
if py.builtin._istext(s):
|
||||||
s = s.encode('utf-8')
|
s = s.encode('utf-8')
|
||||||
config._pastebinfile.write(s)
|
config._pastebinfile.write(s)
|
||||||
|
|
||||||
tr._tw.write = tee_write
|
tr._tw.write = tee_write
|
||||||
|
|
||||||
|
|
||||||
def pytest_unconfigure(config):
|
def pytest_unconfigure(config):
|
||||||
if hasattr(config, '_pastebinfile'):
|
if hasattr(config, '_pastebinfile'):
|
||||||
# get terminal contents and delete file
|
# get terminal contents and delete file
|
||||||
|
@ -45,6 +49,7 @@ def pytest_unconfigure(config):
|
||||||
pastebinurl = create_new_paste(sessionlog)
|
pastebinurl = create_new_paste(sessionlog)
|
||||||
tr.write_line("pastebin session-log: %s\n" % pastebinurl)
|
tr.write_line("pastebin session-log: %s\n" % pastebinurl)
|
||||||
|
|
||||||
|
|
||||||
def create_new_paste(contents):
|
def create_new_paste(contents):
|
||||||
"""
|
"""
|
||||||
Creates a new paste using bpaste.net service.
|
Creates a new paste using bpaste.net service.
|
||||||
|
@ -72,6 +77,7 @@ def create_new_paste(contents):
|
||||||
else:
|
else:
|
||||||
return 'bad response: ' + response
|
return 'bad response: ' + response
|
||||||
|
|
||||||
|
|
||||||
def pytest_terminal_summary(terminalreporter):
|
def pytest_terminal_summary(terminalreporter):
|
||||||
import _pytest.config
|
import _pytest.config
|
||||||
if terminalreporter.config.option.pastebin != "failed":
|
if terminalreporter.config.option.pastebin != "failed":
|
||||||
|
|
|
@ -482,10 +482,12 @@ class Testdir:
|
||||||
for name, value in items:
|
for name, value in items:
|
||||||
p = self.tmpdir.join(name).new(ext=ext)
|
p = self.tmpdir.join(name).new(ext=ext)
|
||||||
source = Source(value)
|
source = Source(value)
|
||||||
|
|
||||||
def my_totext(s, encoding="utf-8"):
|
def my_totext(s, encoding="utf-8"):
|
||||||
if py.builtin._isbytes(s):
|
if py.builtin._isbytes(s):
|
||||||
s = py.builtin._totext(s, encoding=encoding)
|
s = py.builtin._totext(s, encoding=encoding)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
source_unicode = "\n".join([my_totext(line) for line in source.lines])
|
source_unicode = "\n".join([my_totext(line) for line in source.lines])
|
||||||
source = py.builtin._totext(source_unicode)
|
source = py.builtin._totext(source_unicode)
|
||||||
content = source.strip().encode("utf-8") # + "\n"
|
content = source.strip().encode("utf-8") # + "\n"
|
||||||
|
@ -695,12 +697,15 @@ class Testdir:
|
||||||
# warning which will trigger to say they can no longer be
|
# warning which will trigger to say they can no longer be
|
||||||
# re-written, which is fine as they are already re-written.
|
# re-written, which is fine as they are already re-written.
|
||||||
orig_warn = AssertionRewritingHook._warn_already_imported
|
orig_warn = AssertionRewritingHook._warn_already_imported
|
||||||
|
|
||||||
def revert():
|
def revert():
|
||||||
AssertionRewritingHook._warn_already_imported = orig_warn
|
AssertionRewritingHook._warn_already_imported = orig_warn
|
||||||
|
|
||||||
self.request.addfinalizer(revert)
|
self.request.addfinalizer(revert)
|
||||||
AssertionRewritingHook._warn_already_imported = lambda *a: None
|
AssertionRewritingHook._warn_already_imported = lambda *a: None
|
||||||
|
|
||||||
rec = []
|
rec = []
|
||||||
|
|
||||||
class Collect:
|
class Collect:
|
||||||
def pytest_configure(x, config):
|
def pytest_configure(x, config):
|
||||||
rec.append(self.make_hook_recorder(config.pluginmanager))
|
rec.append(self.make_hook_recorder(config.pluginmanager))
|
||||||
|
@ -735,10 +740,13 @@ class Testdir:
|
||||||
try:
|
try:
|
||||||
reprec = self.inline_run(*args, **kwargs)
|
reprec = self.inline_run(*args, **kwargs)
|
||||||
except SystemExit as e:
|
except SystemExit as e:
|
||||||
|
|
||||||
class reprec:
|
class reprec:
|
||||||
ret = e.args[0]
|
ret = e.args[0]
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
class reprec:
|
class reprec:
|
||||||
ret = 3
|
ret = 3
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -214,9 +214,12 @@ class PyobjMixin(PyobjContext):
|
||||||
if obj is None:
|
if obj is None:
|
||||||
self._obj = obj = self._getobj()
|
self._obj = obj = self._getobj()
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def fset(self, value):
|
def fset(self, value):
|
||||||
self._obj = value
|
self._obj = value
|
||||||
|
|
||||||
return property(fget, fset, None, "underlying python object")
|
return property(fget, fset, None, "underlying python object")
|
||||||
|
|
||||||
obj = obj()
|
obj = obj()
|
||||||
|
|
||||||
def _getobj(self):
|
def _getobj(self):
|
||||||
|
|
|
@ -517,8 +517,10 @@ def exit(msg):
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
raise Exit(msg)
|
raise Exit(msg)
|
||||||
|
|
||||||
|
|
||||||
exit.Exception = Exit
|
exit.Exception = Exit
|
||||||
|
|
||||||
|
|
||||||
def skip(msg=""):
|
def skip(msg=""):
|
||||||
""" skip an executing test with the given message. Note: it's usually
|
""" skip an executing test with the given message. Note: it's usually
|
||||||
better to use the pytest.mark.skipif marker to declare a test to be
|
better to use the pytest.mark.skipif marker to declare a test to be
|
||||||
|
@ -527,8 +529,11 @@ def skip(msg=""):
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
raise Skipped(msg=msg)
|
raise Skipped(msg=msg)
|
||||||
|
|
||||||
|
|
||||||
skip.Exception = Skipped
|
skip.Exception = Skipped
|
||||||
|
|
||||||
|
|
||||||
def fail(msg="", pytrace=True):
|
def fail(msg="", pytrace=True):
|
||||||
""" explicitly fail an currently-executing test with the given Message.
|
""" explicitly fail an currently-executing test with the given Message.
|
||||||
|
|
||||||
|
@ -537,6 +542,8 @@ def fail(msg="", pytrace=True):
|
||||||
"""
|
"""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
raise Failed(msg=msg, pytrace=pytrace)
|
raise Failed(msg=msg, pytrace=pytrace)
|
||||||
|
|
||||||
|
|
||||||
fail.Exception = Failed
|
fail.Exception = Failed
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,10 @@ def pytest_configure(config):
|
||||||
if config.option.runxfail:
|
if config.option.runxfail:
|
||||||
old = pytest.xfail
|
old = pytest.xfail
|
||||||
config._cleanup.append(lambda: setattr(pytest, "xfail", old))
|
config._cleanup.append(lambda: setattr(pytest, "xfail", old))
|
||||||
|
|
||||||
def nop(*args, **kwargs):
|
def nop(*args, **kwargs):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
nop.Exception = XFailed
|
nop.Exception = XFailed
|
||||||
setattr(pytest, "xfail", nop)
|
setattr(pytest, "xfail", nop)
|
||||||
|
|
||||||
|
@ -65,6 +67,8 @@ def xfail(reason=""):
|
||||||
""" xfail an executing test or setup functions with the given reason."""
|
""" xfail an executing test or setup functions with the given reason."""
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
raise XFailed(reason)
|
raise XFailed(reason)
|
||||||
|
|
||||||
|
|
||||||
xfail.Exception = XFailed
|
xfail.Exception = XFailed
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ def get_user():
|
||||||
except (ImportError, KeyError):
|
except (ImportError, KeyError):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
# backward compatibility
|
# backward compatibility
|
||||||
TempdirHandler = TempdirFactory
|
TempdirHandler = TempdirFactory
|
||||||
|
|
||||||
|
|
|
@ -186,6 +186,7 @@ def pytest_runtest_protocol(item):
|
||||||
ut = sys.modules['twisted.python.failure']
|
ut = sys.modules['twisted.python.failure']
|
||||||
Failure__init__ = ut.Failure.__init__
|
Failure__init__ = ut.Failure.__init__
|
||||||
check_testcase_implements_trial_reporter()
|
check_testcase_implements_trial_reporter()
|
||||||
|
|
||||||
def excstore(self, exc_value=None, exc_type=None, exc_tb=None,
|
def excstore(self, exc_value=None, exc_type=None, exc_tb=None,
|
||||||
captureVars=None):
|
captureVars=None):
|
||||||
if exc_value is None:
|
if exc_value is None:
|
||||||
|
@ -199,6 +200,7 @@ def pytest_runtest_protocol(item):
|
||||||
captureVars=captureVars)
|
captureVars=captureVars)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
Failure__init__(self, exc_value, exc_type, exc_tb)
|
Failure__init__(self, exc_value, exc_type, exc_tb)
|
||||||
|
|
||||||
ut.Failure.__init__ = excstore
|
ut.Failure.__init__ = excstore
|
||||||
yield
|
yield
|
||||||
ut.Failure.__init__ = Failure__init__
|
ut.Failure.__init__ = Failure__init__
|
||||||
|
|
|
@ -24,6 +24,7 @@ def test_code_with_class():
|
||||||
pass
|
pass
|
||||||
pytest.raises(TypeError, "_pytest._code.Code(A)")
|
pytest.raises(TypeError, "_pytest._code.Code(A)")
|
||||||
|
|
||||||
|
|
||||||
if True:
|
if True:
|
||||||
def x():
|
def x():
|
||||||
pass
|
pass
|
||||||
|
@ -68,8 +69,10 @@ def test_code_from_func():
|
||||||
|
|
||||||
def test_unicode_handling():
|
def test_unicode_handling():
|
||||||
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
|
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
raise Exception(value)
|
raise Exception(value)
|
||||||
|
|
||||||
excinfo = pytest.raises(Exception, f)
|
excinfo = pytest.raises(Exception, f)
|
||||||
str(excinfo)
|
str(excinfo)
|
||||||
if sys.version_info[0] < 3:
|
if sys.version_info[0] < 3:
|
||||||
|
@ -79,8 +82,10 @@ def test_unicode_handling():
|
||||||
@pytest.mark.skipif(sys.version_info[0] >= 3, reason='python 2 only issue')
|
@pytest.mark.skipif(sys.version_info[0] >= 3, reason='python 2 only issue')
|
||||||
def test_unicode_handling_syntax_error():
|
def test_unicode_handling_syntax_error():
|
||||||
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
|
value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
raise SyntaxError('invalid syntax', (None, 1, 3, value))
|
raise SyntaxError('invalid syntax', (None, 1, 3, value))
|
||||||
|
|
||||||
excinfo = pytest.raises(Exception, f)
|
excinfo = pytest.raises(Exception, f)
|
||||||
str(excinfo)
|
str(excinfo)
|
||||||
if sys.version_info[0] < 3:
|
if sys.version_info[0] < 3:
|
||||||
|
|
|
@ -56,13 +56,15 @@ def test_excinfo_simple():
|
||||||
def test_excinfo_getstatement():
|
def test_excinfo_getstatement():
|
||||||
def g():
|
def g():
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
g()
|
g()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
f()
|
f()
|
||||||
except ValueError:
|
except ValueError:
|
||||||
excinfo = _pytest._code.ExceptionInfo()
|
excinfo = _pytest._code.ExceptionInfo()
|
||||||
linenumbers = [_pytest._code.getrawcode(f).co_firstlineno - 1 + 3,
|
linenumbers = [_pytest._code.getrawcode(f).co_firstlineno - 1 + 4,
|
||||||
_pytest._code.getrawcode(f).co_firstlineno - 1 + 1,
|
_pytest._code.getrawcode(f).co_firstlineno - 1 + 1,
|
||||||
_pytest._code.getrawcode(g).co_firstlineno - 1 + 1, ]
|
_pytest._code.getrawcode(g).co_firstlineno - 1 + 1, ]
|
||||||
l = list(excinfo.traceback)
|
l = list(excinfo.traceback)
|
||||||
|
@ -168,11 +170,13 @@ class TestTraceback_f_g_h:
|
||||||
#
|
#
|
||||||
raise ValueError
|
raise ValueError
|
||||||
#
|
#
|
||||||
|
|
||||||
def g():
|
def g():
|
||||||
#
|
#
|
||||||
__tracebackhide__ = tracebackhide
|
__tracebackhide__ = tracebackhide
|
||||||
f()
|
f()
|
||||||
#
|
#
|
||||||
|
|
||||||
def h():
|
def h():
|
||||||
#
|
#
|
||||||
g()
|
g()
|
||||||
|
@ -214,15 +218,18 @@ class TestTraceback_f_g_h:
|
||||||
def test_traceback_no_recursion_index(self):
|
def test_traceback_no_recursion_index(self):
|
||||||
def do_stuff():
|
def do_stuff():
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
|
|
||||||
def reraise_me():
|
def reraise_me():
|
||||||
import sys
|
import sys
|
||||||
exc, val, tb = sys.exc_info()
|
exc, val, tb = sys.exc_info()
|
||||||
py.builtin._reraise(exc, val, tb)
|
py.builtin._reraise(exc, val, tb)
|
||||||
|
|
||||||
def f(n):
|
def f(n):
|
||||||
try:
|
try:
|
||||||
do_stuff()
|
do_stuff()
|
||||||
except:
|
except:
|
||||||
reraise_me()
|
reraise_me()
|
||||||
|
|
||||||
excinfo = pytest.raises(RuntimeError, f, 8)
|
excinfo = pytest.raises(RuntimeError, f, 8)
|
||||||
traceback = excinfo.traceback
|
traceback = excinfo.traceback
|
||||||
recindex = traceback.recursionindex()
|
recindex = traceback.recursionindex()
|
||||||
|
@ -245,17 +252,18 @@ class TestTraceback_f_g_h:
|
||||||
excinfo = pytest.raises(ValueError, fail)
|
excinfo = pytest.raises(ValueError, fail)
|
||||||
assert excinfo.traceback.recursionindex() is None
|
assert excinfo.traceback.recursionindex() is None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_traceback_getcrashentry(self):
|
def test_traceback_getcrashentry(self):
|
||||||
def i():
|
def i():
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def h():
|
def h():
|
||||||
i()
|
i()
|
||||||
|
|
||||||
def g():
|
def g():
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
h()
|
h()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
g()
|
g()
|
||||||
|
|
||||||
|
@ -271,6 +279,7 @@ class TestTraceback_f_g_h:
|
||||||
def g():
|
def g():
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
__tracebackhide__ = True
|
__tracebackhide__ = True
|
||||||
g()
|
g()
|
||||||
|
@ -465,11 +474,13 @@ raise ValueError()
|
||||||
class FakeCode(object):
|
class FakeCode(object):
|
||||||
class raw:
|
class raw:
|
||||||
co_filename = '?'
|
co_filename = '?'
|
||||||
|
|
||||||
path = '?'
|
path = '?'
|
||||||
firstlineno = 5
|
firstlineno = 5
|
||||||
|
|
||||||
def fullsource(self):
|
def fullsource(self):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
fullsource = property(fullsource)
|
fullsource = property(fullsource)
|
||||||
|
|
||||||
class FakeFrame(object):
|
class FakeFrame(object):
|
||||||
|
@ -491,17 +502,21 @@ raise ValueError()
|
||||||
class FakeExcinfo(_pytest._code.ExceptionInfo):
|
class FakeExcinfo(_pytest._code.ExceptionInfo):
|
||||||
typename = "Foo"
|
typename = "Foo"
|
||||||
value = Exception()
|
value = Exception()
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def exconly(self, tryshort):
|
def exconly(self, tryshort):
|
||||||
return "EXC"
|
return "EXC"
|
||||||
|
|
||||||
def errisinstance(self, cls):
|
def errisinstance(self, cls):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
excinfo = FakeExcinfo()
|
excinfo = FakeExcinfo()
|
||||||
|
|
||||||
class FakeRawTB(object):
|
class FakeRawTB(object):
|
||||||
tb_next = None
|
tb_next = None
|
||||||
|
|
||||||
tb = FakeRawTB()
|
tb = FakeRawTB()
|
||||||
excinfo.traceback = Traceback(tb)
|
excinfo.traceback = Traceback(tb)
|
||||||
|
|
||||||
|
@ -719,8 +734,10 @@ raise ValueError()
|
||||||
excinfo = pytest.raises(ValueError, mod.entry)
|
excinfo = pytest.raises(ValueError, mod.entry)
|
||||||
|
|
||||||
p = FormattedExcinfo()
|
p = FormattedExcinfo()
|
||||||
|
|
||||||
def raiseos():
|
def raiseos():
|
||||||
raise OSError(2)
|
raise OSError(2)
|
||||||
|
|
||||||
monkeypatch.setattr(py.std.os, 'getcwd', raiseos)
|
monkeypatch.setattr(py.std.os, 'getcwd', raiseos)
|
||||||
assert p._makepath(__file__) == __file__
|
assert p._makepath(__file__) == __file__
|
||||||
p.repr_traceback(excinfo)
|
p.repr_traceback(excinfo)
|
||||||
|
@ -789,9 +806,11 @@ raise ValueError()
|
||||||
|
|
||||||
def test_reprexcinfo_unicode(self):
|
def test_reprexcinfo_unicode(self):
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
|
|
||||||
class MyRepr(TerminalRepr):
|
class MyRepr(TerminalRepr):
|
||||||
def toterminal(self, tw):
|
def toterminal(self, tw):
|
||||||
tw.line(py.builtin._totext("я", "utf-8"))
|
tw.line(py.builtin._totext("я", "utf-8"))
|
||||||
|
|
||||||
x = py.builtin._totext(MyRepr())
|
x = py.builtin._totext(MyRepr())
|
||||||
assert x == py.builtin._totext("я", "utf-8")
|
assert x == py.builtin._totext("я", "utf-8")
|
||||||
|
|
||||||
|
|
|
@ -383,10 +383,13 @@ class TestFunction:
|
||||||
config = testdir.parseconfigure()
|
config = testdir.parseconfigure()
|
||||||
session = testdir.Session(config)
|
session = testdir.Session(config)
|
||||||
session._fixturemanager = FixtureManager(session)
|
session._fixturemanager = FixtureManager(session)
|
||||||
|
|
||||||
def func1():
|
def func1():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def func2():
|
def func2():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
f1 = pytest.Function(name="name", parent=session, config=config,
|
f1 = pytest.Function(name="name", parent=session, config=config,
|
||||||
args=(1,), callobj=func1)
|
args=(1,), callobj=func1)
|
||||||
assert f1 == f1
|
assert f1 == f1
|
||||||
|
@ -547,12 +550,15 @@ class TestFunction:
|
||||||
def test_pyfunc_call(self, testdir):
|
def test_pyfunc_call(self, testdir):
|
||||||
item = testdir.getitem("def test_func(): raise ValueError")
|
item = testdir.getitem("def test_func(): raise ValueError")
|
||||||
config = item.config
|
config = item.config
|
||||||
|
|
||||||
class MyPlugin1:
|
class MyPlugin1:
|
||||||
def pytest_pyfunc_call(self, pyfuncitem):
|
def pytest_pyfunc_call(self, pyfuncitem):
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
class MyPlugin2:
|
class MyPlugin2:
|
||||||
def pytest_pyfunc_call(self, pyfuncitem):
|
def pytest_pyfunc_call(self, pyfuncitem):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
config.pluginmanager.register(MyPlugin1())
|
config.pluginmanager.register(MyPlugin1())
|
||||||
config.pluginmanager.register(MyPlugin2())
|
config.pluginmanager.register(MyPlugin2())
|
||||||
config.hook.pytest_runtest_setup(item=item)
|
config.hook.pytest_runtest_setup(item=item)
|
||||||
|
|
|
@ -10,15 +10,20 @@ from _pytest import fixtures
|
||||||
def test_getfuncargnames():
|
def test_getfuncargnames():
|
||||||
def f(): pass
|
def f(): pass
|
||||||
assert not fixtures.getfuncargnames(f)
|
assert not fixtures.getfuncargnames(f)
|
||||||
|
|
||||||
def g(arg): pass
|
def g(arg): pass
|
||||||
assert fixtures.getfuncargnames(g) == ('arg',)
|
assert fixtures.getfuncargnames(g) == ('arg',)
|
||||||
|
|
||||||
def h(arg1, arg2="hello"): pass
|
def h(arg1, arg2="hello"): pass
|
||||||
assert fixtures.getfuncargnames(h) == ('arg1',)
|
assert fixtures.getfuncargnames(h) == ('arg1',)
|
||||||
|
|
||||||
def h(arg1, arg2, arg3="hello"): pass
|
def h(arg1, arg2, arg3="hello"): pass
|
||||||
assert fixtures.getfuncargnames(h) == ('arg1', 'arg2')
|
assert fixtures.getfuncargnames(h) == ('arg1', 'arg2')
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
def f(self, arg1, arg2="hello"):
|
def f(self, arg1, arg2="hello"):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert fixtures.getfuncargnames(A().f) == ('arg1',)
|
assert fixtures.getfuncargnames(A().f) == ('arg1',)
|
||||||
if sys.version_info < (3,0):
|
if sys.version_info < (3,0):
|
||||||
assert fixtures.getfuncargnames(A.f) == ('arg1',)
|
assert fixtures.getfuncargnames(A.f) == ('arg1',)
|
||||||
|
@ -869,8 +874,10 @@ class TestRequestCachedSetup:
|
||||||
item1 = testdir.getitem("def test_func(): pass")
|
item1 = testdir.getitem("def test_func(): pass")
|
||||||
req1 = fixtures.FixtureRequest(item1)
|
req1 = fixtures.FixtureRequest(item1)
|
||||||
l = ["hello", "world"]
|
l = ["hello", "world"]
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
return l.pop()
|
return l.pop()
|
||||||
|
|
||||||
ret1 = req1.cached_setup(setup, extrakey=1)
|
ret1 = req1.cached_setup(setup, extrakey=1)
|
||||||
ret2 = req1.cached_setup(setup, extrakey=2)
|
ret2 = req1.cached_setup(setup, extrakey=2)
|
||||||
assert ret2 == "hello"
|
assert ret2 == "hello"
|
||||||
|
@ -884,10 +891,13 @@ class TestRequestCachedSetup:
|
||||||
item1 = testdir.getitem("def test_func(): pass")
|
item1 = testdir.getitem("def test_func(): pass")
|
||||||
req1 = fixtures.FixtureRequest(item1)
|
req1 = fixtures.FixtureRequest(item1)
|
||||||
l = []
|
l = []
|
||||||
|
|
||||||
def setup():
|
def setup():
|
||||||
l.append("setup")
|
l.append("setup")
|
||||||
|
|
||||||
def teardown(val):
|
def teardown(val):
|
||||||
l.append("teardown")
|
l.append("teardown")
|
||||||
|
|
||||||
req1.cached_setup(setup, teardown, scope="function")
|
req1.cached_setup(setup, teardown, scope="function")
|
||||||
assert l == ['setup']
|
assert l == ['setup']
|
||||||
# artificial call of finalizer
|
# artificial call of finalizer
|
||||||
|
|
|
@ -63,10 +63,12 @@ class TestOEJSKITSpecials:
|
||||||
def test_wrapped_getfslineno():
|
def test_wrapped_getfslineno():
|
||||||
def func():
|
def func():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def wrap(f):
|
def wrap(f):
|
||||||
func.__wrapped__ = f
|
func.__wrapped__ = f
|
||||||
func.patchings = ["qwe"]
|
func.patchings = ["qwe"]
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@wrap
|
@wrap
|
||||||
def wrapped_func(x, y, z):
|
def wrapped_func(x, y, z):
|
||||||
pass
|
pass
|
||||||
|
@ -77,28 +79,36 @@ def test_wrapped_getfslineno():
|
||||||
class TestMockDecoration:
|
class TestMockDecoration:
|
||||||
def test_wrapped_getfuncargnames(self):
|
def test_wrapped_getfuncargnames(self):
|
||||||
from _pytest.compat import getfuncargnames
|
from _pytest.compat import getfuncargnames
|
||||||
|
|
||||||
def wrap(f):
|
def wrap(f):
|
||||||
|
|
||||||
def func():
|
def func():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
func.__wrapped__ = f
|
func.__wrapped__ = f
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@wrap
|
@wrap
|
||||||
def f(x):
|
def f(x):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
l = getfuncargnames(f)
|
l = getfuncargnames(f)
|
||||||
assert l == ("x",)
|
assert l == ("x",)
|
||||||
|
|
||||||
def test_wrapped_getfuncargnames_patching(self):
|
def test_wrapped_getfuncargnames_patching(self):
|
||||||
from _pytest.compat import getfuncargnames
|
from _pytest.compat import getfuncargnames
|
||||||
|
|
||||||
def wrap(f):
|
def wrap(f):
|
||||||
def func():
|
def func():
|
||||||
pass
|
pass
|
||||||
func.__wrapped__ = f
|
func.__wrapped__ = f
|
||||||
func.patchings = ["qwe"]
|
func.patchings = ["qwe"]
|
||||||
return func
|
return func
|
||||||
|
|
||||||
@wrap
|
@wrap
|
||||||
def f(x, y, z):
|
def f(x, y, z):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
l = getfuncargnames(f)
|
l = getfuncargnames(f)
|
||||||
assert l == ("y", "z")
|
assert l == ("y", "z")
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,10 @@ class TestMetafunc:
|
||||||
# initiliazation
|
# initiliazation
|
||||||
class FixtureInfo:
|
class FixtureInfo:
|
||||||
name2fixturedefs = None
|
name2fixturedefs = None
|
||||||
|
|
||||||
def __init__(self, names):
|
def __init__(self, names):
|
||||||
self.names_closure = names
|
self.names_closure = names
|
||||||
|
|
||||||
names = fixtures.getfuncargnames(func)
|
names = fixtures.getfuncargnames(func)
|
||||||
fixtureinfo = FixtureInfo(names)
|
fixtureinfo = FixtureInfo(names)
|
||||||
return python.Metafunc(func, fixtureinfo, None)
|
return python.Metafunc(func, fixtureinfo, None)
|
||||||
|
@ -65,7 +67,9 @@ class TestMetafunc:
|
||||||
def test_addcall_param(self):
|
def test_addcall_param(self):
|
||||||
def func(arg1): pass
|
def func(arg1): pass
|
||||||
metafunc = self.Metafunc(func)
|
metafunc = self.Metafunc(func)
|
||||||
|
|
||||||
class obj: pass
|
class obj: pass
|
||||||
|
|
||||||
metafunc.addcall(param=obj)
|
metafunc.addcall(param=obj)
|
||||||
metafunc.addcall(param=obj)
|
metafunc.addcall(param=obj)
|
||||||
metafunc.addcall(param=1)
|
metafunc.addcall(param=1)
|
||||||
|
@ -76,8 +80,11 @@ class TestMetafunc:
|
||||||
|
|
||||||
def test_addcall_funcargs(self):
|
def test_addcall_funcargs(self):
|
||||||
def func(x): pass
|
def func(x): pass
|
||||||
|
|
||||||
metafunc = self.Metafunc(func)
|
metafunc = self.Metafunc(func)
|
||||||
|
|
||||||
class obj: pass
|
class obj: pass
|
||||||
|
|
||||||
metafunc.addcall(funcargs={"x": 2})
|
metafunc.addcall(funcargs={"x": 2})
|
||||||
metafunc.addcall(funcargs={"x": 3})
|
metafunc.addcall(funcargs={"x": 3})
|
||||||
pytest.raises(pytest.fail.Exception, "metafunc.addcall({'xyz': 0})")
|
pytest.raises(pytest.fail.Exception, "metafunc.addcall({'xyz': 0})")
|
||||||
|
@ -142,8 +149,10 @@ class TestMetafunc:
|
||||||
def test_parametrize_with_userobjects(self):
|
def test_parametrize_with_userobjects(self):
|
||||||
def func(x, y): pass
|
def func(x, y): pass
|
||||||
metafunc = self.Metafunc(func)
|
metafunc = self.Metafunc(func)
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
metafunc.parametrize("x", [A(), A()])
|
metafunc.parametrize("x", [A(), A()])
|
||||||
metafunc.parametrize("y", list("ab"))
|
metafunc.parametrize("y", list("ab"))
|
||||||
assert metafunc._calls[0].id == "x0-a"
|
assert metafunc._calls[0].id == "x0-a"
|
||||||
|
@ -254,6 +263,7 @@ class TestMetafunc:
|
||||||
@pytest.mark.issue351
|
@pytest.mark.issue351
|
||||||
def test_idmaker_idfn(self):
|
def test_idmaker_idfn(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
|
|
||||||
def ids(val):
|
def ids(val):
|
||||||
if isinstance(val, Exception):
|
if isinstance(val, Exception):
|
||||||
return repr(val)
|
return repr(val)
|
||||||
|
@ -270,6 +280,7 @@ class TestMetafunc:
|
||||||
@pytest.mark.issue351
|
@pytest.mark.issue351
|
||||||
def test_idmaker_idfn_unique_names(self):
|
def test_idmaker_idfn_unique_names(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
|
|
||||||
def ids(val):
|
def ids(val):
|
||||||
return 'a'
|
return 'a'
|
||||||
|
|
||||||
|
@ -285,6 +296,7 @@ class TestMetafunc:
|
||||||
@pytest.mark.issue351
|
@pytest.mark.issue351
|
||||||
def test_idmaker_idfn_exception(self):
|
def test_idmaker_idfn_exception(self):
|
||||||
from _pytest.python import idmaker
|
from _pytest.python import idmaker
|
||||||
|
|
||||||
def ids(val):
|
def ids(val):
|
||||||
raise Exception("bad code")
|
raise Exception("bad code")
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,15 @@ PY3 = sys.version_info >= (3, 0)
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mock_config():
|
def mock_config():
|
||||||
|
|
||||||
class Config(object):
|
class Config(object):
|
||||||
verbose = False
|
verbose = False
|
||||||
|
|
||||||
def getoption(self, name):
|
def getoption(self, name):
|
||||||
if name == 'verbose':
|
if name == 'verbose':
|
||||||
return self.verbose
|
return self.verbose
|
||||||
raise KeyError('Not mocked out: %s' % name)
|
raise KeyError('Not mocked out: %s' % name)
|
||||||
|
|
||||||
return Config()
|
return Config()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -104,20 +104,29 @@ class TestAssertionRewrite:
|
||||||
def f():
|
def f():
|
||||||
assert False
|
assert False
|
||||||
assert getmsg(f) == "assert False"
|
assert getmsg(f) == "assert False"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = False
|
f = False
|
||||||
assert f
|
assert f
|
||||||
|
|
||||||
assert getmsg(f) == "assert False"
|
assert getmsg(f) == "assert False"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert a_global # noqa
|
assert a_global # noqa
|
||||||
|
|
||||||
assert getmsg(f, {"a_global" : False}) == "assert False"
|
assert getmsg(f, {"a_global" : False}) == "assert False"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert sys == 42
|
assert sys == 42
|
||||||
|
|
||||||
assert getmsg(f, {"sys" : sys}) == "assert sys == 42"
|
assert getmsg(f, {"sys" : sys}) == "assert sys == 42"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert cls == 42 # noqa
|
assert cls == 42 # noqa
|
||||||
|
|
||||||
class X(object):
|
class X(object):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert getmsg(f, {"cls" : X}) == "assert cls == 42"
|
assert getmsg(f, {"cls" : X}) == "assert cls == 42"
|
||||||
|
|
||||||
def test_assert_already_has_message(self):
|
def test_assert_already_has_message(self):
|
||||||
|
@ -190,78 +199,110 @@ class TestAssertionRewrite:
|
||||||
def f():
|
def f():
|
||||||
f = g = False
|
f = g = False
|
||||||
assert f and g
|
assert f and g
|
||||||
|
|
||||||
assert getmsg(f) == "assert (False)"
|
assert getmsg(f) == "assert (False)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = True
|
f = True
|
||||||
g = False
|
g = False
|
||||||
assert f and g
|
assert f and g
|
||||||
|
|
||||||
assert getmsg(f) == "assert (True and False)"
|
assert getmsg(f) == "assert (True and False)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = False
|
f = False
|
||||||
g = True
|
g = True
|
||||||
assert f and g
|
assert f and g
|
||||||
|
|
||||||
assert getmsg(f) == "assert (False)"
|
assert getmsg(f) == "assert (False)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = g = False
|
f = g = False
|
||||||
assert f or g
|
assert f or g
|
||||||
|
|
||||||
assert getmsg(f) == "assert (False or False)"
|
assert getmsg(f) == "assert (False or False)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = g = False
|
f = g = False
|
||||||
assert not f and not g
|
assert not f and not g
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def x():
|
def x():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert x() and x()
|
assert x() and x()
|
||||||
|
|
||||||
assert getmsg(f, {"x" : x}) == """assert (False)
|
assert getmsg(f, {"x" : x}) == """assert (False)
|
||||||
+ where False = x()"""
|
+ where False = x()"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert False or x()
|
assert False or x()
|
||||||
|
|
||||||
assert getmsg(f, {"x" : x}) == """assert (False or False)
|
assert getmsg(f, {"x" : x}) == """assert (False or False)
|
||||||
+ where False = x()"""
|
+ where False = x()"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert 1 in {} and 2 in {}
|
assert 1 in {} and 2 in {}
|
||||||
|
|
||||||
assert getmsg(f) == "assert (1 in {})"
|
assert getmsg(f) == "assert (1 in {})"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x = 1
|
x = 1
|
||||||
y = 2
|
y = 2
|
||||||
assert x in {1 : None} and y in {}
|
assert x in {1 : None} and y in {}
|
||||||
|
|
||||||
assert getmsg(f) == "assert (1 in {1: None} and 2 in {})"
|
assert getmsg(f) == "assert (1 in {1: None} and 2 in {})"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = True
|
f = True
|
||||||
g = False
|
g = False
|
||||||
assert f or g
|
assert f or g
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
f = g = h = lambda: True
|
f = g = h = lambda: True
|
||||||
assert f() and g() and h()
|
assert f() and g() and h()
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def test_short_circut_evaluation(self):
|
def test_short_circut_evaluation(self):
|
||||||
def f():
|
def f():
|
||||||
assert True or explode # noqa
|
assert True or explode # noqa
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x = 1
|
x = 1
|
||||||
assert x == 1 or x == 2
|
assert x == 1 or x == 2
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def test_unary_op(self):
|
def test_unary_op(self):
|
||||||
def f():
|
def f():
|
||||||
x = True
|
x = True
|
||||||
assert not x
|
assert not x
|
||||||
|
|
||||||
assert getmsg(f) == "assert not True"
|
assert getmsg(f) == "assert not True"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x = 0
|
x = 0
|
||||||
assert ~x + 1
|
assert ~x + 1
|
||||||
|
|
||||||
assert getmsg(f) == "assert (~0 + 1)"
|
assert getmsg(f) == "assert (~0 + 1)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x = 3
|
x = 3
|
||||||
assert -x + x
|
assert -x + x
|
||||||
|
|
||||||
assert getmsg(f) == "assert (-3 + 3)"
|
assert getmsg(f) == "assert (-3 + 3)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x = 0
|
x = 0
|
||||||
assert +x + x
|
assert +x + x
|
||||||
|
|
||||||
assert getmsg(f) == "assert (+0 + 0)"
|
assert getmsg(f) == "assert (+0 + 0)"
|
||||||
|
|
||||||
def test_binary_op(self):
|
def test_binary_op(self):
|
||||||
|
@ -269,7 +310,9 @@ class TestAssertionRewrite:
|
||||||
x = 1
|
x = 1
|
||||||
y = -1
|
y = -1
|
||||||
assert x + y
|
assert x + y
|
||||||
|
|
||||||
assert getmsg(f) == "assert (1 + -1)"
|
assert getmsg(f) == "assert (1 + -1)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert not 5 % 4
|
assert not 5 % 4
|
||||||
assert getmsg(f) == "assert not (5 % 4)"
|
assert getmsg(f) == "assert not (5 % 4)"
|
||||||
|
@ -277,7 +320,9 @@ class TestAssertionRewrite:
|
||||||
def test_boolop_percent(self):
|
def test_boolop_percent(self):
|
||||||
def f():
|
def f():
|
||||||
assert 3 % 2 and False
|
assert 3 % 2 and False
|
||||||
|
|
||||||
assert getmsg(f) == "assert ((3 % 2) and False)"
|
assert getmsg(f) == "assert ((3 % 2) and False)"
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert False or 4 % 2
|
assert False or 4 % 2
|
||||||
assert getmsg(f) == "assert (False or (4 % 2))"
|
assert getmsg(f) == "assert (False or (4 % 2))"
|
||||||
|
@ -298,113 +343,159 @@ class TestAssertionRewrite:
|
||||||
def test_call(self):
|
def test_call(self):
|
||||||
def g(a=42, *args, **kwargs):
|
def g(a=42, *args, **kwargs):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
ns = {"g" : g}
|
ns = {"g" : g}
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert g()
|
assert g()
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g()"""
|
+ where False = g()"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert g(1)
|
assert g(1)
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g(1)"""
|
+ where False = g(1)"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert g(1, 2)
|
assert g(1, 2)
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g(1, 2)"""
|
+ where False = g(1, 2)"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert g(1, g=42)
|
assert g(1, g=42)
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g(1, g=42)"""
|
+ where False = g(1, g=42)"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert g(1, 3, g=23)
|
assert g(1, 3, g=23)
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g(1, 3, g=23)"""
|
+ where False = g(1, 3, g=23)"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
seq = [1, 2, 3]
|
seq = [1, 2, 3]
|
||||||
assert g(*seq)
|
assert g(*seq)
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g(*[1, 2, 3])"""
|
+ where False = g(*[1, 2, 3])"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x = "a"
|
x = "a"
|
||||||
assert g(**{x : 2})
|
assert g(**{x : 2})
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = g(**{'a': 2})"""
|
+ where False = g(**{'a': 2})"""
|
||||||
|
|
||||||
def test_attribute(self):
|
def test_attribute(self):
|
||||||
class X(object):
|
class X(object):
|
||||||
g = 3
|
g = 3
|
||||||
|
|
||||||
ns = {"x" : X}
|
ns = {"x" : X}
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert not x.g # noqa
|
assert not x.g # noqa
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert not 3
|
assert getmsg(f, ns) == """assert not 3
|
||||||
+ where 3 = x.g"""
|
+ where 3 = x.g"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
x.a = False # noqa
|
x.a = False # noqa
|
||||||
assert x.a # noqa
|
assert x.a # noqa
|
||||||
|
|
||||||
assert getmsg(f, ns) == """assert False
|
assert getmsg(f, ns) == """assert False
|
||||||
+ where False = x.a"""
|
+ where False = x.a"""
|
||||||
|
|
||||||
def test_comparisons(self):
|
def test_comparisons(self):
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
a, b = range(2)
|
a, b = range(2)
|
||||||
assert b < a
|
assert b < a
|
||||||
|
|
||||||
assert getmsg(f) == """assert 1 < 0"""
|
assert getmsg(f) == """assert 1 < 0"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
a, b, c = range(3)
|
a, b, c = range(3)
|
||||||
assert a > b > c
|
assert a > b > c
|
||||||
|
|
||||||
assert getmsg(f) == """assert 0 > 1"""
|
assert getmsg(f) == """assert 0 > 1"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
a, b, c = range(3)
|
a, b, c = range(3)
|
||||||
assert a < b > c
|
assert a < b > c
|
||||||
|
|
||||||
assert getmsg(f) == """assert 1 > 2"""
|
assert getmsg(f) == """assert 1 > 2"""
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
a, b, c = range(3)
|
a, b, c = range(3)
|
||||||
assert a < b <= c
|
assert a < b <= c
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
a, b, c = range(3)
|
a, b, c = range(3)
|
||||||
assert a < b
|
assert a < b
|
||||||
assert b < c
|
assert b < c
|
||||||
|
|
||||||
getmsg(f, must_pass=True)
|
getmsg(f, must_pass=True)
|
||||||
|
|
||||||
def test_len(self):
|
def test_len(self):
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
l = list(range(10))
|
l = list(range(10))
|
||||||
assert len(l) == 11
|
assert len(l) == 11
|
||||||
|
|
||||||
assert getmsg(f).startswith("""assert 10 == 11
|
assert getmsg(f).startswith("""assert 10 == 11
|
||||||
+ where 10 = len([""")
|
+ where 10 = len([""")
|
||||||
|
|
||||||
def test_custom_reprcompare(self, monkeypatch):
|
def test_custom_reprcompare(self, monkeypatch):
|
||||||
def my_reprcompare(op, left, right):
|
def my_reprcompare(op, left, right):
|
||||||
return "42"
|
return "42"
|
||||||
|
|
||||||
monkeypatch.setattr(util, "_reprcompare", my_reprcompare)
|
monkeypatch.setattr(util, "_reprcompare", my_reprcompare)
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert 42 < 3
|
assert 42 < 3
|
||||||
|
|
||||||
assert getmsg(f) == "assert 42"
|
assert getmsg(f) == "assert 42"
|
||||||
|
|
||||||
def my_reprcompare(op, left, right):
|
def my_reprcompare(op, left, right):
|
||||||
return "%s %s %s" % (left, op, right)
|
return "%s %s %s" % (left, op, right)
|
||||||
|
|
||||||
monkeypatch.setattr(util, "_reprcompare", my_reprcompare)
|
monkeypatch.setattr(util, "_reprcompare", my_reprcompare)
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
assert 1 < 3 < 5 <= 4 < 7
|
assert 1 < 3 < 5 <= 4 < 7
|
||||||
|
|
||||||
assert getmsg(f) == "assert 5 <= 4"
|
assert getmsg(f) == "assert 5 <= 4"
|
||||||
|
|
||||||
def test_assert_raising_nonzero_in_comparison(self):
|
def test_assert_raising_nonzero_in_comparison(self):
|
||||||
def f():
|
def f():
|
||||||
class A(object):
|
class A(object):
|
||||||
|
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
raise ValueError(42)
|
raise ValueError(42)
|
||||||
|
|
||||||
def __lt__(self, other):
|
def __lt__(self, other):
|
||||||
return A()
|
return A()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<MY42 object>"
|
return "<MY42 object>"
|
||||||
|
|
||||||
def myany(x):
|
def myany(x):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
assert myany(A() < 0)
|
assert myany(A() < 0)
|
||||||
|
|
||||||
assert "<MY42 object> < 0" in getmsg(f)
|
assert "<MY42 object> < 0" in getmsg(f)
|
||||||
|
|
||||||
def test_formatchar(self):
|
def test_formatchar(self):
|
||||||
def f():
|
def f():
|
||||||
assert "%test" == "test"
|
assert "%test" == "test"
|
||||||
|
|
||||||
assert getmsg(f).startswith("assert '%test' == 'test'")
|
assert getmsg(f).startswith("assert '%test' == 'test'")
|
||||||
|
|
||||||
def test_custom_repr(self):
|
def test_custom_repr(self):
|
||||||
|
@ -414,8 +505,10 @@ class TestAssertionRewrite:
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "\n{ \n~ \n}"
|
return "\n{ \n~ \n}"
|
||||||
|
|
||||||
f = Foo()
|
f = Foo()
|
||||||
assert 0 == f.a
|
assert 0 == f.a
|
||||||
|
|
||||||
assert r"where 1 = \n{ \n~ \n}.a" in util._format_lines([getmsg(f)])[0]
|
assert r"where 1 = \n{ \n~ \n}.a" in util._format_lines([getmsg(f)])[0]
|
||||||
|
|
||||||
|
|
||||||
|
@ -527,8 +620,10 @@ def test_rewritten():
|
||||||
def test_rewrite_warning(self, pytestconfig, monkeypatch):
|
def test_rewrite_warning(self, pytestconfig, monkeypatch):
|
||||||
hook = AssertionRewritingHook(pytestconfig)
|
hook = AssertionRewritingHook(pytestconfig)
|
||||||
warnings = []
|
warnings = []
|
||||||
|
|
||||||
def mywarn(code, msg):
|
def mywarn(code, msg):
|
||||||
warnings.append((code, msg))
|
warnings.append((code, msg))
|
||||||
|
|
||||||
monkeypatch.setattr(hook.config, 'warn', mywarn)
|
monkeypatch.setattr(hook.config, 'warn', mywarn)
|
||||||
hook.mark_rewrite('_pytest')
|
hook.mark_rewrite('_pytest')
|
||||||
assert '_pytest' in warnings[0][1]
|
assert '_pytest' in warnings[0][1]
|
||||||
|
@ -642,10 +737,12 @@ class TestAssertionRewriteHookDetails(object):
|
||||||
source_path = tmpdir.ensure("source.py")
|
source_path = tmpdir.ensure("source.py")
|
||||||
pycpath = tmpdir.join("pyc").strpath
|
pycpath = tmpdir.join("pyc").strpath
|
||||||
assert _write_pyc(state, [1], source_path.stat(), pycpath)
|
assert _write_pyc(state, [1], source_path.stat(), pycpath)
|
||||||
|
|
||||||
def open(*args):
|
def open(*args):
|
||||||
e = IOError()
|
e = IOError()
|
||||||
e.errno = 10
|
e.errno = 10
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
monkeypatch.setattr(b, "open", open)
|
monkeypatch.setattr(b, "open", open)
|
||||||
assert not _write_pyc(state, [1], source_path.stat(), pycpath)
|
assert not _write_pyc(state, [1], source_path.stat(), pycpath)
|
||||||
|
|
||||||
|
|
|
@ -150,11 +150,13 @@ class TestCollectFS:
|
||||||
class TestCollectPluginHookRelay:
|
class TestCollectPluginHookRelay:
|
||||||
def test_pytest_collect_file(self, testdir):
|
def test_pytest_collect_file(self, testdir):
|
||||||
wascalled = []
|
wascalled = []
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
def pytest_collect_file(self, path, parent):
|
def pytest_collect_file(self, path, parent):
|
||||||
if not path.basename.startswith("."):
|
if not path.basename.startswith("."):
|
||||||
# Ignore hidden files, e.g. .testmondata.
|
# Ignore hidden files, e.g. .testmondata.
|
||||||
wascalled.append(path)
|
wascalled.append(path)
|
||||||
|
|
||||||
testdir.makefile(".abc", "xyz")
|
testdir.makefile(".abc", "xyz")
|
||||||
pytest.main([testdir.tmpdir], plugins=[Plugin()])
|
pytest.main([testdir.tmpdir], plugins=[Plugin()])
|
||||||
assert len(wascalled) == 1
|
assert len(wascalled) == 1
|
||||||
|
@ -162,15 +164,18 @@ class TestCollectPluginHookRelay:
|
||||||
|
|
||||||
def test_pytest_collect_directory(self, testdir):
|
def test_pytest_collect_directory(self, testdir):
|
||||||
wascalled = []
|
wascalled = []
|
||||||
|
|
||||||
class Plugin:
|
class Plugin:
|
||||||
def pytest_collect_directory(self, path, parent):
|
def pytest_collect_directory(self, path, parent):
|
||||||
wascalled.append(path.basename)
|
wascalled.append(path.basename)
|
||||||
|
|
||||||
testdir.mkdir("hello")
|
testdir.mkdir("hello")
|
||||||
testdir.mkdir("world")
|
testdir.mkdir("world")
|
||||||
pytest.main(testdir.tmpdir, plugins=[Plugin()])
|
pytest.main(testdir.tmpdir, plugins=[Plugin()])
|
||||||
assert "hello" in wascalled
|
assert "hello" in wascalled
|
||||||
assert "world" in wascalled
|
assert "world" in wascalled
|
||||||
|
|
||||||
|
|
||||||
class TestPrunetraceback:
|
class TestPrunetraceback:
|
||||||
|
|
||||||
def test_custom_repr_failure(self, testdir):
|
def test_custom_repr_failure(self, testdir):
|
||||||
|
|
|
@ -373,23 +373,31 @@ def test_options_on_small_file_do_not_blow_up(testdir):
|
||||||
['--traceconfig'], ['-v'], ['-v', '-v']):
|
['--traceconfig'], ['-v'], ['-v', '-v']):
|
||||||
runfiletest(opts + [path])
|
runfiletest(opts + [path])
|
||||||
|
|
||||||
|
|
||||||
def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
|
def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
|
||||||
pkg_resources = pytest.importorskip("pkg_resources")
|
pkg_resources = pytest.importorskip("pkg_resources")
|
||||||
|
|
||||||
def my_iter(name):
|
def my_iter(name):
|
||||||
assert name == "pytest11"
|
assert name == "pytest11"
|
||||||
|
|
||||||
class Dist:
|
class Dist:
|
||||||
project_name = 'spam'
|
project_name = 'spam'
|
||||||
version = '1.0'
|
version = '1.0'
|
||||||
|
|
||||||
def _get_metadata(self, name):
|
def _get_metadata(self, name):
|
||||||
return ['foo.txt,sha256=abc,123']
|
return ['foo.txt,sha256=abc,123']
|
||||||
|
|
||||||
class EntryPoint:
|
class EntryPoint:
|
||||||
name = "mytestplugin"
|
name = "mytestplugin"
|
||||||
dist = Dist()
|
dist = Dist()
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
class PseudoPlugin:
|
class PseudoPlugin:
|
||||||
x = 42
|
x = 42
|
||||||
return PseudoPlugin()
|
return PseudoPlugin()
|
||||||
|
|
||||||
return iter([EntryPoint()])
|
return iter([EntryPoint()])
|
||||||
|
|
||||||
monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
|
monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
|
||||||
testdir.makeconftest("""
|
testdir.makeconftest("""
|
||||||
pytest_plugins = "mytestplugin",
|
pytest_plugins = "mytestplugin",
|
||||||
|
@ -402,18 +410,24 @@ def test_preparse_ordering_with_setuptools(testdir, monkeypatch):
|
||||||
|
|
||||||
def test_setuptools_importerror_issue1479(testdir, monkeypatch):
|
def test_setuptools_importerror_issue1479(testdir, monkeypatch):
|
||||||
pkg_resources = pytest.importorskip("pkg_resources")
|
pkg_resources = pytest.importorskip("pkg_resources")
|
||||||
|
|
||||||
def my_iter(name):
|
def my_iter(name):
|
||||||
assert name == "pytest11"
|
assert name == "pytest11"
|
||||||
|
|
||||||
class Dist:
|
class Dist:
|
||||||
project_name = 'spam'
|
project_name = 'spam'
|
||||||
version = '1.0'
|
version = '1.0'
|
||||||
|
|
||||||
def _get_metadata(self, name):
|
def _get_metadata(self, name):
|
||||||
return ['foo.txt,sha256=abc,123']
|
return ['foo.txt,sha256=abc,123']
|
||||||
|
|
||||||
class EntryPoint:
|
class EntryPoint:
|
||||||
name = "mytestplugin"
|
name = "mytestplugin"
|
||||||
dist = Dist()
|
dist = Dist()
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
raise ImportError("Don't hide me!")
|
raise ImportError("Don't hide me!")
|
||||||
|
|
||||||
return iter([EntryPoint()])
|
return iter([EntryPoint()])
|
||||||
|
|
||||||
monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
|
monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
|
||||||
|
@ -423,19 +437,26 @@ def test_setuptools_importerror_issue1479(testdir, monkeypatch):
|
||||||
|
|
||||||
def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch):
|
def test_plugin_preparse_prevents_setuptools_loading(testdir, monkeypatch):
|
||||||
pkg_resources = pytest.importorskip("pkg_resources")
|
pkg_resources = pytest.importorskip("pkg_resources")
|
||||||
|
|
||||||
def my_iter(name):
|
def my_iter(name):
|
||||||
assert name == "pytest11"
|
assert name == "pytest11"
|
||||||
|
|
||||||
class Dist:
|
class Dist:
|
||||||
project_name = 'spam'
|
project_name = 'spam'
|
||||||
version = '1.0'
|
version = '1.0'
|
||||||
|
|
||||||
def _get_metadata(self, name):
|
def _get_metadata(self, name):
|
||||||
return ['foo.txt,sha256=abc,123']
|
return ['foo.txt,sha256=abc,123']
|
||||||
|
|
||||||
class EntryPoint:
|
class EntryPoint:
|
||||||
name = "mytestplugin"
|
name = "mytestplugin"
|
||||||
dist = Dist()
|
dist = Dist()
|
||||||
|
|
||||||
def load(self):
|
def load(self):
|
||||||
assert 0, "should not arrive here"
|
assert 0, "should not arrive here"
|
||||||
|
|
||||||
return iter([EntryPoint()])
|
return iter([EntryPoint()])
|
||||||
|
|
||||||
monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
|
monkeypatch.setattr(pkg_resources, 'iter_entry_points', my_iter)
|
||||||
config = testdir.parseconfig("-p", "no:mytestplugin")
|
config = testdir.parseconfig("-p", "no:mytestplugin")
|
||||||
plugin = config.pluginmanager.getplugin("mytestplugin")
|
plugin = config.pluginmanager.getplugin("mytestplugin")
|
||||||
|
@ -503,9 +524,11 @@ def test_notify_exception(testdir, capfd):
|
||||||
config.notify_exception(excinfo)
|
config.notify_exception(excinfo)
|
||||||
out, err = capfd.readouterr()
|
out, err = capfd.readouterr()
|
||||||
assert "ValueError" in err
|
assert "ValueError" in err
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
def pytest_internalerror(self, excrepr):
|
def pytest_internalerror(self, excrepr):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
config.pluginmanager.register(A())
|
config.pluginmanager.register(A())
|
||||||
config.notify_exception(excinfo)
|
config.notify_exception(excinfo)
|
||||||
out, err = capfd.readouterr()
|
out, err = capfd.readouterr()
|
||||||
|
@ -515,9 +538,11 @@ def test_notify_exception(testdir, capfd):
|
||||||
def test_load_initial_conftest_last_ordering(testdir):
|
def test_load_initial_conftest_last_ordering(testdir):
|
||||||
from _pytest.config import get_config
|
from _pytest.config import get_config
|
||||||
pm = get_config().pluginmanager
|
pm = get_config().pluginmanager
|
||||||
|
|
||||||
class My:
|
class My:
|
||||||
def pytest_load_initial_conftests(self):
|
def pytest_load_initial_conftests(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
m = My()
|
m = My()
|
||||||
pm.register(m)
|
pm.register(m)
|
||||||
hc = pm.hook.pytest_load_initial_conftests
|
hc = pm.hook.pytest_load_initial_conftests
|
||||||
|
|
|
@ -200,8 +200,10 @@ def test_conftest_import_order(testdir, monkeypatch):
|
||||||
sub = testdir.mkdir("sub")
|
sub = testdir.mkdir("sub")
|
||||||
ct2 = sub.join("conftest.py")
|
ct2 = sub.join("conftest.py")
|
||||||
ct2.write("")
|
ct2.write("")
|
||||||
|
|
||||||
def impct(p):
|
def impct(p):
|
||||||
return p
|
return p
|
||||||
|
|
||||||
conftest = PytestPluginManager()
|
conftest = PytestPluginManager()
|
||||||
conftest._confcutdir = testdir.tmpdir
|
conftest._confcutdir = testdir.tmpdir
|
||||||
monkeypatch.setattr(conftest, '_importconftest', impct)
|
monkeypatch.setattr(conftest, '_importconftest', impct)
|
||||||
|
|
|
@ -23,15 +23,19 @@ class TestMark:
|
||||||
|
|
||||||
def test_pytest_mark_bare(self):
|
def test_pytest_mark_bare(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mark.hello(f)
|
mark.hello(f)
|
||||||
assert f.hello
|
assert f.hello
|
||||||
|
|
||||||
def test_pytest_mark_keywords(self):
|
def test_pytest_mark_keywords(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mark.world(x=3, y=4)(f)
|
mark.world(x=3, y=4)(f)
|
||||||
assert f.world
|
assert f.world
|
||||||
assert f.world.kwargs['x'] == 3
|
assert f.world.kwargs['x'] == 3
|
||||||
|
@ -39,8 +43,10 @@ class TestMark:
|
||||||
|
|
||||||
def test_apply_multiple_and_merge(self):
|
def test_apply_multiple_and_merge(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mark.world
|
mark.world
|
||||||
mark.world(x=3)(f)
|
mark.world(x=3)(f)
|
||||||
assert f.world.kwargs['x'] == 3
|
assert f.world.kwargs['x'] == 3
|
||||||
|
@ -53,33 +59,43 @@ class TestMark:
|
||||||
|
|
||||||
def test_pytest_mark_positional(self):
|
def test_pytest_mark_positional(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
mark.world("hello")(f)
|
mark.world("hello")(f)
|
||||||
assert f.world.args[0] == "hello"
|
assert f.world.args[0] == "hello"
|
||||||
mark.world("world")(f)
|
mark.world("world")(f)
|
||||||
|
|
||||||
def test_pytest_mark_positional_func_and_keyword(self):
|
def test_pytest_mark_positional_func_and_keyword(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
m = mark.world(f, omega="hello")
|
m = mark.world(f, omega="hello")
|
||||||
|
|
||||||
def g():
|
def g():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
assert m(g) == g
|
assert m(g) == g
|
||||||
assert g.world.args[0] is f
|
assert g.world.args[0] is f
|
||||||
assert g.world.kwargs["omega"] == "hello"
|
assert g.world.kwargs["omega"] == "hello"
|
||||||
|
|
||||||
def test_pytest_mark_reuse(self):
|
def test_pytest_mark_reuse(self):
|
||||||
mark = Mark()
|
mark = Mark()
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
w = mark.some
|
w = mark.some
|
||||||
w("hello", reason="123")(f)
|
w("hello", reason="123")(f)
|
||||||
assert f.some.args[0] == "hello"
|
assert f.some.args[0] == "hello"
|
||||||
assert f.some.kwargs['reason'] == "123"
|
assert f.some.kwargs['reason'] == "123"
|
||||||
|
|
||||||
def g():
|
def g():
|
||||||
pass
|
pass
|
||||||
|
|
||||||
w("world", reason2="456")(g)
|
w("world", reason2="456")(g)
|
||||||
assert g.some.args[0] == "world"
|
assert g.some.args[0] == "world"
|
||||||
assert 'reason' not in g.some.kwargs
|
assert 'reason' not in g.some.kwargs
|
||||||
|
@ -610,11 +626,12 @@ class TestFunctional:
|
||||||
def test_1(parameter):
|
def test_1(parameter):
|
||||||
assert True
|
assert True
|
||||||
""")
|
""")
|
||||||
|
|
||||||
reprec = testdir.inline_run()
|
reprec = testdir.inline_run()
|
||||||
reprec.assertoutcome(skipped=1)
|
reprec.assertoutcome(skipped=1)
|
||||||
|
|
||||||
|
|
||||||
class TestKeywordSelection:
|
class TestKeywordSelection:
|
||||||
|
|
||||||
def test_select_simple(self, testdir):
|
def test_select_simple(self, testdir):
|
||||||
file_test = testdir.makepyfile("""
|
file_test = testdir.makepyfile("""
|
||||||
def test_one():
|
def test_one():
|
||||||
|
@ -623,6 +640,7 @@ class TestKeywordSelection:
|
||||||
def test_method_one(self):
|
def test_method_one(self):
|
||||||
assert 42 == 43
|
assert 42 == 43
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def check(keyword, name):
|
def check(keyword, name):
|
||||||
reprec = testdir.inline_run("-s", "-k", keyword, file_test)
|
reprec = testdir.inline_run("-s", "-k", keyword, file_test)
|
||||||
passed, skipped, failed = reprec.listoutcomes()
|
passed, skipped, failed = reprec.listoutcomes()
|
||||||
|
@ -709,6 +727,7 @@ class TestKeywordSelection:
|
||||||
p = testdir.makepyfile("""
|
p = testdir.makepyfile("""
|
||||||
def test_one(): assert 1
|
def test_one(): assert 1
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def assert_test_is_not_selected(keyword):
|
def assert_test_is_not_selected(keyword):
|
||||||
reprec = testdir.inline_run("-k", keyword, p)
|
reprec = testdir.inline_run("-k", keyword, p)
|
||||||
passed, skipped, failed = reprec.countoutcomes()
|
passed, skipped, failed = reprec.countoutcomes()
|
||||||
|
|
|
@ -25,18 +25,22 @@ def test_nose_setup(testdir):
|
||||||
def test_setup_func_with_setup_decorator():
|
def test_setup_func_with_setup_decorator():
|
||||||
from _pytest.nose import call_optional
|
from _pytest.nose import call_optional
|
||||||
l = []
|
l = []
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def f(self):
|
def f(self):
|
||||||
l.append(1)
|
l.append(1)
|
||||||
|
|
||||||
call_optional(A(), "f")
|
call_optional(A(), "f")
|
||||||
assert not l
|
assert not l
|
||||||
|
|
||||||
|
|
||||||
def test_setup_func_not_callable():
|
def test_setup_func_not_callable():
|
||||||
from _pytest.nose import call_optional
|
from _pytest.nose import call_optional
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
f = 1
|
f = 1
|
||||||
|
|
||||||
call_optional(A(), "f")
|
call_optional(A(), "f")
|
||||||
|
|
||||||
def test_nose_setup_func(testdir):
|
def test_nose_setup_func(testdir):
|
||||||
|
|
|
@ -138,7 +138,10 @@ class TestParser:
|
||||||
def test_parse_setoption(self, parser):
|
def test_parse_setoption(self, parser):
|
||||||
parser.addoption("--hello", dest="hello", action="store")
|
parser.addoption("--hello", dest="hello", action="store")
|
||||||
parser.addoption("--world", dest="world", default=42)
|
parser.addoption("--world", dest="world", default=42)
|
||||||
class A: pass
|
|
||||||
|
class A:
|
||||||
|
pass
|
||||||
|
|
||||||
option = A()
|
option = A()
|
||||||
args = parser.parse_setoption(['--hello', 'world'], option)
|
args = parser.parse_setoption(['--hello', 'world'], option)
|
||||||
assert option.hello == "world"
|
assert option.hello == "world"
|
||||||
|
|
|
@ -84,8 +84,10 @@ class TestPaste:
|
||||||
function that connects to bpaste service.
|
function that connects to bpaste service.
|
||||||
"""
|
"""
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
def mocked(url, data):
|
def mocked(url, data):
|
||||||
calls.append((url, data))
|
calls.append((url, data))
|
||||||
|
|
||||||
class DummyFile:
|
class DummyFile:
|
||||||
def read(self):
|
def read(self):
|
||||||
# part of html of a normal response
|
# part of html of a normal response
|
||||||
|
|
|
@ -39,8 +39,10 @@ class TestPDB:
|
||||||
def pdblist(self, request):
|
def pdblist(self, request):
|
||||||
monkeypatch = request.getfixturevalue("monkeypatch")
|
monkeypatch = request.getfixturevalue("monkeypatch")
|
||||||
pdblist = []
|
pdblist = []
|
||||||
|
|
||||||
def mypdb(*args):
|
def mypdb(*args):
|
||||||
pdblist.append(args)
|
pdblist.append(args)
|
||||||
|
|
||||||
plugin = request.config.pluginmanager.getplugin('debugging')
|
plugin = request.config.pluginmanager.getplugin('debugging')
|
||||||
monkeypatch.setattr(plugin, 'post_mortem', mypdb)
|
monkeypatch.setattr(plugin, 'post_mortem', mypdb)
|
||||||
return pdblist
|
return pdblist
|
||||||
|
|
|
@ -83,6 +83,7 @@ class TestPytestPluginInteractions:
|
||||||
def test_configure(self, testdir):
|
def test_configure(self, testdir):
|
||||||
config = testdir.parseconfig()
|
config = testdir.parseconfig()
|
||||||
l = []
|
l = []
|
||||||
|
|
||||||
class A:
|
class A:
|
||||||
def pytest_configure(self, config):
|
def pytest_configure(self, config):
|
||||||
l.append(self)
|
l.append(self)
|
||||||
|
@ -102,13 +103,16 @@ class TestPytestPluginInteractions:
|
||||||
def test_hook_tracing(self):
|
def test_hook_tracing(self):
|
||||||
pytestpm = get_config().pluginmanager # fully initialized with plugins
|
pytestpm = get_config().pluginmanager # fully initialized with plugins
|
||||||
saveindent = []
|
saveindent = []
|
||||||
|
|
||||||
class api1:
|
class api1:
|
||||||
def pytest_plugin_registered(self):
|
def pytest_plugin_registered(self):
|
||||||
saveindent.append(pytestpm.trace.root.indent)
|
saveindent.append(pytestpm.trace.root.indent)
|
||||||
|
|
||||||
class api2:
|
class api2:
|
||||||
def pytest_plugin_registered(self):
|
def pytest_plugin_registered(self):
|
||||||
saveindent.append(pytestpm.trace.root.indent)
|
saveindent.append(pytestpm.trace.root.indent)
|
||||||
raise ValueError()
|
raise ValueError()
|
||||||
|
|
||||||
l = []
|
l = []
|
||||||
pytestpm.trace.root.setwriter(l.append)
|
pytestpm.trace.root.setwriter(l.append)
|
||||||
undo = pytestpm.enable_tracing()
|
undo = pytestpm.enable_tracing()
|
||||||
|
|
|
@ -11,6 +11,7 @@ def test_make_hook_recorder(testdir):
|
||||||
assert not recorder.getfailures()
|
assert not recorder.getfailures()
|
||||||
|
|
||||||
pytest.xfail("internal reportrecorder tests need refactoring")
|
pytest.xfail("internal reportrecorder tests need refactoring")
|
||||||
|
|
||||||
class rep:
|
class rep:
|
||||||
excinfo = None
|
excinfo = None
|
||||||
passed = False
|
passed = False
|
||||||
|
@ -80,10 +81,13 @@ def make_holder():
|
||||||
"x"
|
"x"
|
||||||
|
|
||||||
apimod = type(os)('api')
|
apimod = type(os)('api')
|
||||||
|
|
||||||
def pytest_xyz(arg):
|
def pytest_xyz(arg):
|
||||||
"x"
|
"x"
|
||||||
|
|
||||||
def pytest_xyz_noarg():
|
def pytest_xyz_noarg():
|
||||||
"x"
|
"x"
|
||||||
|
|
||||||
apimod.pytest_xyz = pytest_xyz
|
apimod.pytest_xyz = pytest_xyz
|
||||||
apimod.pytest_xyz_noarg = pytest_xyz_noarg
|
apimod.pytest_xyz_noarg = pytest_xyz_noarg
|
||||||
return apiclass, apimod
|
return apiclass, apimod
|
||||||
|
|
|
@ -38,9 +38,13 @@ class TestSetupState:
|
||||||
|
|
||||||
def test_teardown_multiple_one_fails(self, testdir):
|
def test_teardown_multiple_one_fails(self, testdir):
|
||||||
r = []
|
r = []
|
||||||
|
|
||||||
def fin1(): r.append('fin1')
|
def fin1(): r.append('fin1')
|
||||||
|
|
||||||
def fin2(): raise Exception('oops')
|
def fin2(): raise Exception('oops')
|
||||||
|
|
||||||
def fin3(): r.append('fin3')
|
def fin3(): r.append('fin3')
|
||||||
|
|
||||||
item = testdir.getitem("def test_func(): pass")
|
item = testdir.getitem("def test_func(): pass")
|
||||||
ss = runner.SetupState()
|
ss = runner.SetupState()
|
||||||
ss.addfinalizer(fin1, item)
|
ss.addfinalizer(fin1, item)
|
||||||
|
@ -55,7 +59,9 @@ class TestSetupState:
|
||||||
# Ensure the first exception is the one which is re-raised.
|
# Ensure the first exception is the one which is re-raised.
|
||||||
# Ideally both would be reported however.
|
# Ideally both would be reported however.
|
||||||
def fin1(): raise Exception('oops1')
|
def fin1(): raise Exception('oops1')
|
||||||
|
|
||||||
def fin2(): raise Exception('oops2')
|
def fin2(): raise Exception('oops2')
|
||||||
|
|
||||||
item = testdir.getitem("def test_func(): pass")
|
item = testdir.getitem("def test_func(): pass")
|
||||||
ss = runner.SetupState()
|
ss = runner.SetupState()
|
||||||
ss.addfinalizer(fin1, item)
|
ss.addfinalizer(fin1, item)
|
||||||
|
@ -527,8 +533,10 @@ def test_exception_printing_skip():
|
||||||
|
|
||||||
def test_importorskip(monkeypatch):
|
def test_importorskip(monkeypatch):
|
||||||
importorskip = pytest.importorskip
|
importorskip = pytest.importorskip
|
||||||
|
|
||||||
def f():
|
def f():
|
||||||
importorskip("asdlkj")
|
importorskip("asdlkj")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sys = importorskip("sys") # noqa
|
sys = importorskip("sys") # noqa
|
||||||
assert sys == py.std.sys
|
assert sys == py.std.sys
|
||||||
|
@ -643,11 +651,13 @@ def test_makereport_getsource_dynamic_code(testdir, monkeypatch):
|
||||||
"""Test that exception in dynamically generated code doesn't break getting the source line."""
|
"""Test that exception in dynamically generated code doesn't break getting the source line."""
|
||||||
import inspect
|
import inspect
|
||||||
original_findsource = inspect.findsource
|
original_findsource = inspect.findsource
|
||||||
|
|
||||||
def findsource(obj, *args, **kwargs):
|
def findsource(obj, *args, **kwargs):
|
||||||
# Can be triggered by dynamically created functions
|
# Can be triggered by dynamically created functions
|
||||||
if obj.__name__ == 'foo':
|
if obj.__name__ == 'foo':
|
||||||
raise IndexError()
|
raise IndexError()
|
||||||
return original_findsource(obj, *args, **kwargs)
|
return original_findsource(obj, *args, **kwargs)
|
||||||
|
|
||||||
monkeypatch.setattr(inspect, 'findsource', findsource)
|
monkeypatch.setattr(inspect, 'findsource', findsource)
|
||||||
|
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
|
|
1
tox.ini
1
tox.ini
|
@ -175,3 +175,4 @@ norecursedirs = .tox ja .hg cx_freeze_source
|
||||||
|
|
||||||
[flake8]
|
[flake8]
|
||||||
ignore =E401,E225,E261,E128,E124,E301,E302,E121,E303,W391,E501,E231,E126,E701,E265,E241,E251,E226,E101,W191,E131,E203,E122,E123,E271,E712,E222,E127,E125,E221,W292,E111,E113,E293,E262,W293,E129,E702,E201,E272,E202,E704,E731,E402
|
ignore =E401,E225,E261,E128,E124,E301,E302,E121,E303,W391,E501,E231,E126,E701,E265,E241,E251,E226,E101,W191,E131,E203,E122,E123,E271,E712,E222,E127,E125,E221,W292,E111,E113,E293,E262,W293,E129,E702,E201,E272,E202,E704,E731,E402
|
||||||
|
exclude = _pytest/vendored_packages/pluggy.py
|
||||||
|
|
Loading…
Reference in New Issue