fix all singular internal module imports and add a test for them
This commit is contained in:
parent
809c36e1f6
commit
92f6ab1881
|
@ -291,3 +291,12 @@ else:
|
|||
|
||||
def getvalue(self):
|
||||
return self.buffer.getvalue().decode('UTF-8')
|
||||
|
||||
class FuncargnamesCompatAttr(object):
|
||||
""" helper class so that Metafunc, Function and FixtureRequest
|
||||
don't need to each define the "funcargnames" compatibility attribute.
|
||||
"""
|
||||
@property
|
||||
def funcargnames(self):
|
||||
""" alias attribute for ``fixturenames`` for pre-2.3 compatibility"""
|
||||
return self.fixturenames
|
||||
|
|
|
@ -3,7 +3,6 @@ from __future__ import absolute_import, division, print_function
|
|||
import pdb
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
|
@ -35,7 +34,7 @@ def pytest_configure(config):
|
|||
pytestPDB._config = None
|
||||
pytestPDB._pdb_cls = pdb.Pdb
|
||||
|
||||
pdb.set_trace = pytest.set_trace
|
||||
pdb.set_trace = pytestPDB.set_trace
|
||||
pytestPDB._pluginmanager = config.pluginmanager
|
||||
pytestPDB._config = config
|
||||
pytestPDB._pdb_cls = pdb_cls
|
||||
|
@ -75,7 +74,7 @@ class PdbInvoke(object):
|
|||
|
||||
def pytest_internalerror(self, excrepr, excinfo):
|
||||
for line in str(excrepr).split("\n"):
|
||||
sys.stderr.write("INTERNALERROR> %s\n" %line)
|
||||
sys.stderr.write("INTERNALERROR> %s\n" % line)
|
||||
sys.stderr.flush()
|
||||
tb = _postmortem_traceback(excinfo)
|
||||
post_mortem(tb)
|
||||
|
|
|
@ -4,7 +4,6 @@ import sys
|
|||
from py._code.code import FormattedExcinfo
|
||||
|
||||
import py
|
||||
import pytest
|
||||
import warnings
|
||||
|
||||
import inspect
|
||||
|
@ -17,12 +16,15 @@ from _pytest.compat import (
|
|||
getlocation, getfuncargnames,
|
||||
safe_getattr,
|
||||
)
|
||||
from _pytest.runner import fail
|
||||
from _pytest.compat import FuncargnamesCompatAttr
|
||||
from _pytest import python
|
||||
|
||||
def pytest_sessionstart(session):
|
||||
scopename2class.update({
|
||||
'class': pytest.Class,
|
||||
'module': pytest.Module,
|
||||
'function': pytest.Item,
|
||||
'class': python.Class,
|
||||
'module': python.Module,
|
||||
'function': _pytest.main.Item,
|
||||
})
|
||||
session._fixturemanager = FixtureManager(session)
|
||||
|
||||
|
@ -97,7 +99,7 @@ def add_funcarg_pseudo_fixture_def(collector, metafunc, fixturemanager):
|
|||
if scope != "function":
|
||||
node = get_scope_node(collector, scope)
|
||||
if node is None:
|
||||
assert scope == "class" and isinstance(collector, pytest.Module)
|
||||
assert scope == "class" and isinstance(collector, _pytest.python.Module)
|
||||
# use module-level collector for class-scope (for now)
|
||||
node = collector
|
||||
if node and argname in node._name2pseudofixturedef:
|
||||
|
@ -213,17 +215,6 @@ def slice_items(items, ignore, scoped_argkeys_cache):
|
|||
return items, None, None, None
|
||||
|
||||
|
||||
|
||||
class FuncargnamesCompatAttr(object):
|
||||
""" helper class so that Metafunc, Function and FixtureRequest
|
||||
don't need to each define the "funcargnames" compatibility attribute.
|
||||
"""
|
||||
@property
|
||||
def funcargnames(self):
|
||||
""" alias attribute for ``fixturenames`` for pre-2.3 compatibility"""
|
||||
return self.fixturenames
|
||||
|
||||
|
||||
def fillfixtures(function):
|
||||
""" fill missing funcargs for a test function. """
|
||||
try:
|
||||
|
@ -319,7 +310,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
|||
@scopeproperty("class")
|
||||
def cls(self):
|
||||
""" class (can be None) where the test function was collected. """
|
||||
clscol = self._pyfuncitem.getparent(pytest.Class)
|
||||
clscol = self._pyfuncitem.getparent(_pytest.python.Class)
|
||||
if clscol:
|
||||
return clscol.obj
|
||||
|
||||
|
@ -337,7 +328,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
|||
@scopeproperty()
|
||||
def module(self):
|
||||
""" python module object where the test function was collected. """
|
||||
return self._pyfuncitem.getparent(pytest.Module).obj
|
||||
return self._pyfuncitem.getparent(_pytest.python.Module).obj
|
||||
|
||||
@scopeproperty()
|
||||
def fspath(self):
|
||||
|
@ -500,7 +491,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
|||
source_lineno,
|
||||
)
|
||||
)
|
||||
pytest.fail(msg)
|
||||
fail(msg)
|
||||
else:
|
||||
# indices might not be set if old-style metafunc.addcall() was used
|
||||
param_index = funcitem.callspec.indices.get(argname, 0)
|
||||
|
@ -533,10 +524,10 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
|||
if scopemismatch(invoking_scope, requested_scope):
|
||||
# try to report something helpful
|
||||
lines = self._factorytraceback()
|
||||
pytest.fail("ScopeMismatch: You tried to access the %r scoped "
|
||||
"fixture %r with a %r scoped request object, "
|
||||
"involved factories\n%s" %(
|
||||
(requested_scope, argname, invoking_scope, "\n".join(lines))),
|
||||
fail("ScopeMismatch: You tried to access the %r scoped "
|
||||
"fixture %r with a %r scoped request object, "
|
||||
"involved factories\n%s" % (
|
||||
(requested_scope, argname, invoking_scope, "\n".join(lines))),
|
||||
pytrace=False)
|
||||
|
||||
def _factorytraceback(self):
|
||||
|
@ -546,7 +537,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
|
|||
fs, lineno = getfslineno(factory)
|
||||
p = self._pyfuncitem.session.fspath.bestrelpath(fs)
|
||||
args = _format_args(factory)
|
||||
lines.append("%s:%d: def %s%s" %(
|
||||
lines.append("%s:%d: def %s%s" % (
|
||||
p, lineno, factory.__name__, args))
|
||||
return lines
|
||||
|
||||
|
|
|
@ -8,14 +8,13 @@ import sys
|
|||
import _pytest
|
||||
import _pytest._code
|
||||
import py
|
||||
import pytest
|
||||
try:
|
||||
from collections import MutableMapping as MappingMixin
|
||||
except ImportError:
|
||||
from UserDict import DictMixin as MappingMixin
|
||||
|
||||
from _pytest.config import directory_arg
|
||||
from _pytest.runner import collect_one_node
|
||||
from _pytest.config import directory_arg, UsageError, hookimpl
|
||||
from _pytest.runner import collect_one_node, exit
|
||||
|
||||
tracebackcutdir = py.path.local(_pytest.__file__).dirpath()
|
||||
|
||||
|
@ -27,6 +26,7 @@ EXIT_INTERNALERROR = 3
|
|||
EXIT_USAGEERROR = 4
|
||||
EXIT_NOTESTSCOLLECTED = 5
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addini("norecursedirs", "directory patterns to avoid for recursion",
|
||||
type="args", default=['.*', 'build', 'dist', 'CVS', '_darcs', '{arch}', '*.egg', 'venv'])
|
||||
|
@ -78,7 +78,7 @@ def pytest_addoption(parser):
|
|||
|
||||
|
||||
def pytest_configure(config):
|
||||
pytest.config = config # compatibility
|
||||
pytest.config = config # compatibiltiy
|
||||
|
||||
|
||||
def wrap_session(config, doit):
|
||||
|
@ -93,12 +93,11 @@ def wrap_session(config, doit):
|
|||
config.hook.pytest_sessionstart(session=session)
|
||||
initstate = 2
|
||||
session.exitstatus = doit(config, session) or 0
|
||||
except pytest.UsageError:
|
||||
except UsageError:
|
||||
raise
|
||||
except KeyboardInterrupt:
|
||||
excinfo = _pytest._code.ExceptionInfo()
|
||||
if initstate < 2 and isinstance(
|
||||
excinfo.value, pytest.exit.Exception):
|
||||
if initstate < 2 and isinstance(excinfo.value, exit.Exception):
|
||||
sys.stderr.write('{0}: {1}\n'.format(
|
||||
excinfo.typename, excinfo.value.msg))
|
||||
config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
|
||||
|
@ -120,9 +119,11 @@ def wrap_session(config, doit):
|
|||
config._ensure_unconfigure()
|
||||
return session.exitstatus
|
||||
|
||||
|
||||
def pytest_cmdline_main(config):
|
||||
return wrap_session(config, _main)
|
||||
|
||||
|
||||
def _main(config, session):
|
||||
""" default command line protocol for initialization, session,
|
||||
running tests and reporting. """
|
||||
|
@ -134,9 +135,11 @@ def _main(config, session):
|
|||
elif session.testscollected == 0:
|
||||
return EXIT_NOTESTSCOLLECTED
|
||||
|
||||
|
||||
def pytest_collection(session):
|
||||
return session.perform_collect()
|
||||
|
||||
|
||||
def pytest_runtestloop(session):
|
||||
if (session.testsfailed and
|
||||
not session.config.option.continue_on_collection_errors):
|
||||
|
@ -153,6 +156,7 @@ def pytest_runtestloop(session):
|
|||
raise session.Interrupted(session.shouldstop)
|
||||
return True
|
||||
|
||||
|
||||
def pytest_ignore_collect(path, config):
|
||||
p = path.dirpath()
|
||||
ignore_paths = config._getconftest_pathlist("collect_ignore", path=p)
|
||||
|
@ -200,7 +204,7 @@ class _CompatProperty(object):
|
|||
# "usage of {owner!r}.{name} is deprecated, please use pytest.{name} instead".format(
|
||||
# name=self.name, owner=type(owner).__name__),
|
||||
# PendingDeprecationWarning, stacklevel=2)
|
||||
return getattr(pytest, self.name)
|
||||
return getattr(__import__('pytest'), self.name)
|
||||
|
||||
|
||||
|
||||
|
@ -284,7 +288,7 @@ class Node(object):
|
|||
def _getcustomclass(self, name):
|
||||
maybe_compatprop = getattr(type(self), name)
|
||||
if isinstance(maybe_compatprop, _CompatProperty):
|
||||
return getattr(pytest, name)
|
||||
return getattr(__import__('pytest'), name)
|
||||
else:
|
||||
cls = getattr(self, name)
|
||||
# TODO: reenable in the features branch
|
||||
|
@ -367,9 +371,9 @@ class Node(object):
|
|||
|
||||
``marker`` can be a string or pytest.mark.* instance.
|
||||
"""
|
||||
from _pytest.mark import MarkDecorator
|
||||
from _pytest.mark import MarkDecorator, MARK_GEN
|
||||
if isinstance(marker, py.builtin._basestring):
|
||||
marker = getattr(pytest.mark, marker)
|
||||
marker = getattr(MARK_GEN, marker)
|
||||
elif not isinstance(marker, MarkDecorator):
|
||||
raise ValueError("is not a string or pytest.mark.* Marker")
|
||||
self.keywords[marker.name] = marker
|
||||
|
@ -555,12 +559,12 @@ class Session(FSCollector):
|
|||
def _makeid(self):
|
||||
return ""
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
@hookimpl(tryfirst=True)
|
||||
def pytest_collectstart(self):
|
||||
if self.shouldstop:
|
||||
raise self.Interrupted(self.shouldstop)
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
@hookimpl(tryfirst=True)
|
||||
def pytest_runtest_logreport(self, report):
|
||||
if report.failed and not hasattr(report, 'wasxfail'):
|
||||
self.testsfailed += 1
|
||||
|
@ -619,8 +623,8 @@ class Session(FSCollector):
|
|||
for arg, exc in self._notfound:
|
||||
line = "(no name %r in any of %r)" % (arg, exc.args[0])
|
||||
errors.append("not found: %s\n%s" % (arg, line))
|
||||
#XXX: test this
|
||||
raise pytest.UsageError(*errors)
|
||||
# XXX: test this
|
||||
raise UsageError(*errors)
|
||||
if not genitems:
|
||||
return rep.result
|
||||
else:
|
||||
|
@ -648,7 +652,7 @@ class Session(FSCollector):
|
|||
names = self._parsearg(arg)
|
||||
path = names.pop(0)
|
||||
if path.check(dir=1):
|
||||
assert not names, "invalid arg %r" %(arg,)
|
||||
assert not names, "invalid arg %r" % (arg,)
|
||||
for path in path.visit(fil=lambda x: x.check(file=1),
|
||||
rec=self._recurse, bf=True, sort=True):
|
||||
for x in self._collectfile(path):
|
||||
|
@ -707,9 +711,11 @@ class Session(FSCollector):
|
|||
path = self.config.invocation_dir.join(relpath, abs=True)
|
||||
if not path.check():
|
||||
if self.config.option.pyargs:
|
||||
raise pytest.UsageError("file or package not found: " + arg + " (missing __init__.py?)")
|
||||
raise UsageError(
|
||||
"file or package not found: " + arg +
|
||||
" (missing __init__.py?)")
|
||||
else:
|
||||
raise pytest.UsageError("file not found: " + arg)
|
||||
raise UsageError("file not found: " + arg)
|
||||
parts[0] = path
|
||||
return parts
|
||||
|
||||
|
@ -732,11 +738,11 @@ class Session(FSCollector):
|
|||
nextnames = names[1:]
|
||||
resultnodes = []
|
||||
for node in matching:
|
||||
if isinstance(node, pytest.Item):
|
||||
if isinstance(node, Item):
|
||||
if not names:
|
||||
resultnodes.append(node)
|
||||
continue
|
||||
assert isinstance(node, pytest.Collector)
|
||||
assert isinstance(node, Collector)
|
||||
rep = collect_one_node(node)
|
||||
if rep.passed:
|
||||
has_matched = False
|
||||
|
@ -754,11 +760,11 @@ class Session(FSCollector):
|
|||
|
||||
def genitems(self, node):
|
||||
self.trace("genitems", node)
|
||||
if isinstance(node, pytest.Item):
|
||||
if isinstance(node, Item):
|
||||
node.ihook.pytest_itemcollected(item=node)
|
||||
yield node
|
||||
else:
|
||||
assert isinstance(node, pytest.Collector)
|
||||
assert isinstance(node, Collector)
|
||||
rep = collect_one_node(node)
|
||||
if rep.passed:
|
||||
for subnode in rep.result:
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
""" monkeypatching and mocking functionality. """
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
import os, sys
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
|
||||
from py.builtin import _basestring
|
||||
|
||||
import pytest
|
||||
from _pytest.fixtures import fixture
|
||||
|
||||
RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@fixture
|
||||
def monkeypatch():
|
||||
"""The returned ``monkeypatch`` fixture provides these
|
||||
helper methods to modify objects, dictionaries or os.environ::
|
||||
|
|
|
@ -9,13 +9,13 @@ import math
|
|||
from itertools import count
|
||||
|
||||
import py
|
||||
import pytest
|
||||
from _pytest.mark import MarkerError
|
||||
|
||||
from _pytest.config import hookimpl
|
||||
|
||||
import _pytest
|
||||
import _pytest._pluggy as pluggy
|
||||
from _pytest import fixtures
|
||||
from _pytest import main
|
||||
from _pytest.compat import (
|
||||
isclass, isfunction, is_generator, _escape_strings,
|
||||
REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
|
||||
|
@ -50,7 +50,7 @@ def filter_traceback(entry):
|
|||
|
||||
def pyobj_property(name):
|
||||
def get(self):
|
||||
node = self.getparent(getattr(pytest, name))
|
||||
node = self.getparent(getattr(__import__('pytest'), name))
|
||||
if node is not None:
|
||||
return node.obj
|
||||
doc = "python %s object this node was collected from (can be None)." % (
|
||||
|
@ -128,7 +128,7 @@ def pytest_configure(config):
|
|||
)
|
||||
|
||||
|
||||
@pytest.hookimpl(trylast=True)
|
||||
@hookimpl(trylast=True)
|
||||
def pytest_pyfunc_call(pyfuncitem):
|
||||
testfunction = pyfuncitem.obj
|
||||
if pyfuncitem._isyieldedfunction():
|
||||
|
@ -141,6 +141,7 @@ def pytest_pyfunc_call(pyfuncitem):
|
|||
testfunction(**testargs)
|
||||
return True
|
||||
|
||||
|
||||
def pytest_collect_file(path, parent):
|
||||
ext = path.ext
|
||||
if ext == ".py":
|
||||
|
@ -156,7 +157,7 @@ def pytest_collect_file(path, parent):
|
|||
def pytest_pycollect_makemodule(path, parent):
|
||||
return Module(path, parent)
|
||||
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
@hookimpl(hookwrapper=True)
|
||||
def pytest_pycollect_makeitem(collector, name, obj):
|
||||
outcome = yield
|
||||
res = outcome.get_result()
|
||||
|
@ -252,7 +253,7 @@ class PyobjMixin(PyobjContext):
|
|||
assert isinstance(lineno, int)
|
||||
return fspath, lineno, modpath
|
||||
|
||||
class PyCollector(PyobjMixin, pytest.Collector):
|
||||
class PyCollector(PyobjMixin, main.Collector):
|
||||
|
||||
def funcnamefilter(self, name):
|
||||
return self._matches_prefix_or_glob_option('python_functions', name)
|
||||
|
@ -576,7 +577,7 @@ class FunctionMixin(PyobjMixin):
|
|||
entry.set_repr_style('short')
|
||||
|
||||
def _repr_failure_py(self, excinfo, style="long"):
|
||||
if excinfo.errisinstance(pytest.fail.Exception):
|
||||
if excinfo.errisinstance(fail.Exception):
|
||||
if not excinfo.value.pytrace:
|
||||
return py._builtin._totext(excinfo.value)
|
||||
return super(FunctionMixin, self)._repr_failure_py(excinfo,
|
||||
|
@ -774,7 +775,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
|
|||
to set a dynamic scope using test context or configuration.
|
||||
"""
|
||||
from _pytest.fixtures import scope2index
|
||||
from _pytest.mark import ParameterSet
|
||||
from _pytest.mark import extract_argvalue, MARK_GEN
|
||||
from py.io import saferepr
|
||||
|
||||
if not isinstance(argnames, (tuple, list)):
|
||||
|
@ -1240,7 +1241,7 @@ class RaisesContext(object):
|
|||
def __exit__(self, *tp):
|
||||
__tracebackhide__ = True
|
||||
if tp[0] is None:
|
||||
pytest.fail(self.message)
|
||||
fail(self.message)
|
||||
if sys.version_info < (2, 7):
|
||||
# py26: on __exit__() exc_value often does not contain the
|
||||
# exception value.
|
||||
|
@ -1511,7 +1512,7 @@ class ApproxNonIterable(object):
|
|||
# the basic pytest Function item
|
||||
#
|
||||
|
||||
class Function(FunctionMixin, pytest.Item, fixtures.FuncargnamesCompatAttr):
|
||||
class Function(FunctionMixin, main.Item, fixtures.FuncargnamesCompatAttr):
|
||||
""" a Function Item is responsible for setting up and executing a
|
||||
Python test function.
|
||||
"""
|
||||
|
|
|
@ -7,10 +7,11 @@ import _pytest._code
|
|||
import py
|
||||
import sys
|
||||
import warnings
|
||||
import pytest
|
||||
|
||||
from _pytest.fixtures import yield_fixture
|
||||
|
||||
|
||||
@pytest.yield_fixture
|
||||
@yield_fixture
|
||||
def recwarn():
|
||||
"""Return a WarningsRecorder instance that provides these methods:
|
||||
|
||||
|
@ -190,7 +191,8 @@ class WarningsChecker(WarningsRecorder):
|
|||
if not any(issubclass(r.category, self.expected_warning)
|
||||
for r in self):
|
||||
__tracebackhide__ = True
|
||||
pytest.fail("DID NOT WARN. No warnings of type {0} was emitted. "
|
||||
"The list of emitted warnings is: {1}.".format(
|
||||
self.expected_warning,
|
||||
[each.message for each in self]))
|
||||
from _pytest.runner import fail
|
||||
fail("DID NOT WARN. No warnings of type {0} was emitted. "
|
||||
"The list of emitted warnings is: {1}.".format(
|
||||
self.expected_warning,
|
||||
[each.message for each in self]))
|
||||
|
|
|
@ -6,7 +6,6 @@ import sys
|
|||
from time import time
|
||||
|
||||
import py
|
||||
import pytest
|
||||
from _pytest._code.code import TerminalRepr, ExceptionInfo
|
||||
|
||||
|
||||
|
@ -257,7 +256,7 @@ def pytest_runtest_makereport(item, call):
|
|||
if not isinstance(excinfo, ExceptionInfo):
|
||||
outcome = "failed"
|
||||
longrepr = excinfo
|
||||
elif excinfo.errisinstance(pytest.skip.Exception):
|
||||
elif excinfo.errisinstance(skip.Exception):
|
||||
outcome = "skipped"
|
||||
r = excinfo._getreprcrash()
|
||||
longrepr = (str(r.path), r.lineno, r.message)
|
||||
|
|
|
@ -6,9 +6,9 @@ import sys
|
|||
import traceback
|
||||
|
||||
import py
|
||||
import pytest
|
||||
from _pytest.config import hookimpl
|
||||
from _pytest.mark import MarkInfo, MarkDecorator
|
||||
|
||||
from _pytest.runner import fail, skip
|
||||
|
||||
def pytest_addoption(parser):
|
||||
group = parser.getgroup("general")
|
||||
|
@ -25,6 +25,8 @@ def pytest_addoption(parser):
|
|||
|
||||
def pytest_configure(config):
|
||||
if config.option.runxfail:
|
||||
# yay a hack
|
||||
import pytest
|
||||
old = pytest.xfail
|
||||
config._cleanup.append(lambda: setattr(pytest, "xfail", old))
|
||||
|
||||
|
@ -57,7 +59,7 @@ def pytest_configure(config):
|
|||
)
|
||||
|
||||
|
||||
class XFailed(pytest.fail.Exception):
|
||||
class XFailed(fail.Exception):
|
||||
""" raised from an explicit call to pytest.xfail() """
|
||||
|
||||
|
||||
|
@ -98,15 +100,15 @@ class MarkEvaluator(object):
|
|||
except Exception:
|
||||
self.exc = sys.exc_info()
|
||||
if isinstance(self.exc[1], SyntaxError):
|
||||
msg = [" " * (self.exc[1].offset + 4) + "^",]
|
||||
msg = [" " * (self.exc[1].offset + 4) + "^", ]
|
||||
msg.append("SyntaxError: invalid syntax")
|
||||
else:
|
||||
msg = traceback.format_exception_only(*self.exc[:2])
|
||||
pytest.fail("Error evaluating %r expression\n"
|
||||
" %s\n"
|
||||
"%s"
|
||||
%(self.name, self.expr, "\n".join(msg)),
|
||||
pytrace=False)
|
||||
fail("Error evaluating %r expression\n"
|
||||
" %s\n"
|
||||
"%s"
|
||||
% (self.name, self.expr, "\n".join(msg)),
|
||||
pytrace=False)
|
||||
|
||||
def _getglobals(self):
|
||||
d = {'os': os, 'sys': sys, 'config': self.item.config}
|
||||
|
@ -138,7 +140,7 @@ class MarkEvaluator(object):
|
|||
# XXX better be checked at collection time
|
||||
msg = "you need to specify reason=STRING " \
|
||||
"when using booleans as conditions."
|
||||
pytest.fail(msg)
|
||||
fail(msg)
|
||||
result = bool(expr)
|
||||
if result:
|
||||
self.result = True
|
||||
|
@ -162,7 +164,7 @@ class MarkEvaluator(object):
|
|||
return expl
|
||||
|
||||
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
@hookimpl(tryfirst=True)
|
||||
def pytest_runtest_setup(item):
|
||||
# Check if skip or skipif are specified as pytest marks
|
||||
|
||||
|
@ -171,23 +173,23 @@ def pytest_runtest_setup(item):
|
|||
eval_skipif = MarkEvaluator(item, 'skipif')
|
||||
if eval_skipif.istrue():
|
||||
item._evalskip = eval_skipif
|
||||
pytest.skip(eval_skipif.getexplanation())
|
||||
skip(eval_skipif.getexplanation())
|
||||
|
||||
skip_info = item.keywords.get('skip')
|
||||
if isinstance(skip_info, (MarkInfo, MarkDecorator)):
|
||||
item._evalskip = True
|
||||
if 'reason' in skip_info.kwargs:
|
||||
pytest.skip(skip_info.kwargs['reason'])
|
||||
skip(skip_info.kwargs['reason'])
|
||||
elif skip_info.args:
|
||||
pytest.skip(skip_info.args[0])
|
||||
skip(skip_info.args[0])
|
||||
else:
|
||||
pytest.skip("unconditional skip")
|
||||
skip("unconditional skip")
|
||||
|
||||
item._evalxfail = MarkEvaluator(item, 'xfail')
|
||||
check_xfail_no_run(item)
|
||||
|
||||
|
||||
@pytest.mark.hookwrapper
|
||||
@hookimpl(hookwrapper=True)
|
||||
def pytest_pyfunc_call(pyfuncitem):
|
||||
check_xfail_no_run(pyfuncitem)
|
||||
outcome = yield
|
||||
|
@ -217,7 +219,7 @@ def check_strict_xfail(pyfuncitem):
|
|||
pytest.fail('[XPASS(strict)] ' + explanation, pytrace=False)
|
||||
|
||||
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
@hookimpl(hookwrapper=True)
|
||||
def pytest_runtest_makereport(item, call):
|
||||
outcome = yield
|
||||
rep = outcome.get_result()
|
||||
|
@ -237,7 +239,7 @@ def pytest_runtest_makereport(item, call):
|
|||
rep.wasxfail = rep.longrepr
|
||||
elif item.config.option.runxfail:
|
||||
pass # don't interefere
|
||||
elif call.excinfo and call.excinfo.errisinstance(pytest.xfail.Exception):
|
||||
elif call.excinfo and call.excinfo.errisinstance(xfail.Exception):
|
||||
rep.wasxfail = "reason: " + call.excinfo.value.msg
|
||||
rep.outcome = "skipped"
|
||||
elif evalxfail and not rep.skipped and evalxfail.wasvalid() and \
|
||||
|
|
Loading…
Reference in New Issue