Merge pull request #2315 from RonnyPfannschmidt/namespace-hook
remove pytest internal usage of the namespace hook
This commit is contained in:
		
						commit
						25371ddbfd
					
				| 
						 | 
					@ -27,6 +27,10 @@ New Features
 | 
				
			||||||
Changes
 | 
					Changes
 | 
				
			||||||
-------
 | 
					-------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* remove all internal uses of pytest_namespace hooks,
 | 
				
			||||||
 | 
					  this is to prepare the removal of preloadconfig in pytest 4.0
 | 
				
			||||||
 | 
					  Thanks to `@RonnyPfannschmidt`_ for the PR.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Old-style classes have been changed to new-style classes in order to improve
 | 
					* Old-style classes have been changed to new-style classes in order to improve
 | 
				
			||||||
  compatibility with Python 2. Thanks to `@MichalTHEDUDE`_ and `@mandeep`_ for the PR (`#2147`_).
 | 
					  compatibility with Python 2. Thanks to `@MichalTHEDUDE`_ and `@mandeep`_ for the PR (`#2147`_).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,9 +25,6 @@ def pytest_addoption(parser):
 | 
				
			||||||
                            expression information.""")
 | 
					                            expression information.""")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    return {'register_assert_rewrite': register_assert_rewrite}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def register_assert_rewrite(*names):
 | 
					def register_assert_rewrite(*names):
 | 
				
			||||||
    """Register one or more module names to be rewritten on import.
 | 
					    """Register one or more module names to be rewritten on import.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -254,6 +254,29 @@ else:
 | 
				
			||||||
            return v.encode('ascii', errors)
 | 
					            return v.encode('ascii', errors)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COLLECT_FAKEMODULE_ATTRIBUTES = (
 | 
				
			||||||
 | 
					    'Collector',
 | 
				
			||||||
 | 
					    'Module',
 | 
				
			||||||
 | 
					    'Generator',
 | 
				
			||||||
 | 
					    'Function',
 | 
				
			||||||
 | 
					    'Instance',
 | 
				
			||||||
 | 
					    'Session',
 | 
				
			||||||
 | 
					    'Item',
 | 
				
			||||||
 | 
					    'Class',
 | 
				
			||||||
 | 
					    'File',
 | 
				
			||||||
 | 
					    '_fillfuncargs',
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _setup_collect_fakemodule():
 | 
				
			||||||
 | 
					    from types import ModuleType
 | 
				
			||||||
 | 
					    import pytest
 | 
				
			||||||
 | 
					    pytest.collect = ModuleType('pytest.collect')
 | 
				
			||||||
 | 
					    pytest.collect.__all__ = []  # used for setns
 | 
				
			||||||
 | 
					    for attr in COLLECT_FAKEMODULE_ATTRIBUTES:
 | 
				
			||||||
 | 
					        setattr(pytest.collect, attr, getattr(pytest, attr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if _PY2:
 | 
					if _PY2:
 | 
				
			||||||
    from py.io import TextIO as CaptureIO
 | 
					    from py.io import TextIO as CaptureIO
 | 
				
			||||||
else:
 | 
					else:
 | 
				
			||||||
| 
						 | 
					@ -268,3 +291,12 @@ else:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        def getvalue(self):
 | 
					        def getvalue(self):
 | 
				
			||||||
            return self.buffer.getvalue().decode('UTF-8')
 | 
					            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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,6 +100,7 @@ default_plugins = (
 | 
				
			||||||
     "junitxml resultlog doctest cacheprovider freeze_support "
 | 
					     "junitxml resultlog doctest cacheprovider freeze_support "
 | 
				
			||||||
     "setuponly setupplan warnings").split()
 | 
					     "setuponly setupplan warnings").split()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
builtin_plugins = set(default_plugins)
 | 
					builtin_plugins = set(default_plugins)
 | 
				
			||||||
builtin_plugins.add("pytester")
 | 
					builtin_plugins.add("pytester")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3,7 +3,6 @@ from __future__ import absolute_import, division, print_function
 | 
				
			||||||
import pdb
 | 
					import pdb
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_addoption(parser):
 | 
					def pytest_addoption(parser):
 | 
				
			||||||
| 
						 | 
					@ -16,8 +15,6 @@ def pytest_addoption(parser):
 | 
				
			||||||
        help="start a custom interactive Python debugger on errors. "
 | 
					        help="start a custom interactive Python debugger on errors. "
 | 
				
			||||||
             "For example: --pdbcls=IPython.terminal.debugger:TerminalPdb")
 | 
					             "For example: --pdbcls=IPython.terminal.debugger:TerminalPdb")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    return {'set_trace': pytestPDB().set_trace}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_configure(config):
 | 
					def pytest_configure(config):
 | 
				
			||||||
    if config.getvalue("usepdb_cls"):
 | 
					    if config.getvalue("usepdb_cls"):
 | 
				
			||||||
| 
						 | 
					@ -37,31 +34,33 @@ def pytest_configure(config):
 | 
				
			||||||
        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 = pytestPDB.set_trace
 | 
				
			||||||
    pytestPDB._pluginmanager = config.pluginmanager
 | 
					    pytestPDB._pluginmanager = config.pluginmanager
 | 
				
			||||||
    pytestPDB._config = config
 | 
					    pytestPDB._config = config
 | 
				
			||||||
    pytestPDB._pdb_cls = pdb_cls
 | 
					    pytestPDB._pdb_cls = pdb_cls
 | 
				
			||||||
    config._cleanup.append(fin)
 | 
					    config._cleanup.append(fin)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class pytestPDB(object):
 | 
					class pytestPDB(object):
 | 
				
			||||||
    """ Pseudo PDB that defers to the real pdb. """
 | 
					    """ Pseudo PDB that defers to the real pdb. """
 | 
				
			||||||
    _pluginmanager = None
 | 
					    _pluginmanager = None
 | 
				
			||||||
    _config = None
 | 
					    _config = None
 | 
				
			||||||
    _pdb_cls = pdb.Pdb
 | 
					    _pdb_cls = pdb.Pdb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_trace(self):
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def set_trace(cls):
 | 
				
			||||||
        """ invoke PDB set_trace debugging, dropping any IO capturing. """
 | 
					        """ invoke PDB set_trace debugging, dropping any IO capturing. """
 | 
				
			||||||
        import _pytest.config
 | 
					        import _pytest.config
 | 
				
			||||||
        frame = sys._getframe().f_back
 | 
					        frame = sys._getframe().f_back
 | 
				
			||||||
        if self._pluginmanager is not None:
 | 
					        if cls._pluginmanager is not None:
 | 
				
			||||||
            capman = self._pluginmanager.getplugin("capturemanager")
 | 
					            capman = cls._pluginmanager.getplugin("capturemanager")
 | 
				
			||||||
            if capman:
 | 
					            if capman:
 | 
				
			||||||
                capman.suspendcapture(in_=True)
 | 
					                capman.suspendcapture(in_=True)
 | 
				
			||||||
            tw = _pytest.config.create_terminal_writer(self._config)
 | 
					            tw = _pytest.config.create_terminal_writer(cls._config)
 | 
				
			||||||
            tw.line()
 | 
					            tw.line()
 | 
				
			||||||
            tw.sep(">", "PDB set_trace (IO-capturing turned off)")
 | 
					            tw.sep(">", "PDB set_trace (IO-capturing turned off)")
 | 
				
			||||||
            self._pluginmanager.hook.pytest_enter_pdb(config=self._config)
 | 
					            cls._pluginmanager.hook.pytest_enter_pdb(config=cls._config)
 | 
				
			||||||
        self._pdb_cls().set_trace(frame)
 | 
					        cls._pdb_cls().set_trace(frame)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PdbInvoke(object):
 | 
					class PdbInvoke(object):
 | 
				
			||||||
| 
						 | 
					@ -75,7 +74,7 @@ class PdbInvoke(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def pytest_internalerror(self, excrepr, excinfo):
 | 
					    def pytest_internalerror(self, excrepr, excinfo):
 | 
				
			||||||
        for line in str(excrepr).split("\n"):
 | 
					        for line in str(excrepr).split("\n"):
 | 
				
			||||||
            sys.stderr.write("INTERNALERROR> %s\n" %line)
 | 
					            sys.stderr.write("INTERNALERROR> %s\n" % line)
 | 
				
			||||||
            sys.stderr.flush()
 | 
					            sys.stderr.flush()
 | 
				
			||||||
        tb = _postmortem_traceback(excinfo)
 | 
					        tb = _postmortem_traceback(excinfo)
 | 
				
			||||||
        post_mortem(tb)
 | 
					        post_mortem(tb)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,7 +4,6 @@ import sys
 | 
				
			||||||
from py._code.code import FormattedExcinfo
 | 
					from py._code.code import FormattedExcinfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
import warnings
 | 
					import warnings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import inspect
 | 
					import inspect
 | 
				
			||||||
| 
						 | 
					@ -17,8 +16,16 @@ from _pytest.compat import (
 | 
				
			||||||
    getlocation, getfuncargnames,
 | 
					    getlocation, getfuncargnames,
 | 
				
			||||||
    safe_getattr,
 | 
					    safe_getattr,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from _pytest.runner import fail
 | 
				
			||||||
 | 
					from _pytest.compat import FuncargnamesCompatAttr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_sessionstart(session):
 | 
					def pytest_sessionstart(session):
 | 
				
			||||||
 | 
					    import _pytest.python
 | 
				
			||||||
 | 
					    scopename2class.update({
 | 
				
			||||||
 | 
					        'class': _pytest.python.Class,
 | 
				
			||||||
 | 
					        'module': _pytest.python.Module,
 | 
				
			||||||
 | 
					        'function': _pytest.main.Item,
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
    session._fixturemanager = FixtureManager(session)
 | 
					    session._fixturemanager = FixtureManager(session)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,19 +52,6 @@ def scopeproperty(name=None, doc=None):
 | 
				
			||||||
    return decoratescope
 | 
					    return decoratescope
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    scopename2class.update({
 | 
					 | 
				
			||||||
        'class': pytest.Class,
 | 
					 | 
				
			||||||
        'module': pytest.Module,
 | 
					 | 
				
			||||||
        'function': pytest.Item,
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        'fixture': fixture,
 | 
					 | 
				
			||||||
        'yield_fixture': yield_fixture,
 | 
					 | 
				
			||||||
        'collect': {'_fillfuncargs': fillfixtures}
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def get_scope_node(node, scope):
 | 
					def get_scope_node(node, scope):
 | 
				
			||||||
    cls = scopename2class.get(scope)
 | 
					    cls = scopename2class.get(scope)
 | 
				
			||||||
    if cls is None:
 | 
					    if cls is None:
 | 
				
			||||||
| 
						 | 
					@ -105,7 +99,7 @@ def add_funcarg_pseudo_fixture_def(collector, metafunc, fixturemanager):
 | 
				
			||||||
        if scope != "function":
 | 
					        if scope != "function":
 | 
				
			||||||
            node = get_scope_node(collector, scope)
 | 
					            node = get_scope_node(collector, scope)
 | 
				
			||||||
            if node is None:
 | 
					            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)
 | 
					                # use module-level collector for class-scope (for now)
 | 
				
			||||||
                node = collector
 | 
					                node = collector
 | 
				
			||||||
        if node and argname in node._name2pseudofixturedef:
 | 
					        if node and argname in node._name2pseudofixturedef:
 | 
				
			||||||
| 
						 | 
					@ -221,17 +215,6 @@ def slice_items(items, ignore, scoped_argkeys_cache):
 | 
				
			||||||
    return items, None, None, None
 | 
					    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):
 | 
					def fillfixtures(function):
 | 
				
			||||||
    """ fill missing funcargs for a test function. """
 | 
					    """ fill missing funcargs for a test function. """
 | 
				
			||||||
    try:
 | 
					    try:
 | 
				
			||||||
| 
						 | 
					@ -327,7 +310,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
 | 
				
			||||||
    @scopeproperty("class")
 | 
					    @scopeproperty("class")
 | 
				
			||||||
    def cls(self):
 | 
					    def cls(self):
 | 
				
			||||||
        """ class (can be None) where the test function was collected. """
 | 
					        """ 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:
 | 
					        if clscol:
 | 
				
			||||||
            return clscol.obj
 | 
					            return clscol.obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -345,7 +328,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
 | 
				
			||||||
    @scopeproperty()
 | 
					    @scopeproperty()
 | 
				
			||||||
    def module(self):
 | 
					    def module(self):
 | 
				
			||||||
        """ python module object where the test function was collected. """
 | 
					        """ 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()
 | 
					    @scopeproperty()
 | 
				
			||||||
    def fspath(self):
 | 
					    def fspath(self):
 | 
				
			||||||
| 
						 | 
					@ -508,7 +491,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
 | 
				
			||||||
                        source_lineno,
 | 
					                        source_lineno,
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
                pytest.fail(msg)
 | 
					                fail(msg)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            # indices might not be set if old-style metafunc.addcall() was used
 | 
					            # indices might not be set if old-style metafunc.addcall() was used
 | 
				
			||||||
            param_index = funcitem.callspec.indices.get(argname, 0)
 | 
					            param_index = funcitem.callspec.indices.get(argname, 0)
 | 
				
			||||||
| 
						 | 
					@ -541,10 +524,10 @@ class FixtureRequest(FuncargnamesCompatAttr):
 | 
				
			||||||
        if scopemismatch(invoking_scope, requested_scope):
 | 
					        if scopemismatch(invoking_scope, requested_scope):
 | 
				
			||||||
            # try to report something helpful
 | 
					            # try to report something helpful
 | 
				
			||||||
            lines = self._factorytraceback()
 | 
					            lines = self._factorytraceback()
 | 
				
			||||||
            pytest.fail("ScopeMismatch: You tried to access the %r scoped "
 | 
					            fail("ScopeMismatch: You tried to access the %r scoped "
 | 
				
			||||||
                "fixture %r with a %r scoped request object, "
 | 
					                 "fixture %r with a %r scoped request object, "
 | 
				
			||||||
                "involved factories\n%s" %(
 | 
					                 "involved factories\n%s" % (
 | 
				
			||||||
                (requested_scope, argname, invoking_scope, "\n".join(lines))),
 | 
					                    (requested_scope, argname, invoking_scope, "\n".join(lines))),
 | 
				
			||||||
                pytrace=False)
 | 
					                pytrace=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _factorytraceback(self):
 | 
					    def _factorytraceback(self):
 | 
				
			||||||
| 
						 | 
					@ -554,7 +537,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
 | 
				
			||||||
            fs, lineno = getfslineno(factory)
 | 
					            fs, lineno = getfslineno(factory)
 | 
				
			||||||
            p = self._pyfuncitem.session.fspath.bestrelpath(fs)
 | 
					            p = self._pyfuncitem.session.fspath.bestrelpath(fs)
 | 
				
			||||||
            args = _format_args(factory)
 | 
					            args = _format_args(factory)
 | 
				
			||||||
            lines.append("%s:%d:  def %s%s" %(
 | 
					            lines.append("%s:%d:  def %s%s" % (
 | 
				
			||||||
                p, lineno, factory.__name__, args))
 | 
					                p, lineno, factory.__name__, args))
 | 
				
			||||||
        return lines
 | 
					        return lines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -699,8 +682,9 @@ def fail_fixturefunc(fixturefunc, msg):
 | 
				
			||||||
    fs, lineno = getfslineno(fixturefunc)
 | 
					    fs, lineno = getfslineno(fixturefunc)
 | 
				
			||||||
    location = "%s:%s" % (fs, lineno+1)
 | 
					    location = "%s:%s" % (fs, lineno+1)
 | 
				
			||||||
    source = _pytest._code.Source(fixturefunc)
 | 
					    source = _pytest._code.Source(fixturefunc)
 | 
				
			||||||
    pytest.fail(msg + ":\n\n" + str(source.indent()) + "\n" + location,
 | 
					    fail(msg + ":\n\n" + str(source.indent()) + "\n" + location,
 | 
				
			||||||
                pytrace=False)
 | 
					         pytrace=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def call_fixture_func(fixturefunc, request, kwargs):
 | 
					def call_fixture_func(fixturefunc, request, kwargs):
 | 
				
			||||||
    yieldctx = is_generator(fixturefunc)
 | 
					    yieldctx = is_generator(fixturefunc)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,9 +5,6 @@ pytest
 | 
				
			||||||
from __future__ import absolute_import, division, print_function
 | 
					from __future__ import absolute_import, division, print_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    return {'freeze_includes': freeze_includes}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def freeze_includes():
 | 
					def freeze_includes():
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,9 @@ def pytest_addhooks(pluginmanager):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@hookspec(historic=True)
 | 
					@hookspec(historic=True)
 | 
				
			||||||
def pytest_namespace():
 | 
					def pytest_namespace():
 | 
				
			||||||
    """return dict of name->object to be made globally available in
 | 
					    """
 | 
				
			||||||
 | 
					    DEPRECATED: this hook causes direct monkeypatching on pytest, its use is strongly discouraged
 | 
				
			||||||
 | 
					    return dict of name->object to be made globally available in
 | 
				
			||||||
    the pytest namespace.  This hook is called at plugin registration
 | 
					    the pytest namespace.  This hook is called at plugin registration
 | 
				
			||||||
    time.
 | 
					    time.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,13 @@ import sys
 | 
				
			||||||
import _pytest
 | 
					import _pytest
 | 
				
			||||||
import _pytest._code
 | 
					import _pytest._code
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
try:
 | 
					try:
 | 
				
			||||||
    from collections import MutableMapping as MappingMixin
 | 
					    from collections import MutableMapping as MappingMixin
 | 
				
			||||||
except ImportError:
 | 
					except ImportError:
 | 
				
			||||||
    from UserDict import DictMixin as MappingMixin
 | 
					    from UserDict import DictMixin as MappingMixin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from _pytest.config import directory_arg
 | 
					from _pytest.config import directory_arg, UsageError, hookimpl
 | 
				
			||||||
from _pytest.runner import collect_one_node
 | 
					from _pytest.runner import collect_one_node, exit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
tracebackcutdir = py.path.local(_pytest.__file__).dirpath()
 | 
					tracebackcutdir = py.path.local(_pytest.__file__).dirpath()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +26,7 @@ EXIT_INTERNALERROR = 3
 | 
				
			||||||
EXIT_USAGEERROR = 4
 | 
					EXIT_USAGEERROR = 4
 | 
				
			||||||
EXIT_NOTESTSCOLLECTED = 5
 | 
					EXIT_NOTESTSCOLLECTED = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_addoption(parser):
 | 
					def pytest_addoption(parser):
 | 
				
			||||||
    parser.addini("norecursedirs", "directory patterns to avoid for recursion",
 | 
					    parser.addini("norecursedirs", "directory patterns to avoid for recursion",
 | 
				
			||||||
        type="args", default=['.*', 'build', 'dist', 'CVS', '_darcs', '{arch}', '*.egg', 'venv'])
 | 
					        type="args", default=['.*', 'build', 'dist', 'CVS', '_darcs', '{arch}', '*.egg', 'venv'])
 | 
				
			||||||
| 
						 | 
					@ -77,13 +77,18 @@ def pytest_addoption(parser):
 | 
				
			||||||
               help="base temporary directory for this test run.")
 | 
					               help="base temporary directory for this test run.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					def pytest_namespace():
 | 
				
			||||||
    collect = dict(Item=Item, Collector=Collector, File=File, Session=Session)
 | 
					    """keeping this one works around a deeper startup issue in pytest
 | 
				
			||||||
    return dict(collect=collect)
 | 
					
 | 
				
			||||||
 | 
					    i tried to find it for a while but the amount of time turned unsustainable,
 | 
				
			||||||
 | 
					    so i put a hack in to revisit later
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    return {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_configure(config):
 | 
					def pytest_configure(config):
 | 
				
			||||||
    pytest.config = config # compatibility
 | 
					    __import__('pytest').config = config # compatibiltiy
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def wrap_session(config, doit):
 | 
					def wrap_session(config, doit):
 | 
				
			||||||
| 
						 | 
					@ -98,12 +103,11 @@ def wrap_session(config, doit):
 | 
				
			||||||
            config.hook.pytest_sessionstart(session=session)
 | 
					            config.hook.pytest_sessionstart(session=session)
 | 
				
			||||||
            initstate = 2
 | 
					            initstate = 2
 | 
				
			||||||
            session.exitstatus = doit(config, session) or 0
 | 
					            session.exitstatus = doit(config, session) or 0
 | 
				
			||||||
        except pytest.UsageError:
 | 
					        except UsageError:
 | 
				
			||||||
            raise
 | 
					            raise
 | 
				
			||||||
        except KeyboardInterrupt:
 | 
					        except KeyboardInterrupt:
 | 
				
			||||||
            excinfo = _pytest._code.ExceptionInfo()
 | 
					            excinfo = _pytest._code.ExceptionInfo()
 | 
				
			||||||
            if initstate < 2 and isinstance(
 | 
					            if initstate < 2 and isinstance(excinfo.value, exit.Exception):
 | 
				
			||||||
                    excinfo.value, pytest.exit.Exception):
 | 
					 | 
				
			||||||
                sys.stderr.write('{0}: {1}\n'.format(
 | 
					                sys.stderr.write('{0}: {1}\n'.format(
 | 
				
			||||||
                    excinfo.typename, excinfo.value.msg))
 | 
					                    excinfo.typename, excinfo.value.msg))
 | 
				
			||||||
            config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
 | 
					            config.hook.pytest_keyboard_interrupt(excinfo=excinfo)
 | 
				
			||||||
| 
						 | 
					@ -125,9 +129,11 @@ def wrap_session(config, doit):
 | 
				
			||||||
        config._ensure_unconfigure()
 | 
					        config._ensure_unconfigure()
 | 
				
			||||||
    return session.exitstatus
 | 
					    return session.exitstatus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_cmdline_main(config):
 | 
					def pytest_cmdline_main(config):
 | 
				
			||||||
    return wrap_session(config, _main)
 | 
					    return wrap_session(config, _main)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _main(config, session):
 | 
					def _main(config, session):
 | 
				
			||||||
    """ default command line protocol for initialization, session,
 | 
					    """ default command line protocol for initialization, session,
 | 
				
			||||||
    running tests and reporting. """
 | 
					    running tests and reporting. """
 | 
				
			||||||
| 
						 | 
					@ -139,9 +145,11 @@ def _main(config, session):
 | 
				
			||||||
    elif session.testscollected == 0:
 | 
					    elif session.testscollected == 0:
 | 
				
			||||||
        return EXIT_NOTESTSCOLLECTED
 | 
					        return EXIT_NOTESTSCOLLECTED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_collection(session):
 | 
					def pytest_collection(session):
 | 
				
			||||||
    return session.perform_collect()
 | 
					    return session.perform_collect()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_runtestloop(session):
 | 
					def pytest_runtestloop(session):
 | 
				
			||||||
    if (session.testsfailed and
 | 
					    if (session.testsfailed and
 | 
				
			||||||
            not session.config.option.continue_on_collection_errors):
 | 
					            not session.config.option.continue_on_collection_errors):
 | 
				
			||||||
| 
						 | 
					@ -158,6 +166,7 @@ def pytest_runtestloop(session):
 | 
				
			||||||
            raise session.Interrupted(session.shouldstop)
 | 
					            raise session.Interrupted(session.shouldstop)
 | 
				
			||||||
    return True
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_ignore_collect(path, config):
 | 
					def pytest_ignore_collect(path, config):
 | 
				
			||||||
    p = path.dirpath()
 | 
					    p = path.dirpath()
 | 
				
			||||||
    ignore_paths = config._getconftest_pathlist("collect_ignore", path=p)
 | 
					    ignore_paths = config._getconftest_pathlist("collect_ignore", path=p)
 | 
				
			||||||
| 
						 | 
					@ -205,7 +214,7 @@ class _CompatProperty(object):
 | 
				
			||||||
        #     "usage of {owner!r}.{name} is deprecated, please use pytest.{name} instead".format(
 | 
					        #     "usage of {owner!r}.{name} is deprecated, please use pytest.{name} instead".format(
 | 
				
			||||||
        #         name=self.name, owner=type(owner).__name__),
 | 
					        #         name=self.name, owner=type(owner).__name__),
 | 
				
			||||||
        #     PendingDeprecationWarning, stacklevel=2)
 | 
					        #     PendingDeprecationWarning, stacklevel=2)
 | 
				
			||||||
        return getattr(pytest, self.name)
 | 
					        return getattr(__import__('pytest'), self.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -289,7 +298,7 @@ class Node(object):
 | 
				
			||||||
    def _getcustomclass(self, name):
 | 
					    def _getcustomclass(self, name):
 | 
				
			||||||
        maybe_compatprop = getattr(type(self), name)
 | 
					        maybe_compatprop = getattr(type(self), name)
 | 
				
			||||||
        if isinstance(maybe_compatprop, _CompatProperty):
 | 
					        if isinstance(maybe_compatprop, _CompatProperty):
 | 
				
			||||||
            return getattr(pytest, name)
 | 
					            return getattr(__import__('pytest'), name)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            cls = getattr(self, name)
 | 
					            cls = getattr(self, name)
 | 
				
			||||||
            # TODO: reenable in the features branch
 | 
					            # TODO: reenable in the features branch
 | 
				
			||||||
| 
						 | 
					@ -369,9 +378,9 @@ class Node(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ``marker`` can be a string or pytest.mark.* instance.
 | 
					        ``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):
 | 
					        if isinstance(marker, py.builtin._basestring):
 | 
				
			||||||
            marker = getattr(pytest.mark, marker)
 | 
					            marker = getattr(MARK_GEN, marker)
 | 
				
			||||||
        elif not isinstance(marker, MarkDecorator):
 | 
					        elif not isinstance(marker, MarkDecorator):
 | 
				
			||||||
            raise ValueError("is not a string or pytest.mark.* Marker")
 | 
					            raise ValueError("is not a string or pytest.mark.* Marker")
 | 
				
			||||||
        self.keywords[marker.name] = marker
 | 
					        self.keywords[marker.name] = marker
 | 
				
			||||||
| 
						 | 
					@ -557,12 +566,12 @@ class Session(FSCollector):
 | 
				
			||||||
    def _makeid(self):
 | 
					    def _makeid(self):
 | 
				
			||||||
        return ""
 | 
					        return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.hookimpl(tryfirst=True)
 | 
					    @hookimpl(tryfirst=True)
 | 
				
			||||||
    def pytest_collectstart(self):
 | 
					    def pytest_collectstart(self):
 | 
				
			||||||
        if self.shouldstop:
 | 
					        if self.shouldstop:
 | 
				
			||||||
            raise self.Interrupted(self.shouldstop)
 | 
					            raise self.Interrupted(self.shouldstop)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @pytest.hookimpl(tryfirst=True)
 | 
					    @hookimpl(tryfirst=True)
 | 
				
			||||||
    def pytest_runtest_logreport(self, report):
 | 
					    def pytest_runtest_logreport(self, report):
 | 
				
			||||||
        if report.failed and not hasattr(report, 'wasxfail'):
 | 
					        if report.failed and not hasattr(report, 'wasxfail'):
 | 
				
			||||||
            self.testsfailed += 1
 | 
					            self.testsfailed += 1
 | 
				
			||||||
| 
						 | 
					@ -622,8 +631,8 @@ class Session(FSCollector):
 | 
				
			||||||
            for arg, exc in self._notfound:
 | 
					            for arg, exc in self._notfound:
 | 
				
			||||||
                line = "(no name %r in any of %r)" % (arg, exc.args[0])
 | 
					                line = "(no name %r in any of %r)" % (arg, exc.args[0])
 | 
				
			||||||
                errors.append("not found: %s\n%s" % (arg, line))
 | 
					                errors.append("not found: %s\n%s" % (arg, line))
 | 
				
			||||||
                #XXX: test this
 | 
					                # XXX: test this
 | 
				
			||||||
            raise pytest.UsageError(*errors)
 | 
					            raise UsageError(*errors)
 | 
				
			||||||
        if not genitems:
 | 
					        if not genitems:
 | 
				
			||||||
            return rep.result
 | 
					            return rep.result
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
| 
						 | 
					@ -651,7 +660,7 @@ class Session(FSCollector):
 | 
				
			||||||
        names = self._parsearg(arg)
 | 
					        names = self._parsearg(arg)
 | 
				
			||||||
        path = names.pop(0)
 | 
					        path = names.pop(0)
 | 
				
			||||||
        if path.check(dir=1):
 | 
					        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),
 | 
					            for path in path.visit(fil=lambda x: x.check(file=1),
 | 
				
			||||||
                                   rec=self._recurse, bf=True, sort=True):
 | 
					                                   rec=self._recurse, bf=True, sort=True):
 | 
				
			||||||
                for x in self._collectfile(path):
 | 
					                for x in self._collectfile(path):
 | 
				
			||||||
| 
						 | 
					@ -710,9 +719,11 @@ class Session(FSCollector):
 | 
				
			||||||
        path = self.config.invocation_dir.join(relpath, abs=True)
 | 
					        path = self.config.invocation_dir.join(relpath, abs=True)
 | 
				
			||||||
        if not path.check():
 | 
					        if not path.check():
 | 
				
			||||||
            if self.config.option.pyargs:
 | 
					            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:
 | 
					            else:
 | 
				
			||||||
                raise pytest.UsageError("file not found: " + arg)
 | 
					                raise UsageError("file not found: " + arg)
 | 
				
			||||||
        parts[0] = path
 | 
					        parts[0] = path
 | 
				
			||||||
        return parts
 | 
					        return parts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -735,11 +746,11 @@ class Session(FSCollector):
 | 
				
			||||||
        nextnames = names[1:]
 | 
					        nextnames = names[1:]
 | 
				
			||||||
        resultnodes = []
 | 
					        resultnodes = []
 | 
				
			||||||
        for node in matching:
 | 
					        for node in matching:
 | 
				
			||||||
            if isinstance(node, pytest.Item):
 | 
					            if isinstance(node, Item):
 | 
				
			||||||
                if not names:
 | 
					                if not names:
 | 
				
			||||||
                    resultnodes.append(node)
 | 
					                    resultnodes.append(node)
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            assert isinstance(node, pytest.Collector)
 | 
					            assert isinstance(node, Collector)
 | 
				
			||||||
            rep = collect_one_node(node)
 | 
					            rep = collect_one_node(node)
 | 
				
			||||||
            if rep.passed:
 | 
					            if rep.passed:
 | 
				
			||||||
                has_matched = False
 | 
					                has_matched = False
 | 
				
			||||||
| 
						 | 
					@ -757,11 +768,11 @@ class Session(FSCollector):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def genitems(self, node):
 | 
					    def genitems(self, node):
 | 
				
			||||||
        self.trace("genitems", node)
 | 
					        self.trace("genitems", node)
 | 
				
			||||||
        if isinstance(node, pytest.Item):
 | 
					        if isinstance(node, Item):
 | 
				
			||||||
            node.ihook.pytest_itemcollected(item=node)
 | 
					            node.ihook.pytest_itemcollected(item=node)
 | 
				
			||||||
            yield node
 | 
					            yield node
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            assert isinstance(node, pytest.Collector)
 | 
					            assert isinstance(node, Collector)
 | 
				
			||||||
            rep = collect_one_node(node)
 | 
					            rep = collect_one_node(node)
 | 
				
			||||||
            if rep.passed:
 | 
					            if rep.passed:
 | 
				
			||||||
                for subnode in rep.result:
 | 
					                for subnode in rep.result:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,12 +66,8 @@ class MarkerError(Exception):
 | 
				
			||||||
    """Error in use of a pytest marker/attribute."""
 | 
					    """Error in use of a pytest marker/attribute."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def param(*values, **kw):
 | 
				
			||||||
def pytest_namespace():
 | 
					    return ParameterSet.param(*values, **kw)
 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        'mark': MarkGenerator(),
 | 
					 | 
				
			||||||
        'param': ParameterSet.param,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_addoption(parser):
 | 
					def pytest_addoption(parser):
 | 
				
			||||||
| 
						 | 
					@ -225,9 +221,13 @@ def matchkeyword(colitem, keywordexpr):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_configure(config):
 | 
					def pytest_configure(config):
 | 
				
			||||||
    import pytest
 | 
					    config._old_mark_config = MARK_GEN._config
 | 
				
			||||||
    if config.option.strict:
 | 
					    if config.option.strict:
 | 
				
			||||||
        pytest.mark._config = config
 | 
					        MARK_GEN._config = config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def pytest_unconfigure(config):
 | 
				
			||||||
 | 
					    MARK_GEN._config = getattr(config, '_old_mark_config', None)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MarkGenerator(object):
 | 
					class MarkGenerator(object):
 | 
				
			||||||
| 
						 | 
					@ -241,11 +241,13 @@ class MarkGenerator(object):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    will set a 'slowtest' :class:`MarkInfo` object
 | 
					    will set a 'slowtest' :class:`MarkInfo` object
 | 
				
			||||||
    on the ``test_function`` object. """
 | 
					    on the ``test_function`` object. """
 | 
				
			||||||
 | 
					    _config = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __getattr__(self, name):
 | 
					    def __getattr__(self, name):
 | 
				
			||||||
        if name[0] == "_":
 | 
					        if name[0] == "_":
 | 
				
			||||||
            raise AttributeError("Marker name must NOT start with underscore")
 | 
					            raise AttributeError("Marker name must NOT start with underscore")
 | 
				
			||||||
        if hasattr(self, '_config'):
 | 
					        if self._config is not None:
 | 
				
			||||||
            self._check(name)
 | 
					            self._check(name)
 | 
				
			||||||
        return MarkDecorator(Mark(name, (), {}))
 | 
					        return MarkDecorator(Mark(name, (), {}))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -263,6 +265,7 @@ class MarkGenerator(object):
 | 
				
			||||||
        if name not in self._markers:
 | 
					        if name not in self._markers:
 | 
				
			||||||
            raise AttributeError("%r not a registered marker" % (name,))
 | 
					            raise AttributeError("%r not a registered marker" % (name,))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def istestfunc(func):
 | 
					def istestfunc(func):
 | 
				
			||||||
    return hasattr(func, "__call__") and \
 | 
					    return hasattr(func, "__call__") and \
 | 
				
			||||||
        getattr(func, "__name__", "<lambda>") != "<lambda>"
 | 
					        getattr(func, "__name__", "<lambda>") != "<lambda>"
 | 
				
			||||||
| 
						 | 
					@ -384,3 +387,6 @@ class MarkInfo(object):
 | 
				
			||||||
    def __iter__(self):
 | 
					    def __iter__(self):
 | 
				
			||||||
        """ yield MarkInfo objects each relating to a marking-call. """
 | 
					        """ yield MarkInfo objects each relating to a marking-call. """
 | 
				
			||||||
        return imap(MarkInfo, self._marks)
 | 
					        return imap(MarkInfo, self._marks)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MARK_GEN = MarkGenerator()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,17 @@
 | 
				
			||||||
""" monkeypatching and mocking functionality.  """
 | 
					""" monkeypatching and mocking functionality.  """
 | 
				
			||||||
from __future__ import absolute_import, division, print_function
 | 
					from __future__ import absolute_import, division, print_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import os, sys
 | 
					import os
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from py.builtin import _basestring
 | 
					from py.builtin import _basestring
 | 
				
			||||||
 | 
					from _pytest.fixtures import fixture
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$")
 | 
					RE_IMPORT_ERROR_NAME = re.compile("^No module named (.*)$")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.fixture
 | 
					@fixture
 | 
				
			||||||
def monkeypatch():
 | 
					def monkeypatch():
 | 
				
			||||||
    """The returned ``monkeypatch`` fixture provides these
 | 
					    """The returned ``monkeypatch`` fixture provides these
 | 
				
			||||||
    helper methods to modify objects, dictionaries or os.environ::
 | 
					    helper methods to modify objects, dictionaries or os.environ::
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,8 +4,8 @@ from __future__ import absolute_import, division, print_function
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import pytest
 | 
					from _pytest import unittest, runner, python
 | 
				
			||||||
from _pytest import unittest
 | 
					from _pytest.config import hookimpl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_skip_exceptions():
 | 
					def get_skip_exceptions():
 | 
				
			||||||
| 
						 | 
					@ -20,19 +20,19 @@ def get_skip_exceptions():
 | 
				
			||||||
def pytest_runtest_makereport(item, call):
 | 
					def pytest_runtest_makereport(item, call):
 | 
				
			||||||
    if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()):
 | 
					    if call.excinfo and call.excinfo.errisinstance(get_skip_exceptions()):
 | 
				
			||||||
        # let's substitute the excinfo with a pytest.skip one
 | 
					        # let's substitute the excinfo with a pytest.skip one
 | 
				
			||||||
        call2 = call.__class__(lambda:
 | 
					        call2 = call.__class__(
 | 
				
			||||||
                    pytest.skip(str(call.excinfo.value)), call.when)
 | 
					            lambda: runner.skip(str(call.excinfo.value)), call.when)
 | 
				
			||||||
        call.excinfo = call2.excinfo
 | 
					        call.excinfo = call2.excinfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(trylast=True)
 | 
					@hookimpl(trylast=True)
 | 
				
			||||||
def pytest_runtest_setup(item):
 | 
					def pytest_runtest_setup(item):
 | 
				
			||||||
    if is_potential_nosetest(item):
 | 
					    if is_potential_nosetest(item):
 | 
				
			||||||
        if isinstance(item.parent, pytest.Generator):
 | 
					        if isinstance(item.parent, python.Generator):
 | 
				
			||||||
            gen = item.parent
 | 
					            gen = item.parent
 | 
				
			||||||
            if not hasattr(gen, '_nosegensetup'):
 | 
					            if not hasattr(gen, '_nosegensetup'):
 | 
				
			||||||
                call_optional(gen.obj, 'setup')
 | 
					                call_optional(gen.obj, 'setup')
 | 
				
			||||||
                if isinstance(gen.parent, pytest.Instance):
 | 
					                if isinstance(gen.parent, python.Instance):
 | 
				
			||||||
                    call_optional(gen.parent.obj, 'setup')
 | 
					                    call_optional(gen.parent.obj, 'setup')
 | 
				
			||||||
                gen._nosegensetup = True
 | 
					                gen._nosegensetup = True
 | 
				
			||||||
        if not call_optional(item.obj, 'setup'):
 | 
					        if not call_optional(item.obj, 'setup'):
 | 
				
			||||||
| 
						 | 
					@ -51,14 +51,14 @@ def teardown_nose(item):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_make_collect_report(collector):
 | 
					def pytest_make_collect_report(collector):
 | 
				
			||||||
    if isinstance(collector, pytest.Generator):
 | 
					    if isinstance(collector, python.Generator):
 | 
				
			||||||
        call_optional(collector.obj, 'setup')
 | 
					        call_optional(collector.obj, 'setup')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def is_potential_nosetest(item):
 | 
					def is_potential_nosetest(item):
 | 
				
			||||||
    # extra check needed since we do not do nose style setup/teardown
 | 
					    # extra check needed since we do not do nose style setup/teardown
 | 
				
			||||||
    # on direct unittest style classes
 | 
					    # on direct unittest style classes
 | 
				
			||||||
    return isinstance(item, pytest.Function) and \
 | 
					    return isinstance(item, python.Function) and \
 | 
				
			||||||
        not isinstance(item, unittest.TestCaseFunction)
 | 
					        not isinstance(item, unittest.TestCaseFunction)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,19 +9,20 @@ import math
 | 
				
			||||||
from itertools import count
 | 
					from itertools import count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
from _pytest.mark import MarkerError
 | 
					from _pytest.mark import MarkerError
 | 
				
			||||||
 | 
					from _pytest.config import hookimpl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import _pytest
 | 
					import _pytest
 | 
				
			||||||
import _pytest._pluggy as pluggy
 | 
					import _pytest._pluggy as pluggy
 | 
				
			||||||
from _pytest import fixtures
 | 
					from _pytest import fixtures
 | 
				
			||||||
 | 
					from _pytest import main
 | 
				
			||||||
from _pytest.compat import (
 | 
					from _pytest.compat import (
 | 
				
			||||||
    isclass, isfunction, is_generator, _escape_strings,
 | 
					    isclass, isfunction, is_generator, _escape_strings,
 | 
				
			||||||
    REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
 | 
					    REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
 | 
				
			||||||
    get_real_func, getfslineno, safe_getattr,
 | 
					    get_real_func, getfslineno, safe_getattr,
 | 
				
			||||||
    getlocation, enum,
 | 
					    getlocation, enum,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from _pytest.runner import fail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cutdir1 = py.path.local(pluggy.__file__.rstrip("oc"))
 | 
					cutdir1 = py.path.local(pluggy.__file__.rstrip("oc"))
 | 
				
			||||||
cutdir2 = py.path.local(_pytest.__file__).dirpath()
 | 
					cutdir2 = py.path.local(_pytest.__file__).dirpath()
 | 
				
			||||||
| 
						 | 
					@ -49,7 +50,7 @@ def filter_traceback(entry):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pyobj_property(name):
 | 
					def pyobj_property(name):
 | 
				
			||||||
    def get(self):
 | 
					    def get(self):
 | 
				
			||||||
        node = self.getparent(getattr(pytest, name))
 | 
					        node = self.getparent(getattr(__import__('pytest'), name))
 | 
				
			||||||
        if node is not None:
 | 
					        if node is not None:
 | 
				
			||||||
            return node.obj
 | 
					            return node.obj
 | 
				
			||||||
    doc = "python %s object this node was collected from (can be None)." % (
 | 
					    doc = "python %s object this node was collected from (can be None)." % (
 | 
				
			||||||
| 
						 | 
					@ -126,23 +127,8 @@ def pytest_configure(config):
 | 
				
			||||||
        "all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures "
 | 
					        "all of the specified fixtures. see http://pytest.org/latest/fixture.html#usefixtures "
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(trylast=True)
 | 
					 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    raises.Exception = pytest.fail.Exception
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        'raises': raises,
 | 
					 | 
				
			||||||
        'approx': approx,
 | 
					 | 
				
			||||||
        'collect': {
 | 
					 | 
				
			||||||
            'Module': Module,
 | 
					 | 
				
			||||||
            'Class': Class,
 | 
					 | 
				
			||||||
            'Instance': Instance,
 | 
					 | 
				
			||||||
            'Function': Function,
 | 
					 | 
				
			||||||
            'Generator': Generator,
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@hookimpl(trylast=True)
 | 
				
			||||||
@pytest.hookimpl(trylast=True)
 | 
					 | 
				
			||||||
def pytest_pyfunc_call(pyfuncitem):
 | 
					def pytest_pyfunc_call(pyfuncitem):
 | 
				
			||||||
    testfunction = pyfuncitem.obj
 | 
					    testfunction = pyfuncitem.obj
 | 
				
			||||||
    if pyfuncitem._isyieldedfunction():
 | 
					    if pyfuncitem._isyieldedfunction():
 | 
				
			||||||
| 
						 | 
					@ -155,6 +141,7 @@ def pytest_pyfunc_call(pyfuncitem):
 | 
				
			||||||
        testfunction(**testargs)
 | 
					        testfunction(**testargs)
 | 
				
			||||||
    return True
 | 
					    return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_collect_file(path, parent):
 | 
					def pytest_collect_file(path, parent):
 | 
				
			||||||
    ext = path.ext
 | 
					    ext = path.ext
 | 
				
			||||||
    if ext == ".py":
 | 
					    if ext == ".py":
 | 
				
			||||||
| 
						 | 
					@ -170,7 +157,7 @@ def pytest_collect_file(path, parent):
 | 
				
			||||||
def pytest_pycollect_makemodule(path, parent):
 | 
					def pytest_pycollect_makemodule(path, parent):
 | 
				
			||||||
    return Module(path, parent)
 | 
					    return Module(path, parent)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(hookwrapper=True)
 | 
					@hookimpl(hookwrapper=True)
 | 
				
			||||||
def pytest_pycollect_makeitem(collector, name, obj):
 | 
					def pytest_pycollect_makeitem(collector, name, obj):
 | 
				
			||||||
    outcome = yield
 | 
					    outcome = yield
 | 
				
			||||||
    res = outcome.get_result()
 | 
					    res = outcome.get_result()
 | 
				
			||||||
| 
						 | 
					@ -266,7 +253,7 @@ class PyobjMixin(PyobjContext):
 | 
				
			||||||
        assert isinstance(lineno, int)
 | 
					        assert isinstance(lineno, int)
 | 
				
			||||||
        return fspath, lineno, modpath
 | 
					        return fspath, lineno, modpath
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PyCollector(PyobjMixin, pytest.Collector):
 | 
					class PyCollector(PyobjMixin, main.Collector):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def funcnamefilter(self, name):
 | 
					    def funcnamefilter(self, name):
 | 
				
			||||||
        return self._matches_prefix_or_glob_option('python_functions', name)
 | 
					        return self._matches_prefix_or_glob_option('python_functions', name)
 | 
				
			||||||
| 
						 | 
					@ -403,7 +390,8 @@ def transfer_markers(funcobj, cls, mod):
 | 
				
			||||||
            if not _marked(funcobj, pytestmark):
 | 
					            if not _marked(funcobj, pytestmark):
 | 
				
			||||||
                pytestmark(funcobj)
 | 
					                pytestmark(funcobj)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Module(pytest.File, PyCollector):
 | 
					
 | 
				
			||||||
 | 
					class Module(main.File, PyCollector):
 | 
				
			||||||
    """ Collector for test classes and functions. """
 | 
					    """ Collector for test classes and functions. """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _getobj(self):
 | 
					    def _getobj(self):
 | 
				
			||||||
| 
						 | 
					@ -590,7 +578,7 @@ class FunctionMixin(PyobjMixin):
 | 
				
			||||||
                        entry.set_repr_style('short')
 | 
					                        entry.set_repr_style('short')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _repr_failure_py(self, excinfo, style="long"):
 | 
					    def _repr_failure_py(self, excinfo, style="long"):
 | 
				
			||||||
        if excinfo.errisinstance(pytest.fail.Exception):
 | 
					        if excinfo.errisinstance(fail.Exception):
 | 
				
			||||||
            if not excinfo.value.pytrace:
 | 
					            if not excinfo.value.pytrace:
 | 
				
			||||||
                return py._builtin._totext(excinfo.value)
 | 
					                return py._builtin._totext(excinfo.value)
 | 
				
			||||||
        return super(FunctionMixin, self)._repr_failure_py(excinfo,
 | 
					        return super(FunctionMixin, self)._repr_failure_py(excinfo,
 | 
				
			||||||
| 
						 | 
					@ -788,7 +776,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
 | 
				
			||||||
            to set a dynamic scope using test context or configuration.
 | 
					            to set a dynamic scope using test context or configuration.
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
        from _pytest.fixtures import scope2index
 | 
					        from _pytest.fixtures import scope2index
 | 
				
			||||||
        from _pytest.mark import ParameterSet
 | 
					        from _pytest.mark import MARK_GEN, ParameterSet
 | 
				
			||||||
        from py.io import saferepr
 | 
					        from py.io import saferepr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not isinstance(argnames, (tuple, list)):
 | 
					        if not isinstance(argnames, (tuple, list)):
 | 
				
			||||||
| 
						 | 
					@ -801,12 +789,11 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
 | 
				
			||||||
            for x in argvalues]
 | 
					            for x in argvalues]
 | 
				
			||||||
        del argvalues
 | 
					        del argvalues
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if not parameters:
 | 
					        if not parameters:
 | 
				
			||||||
            fs, lineno = getfslineno(self.function)
 | 
					            fs, lineno = getfslineno(self.function)
 | 
				
			||||||
            reason = "got empty parameter set %r, function %s at %s:%d" % (
 | 
					            reason = "got empty parameter set %r, function %s at %s:%d" % (
 | 
				
			||||||
                    argnames, self.function.__name__, fs, lineno)
 | 
					                    argnames, self.function.__name__, fs, lineno)
 | 
				
			||||||
            mark = pytest.mark.skip(reason=reason)
 | 
					            mark = MARK_GEN.skip(reason=reason)
 | 
				
			||||||
            parameters.append(ParameterSet(
 | 
					            parameters.append(ParameterSet(
 | 
				
			||||||
                values=(NOTSET,) * len(argnames),
 | 
					                values=(NOTSET,) * len(argnames),
 | 
				
			||||||
                marks=[mark],
 | 
					                marks=[mark],
 | 
				
			||||||
| 
						 | 
					@ -883,7 +870,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
 | 
				
			||||||
        if funcargs is not None:
 | 
					        if funcargs is not None:
 | 
				
			||||||
            for name in funcargs:
 | 
					            for name in funcargs:
 | 
				
			||||||
                if name not in self.fixturenames:
 | 
					                if name not in self.fixturenames:
 | 
				
			||||||
                    pytest.fail("funcarg %r not used in this function." % name)
 | 
					                    fail("funcarg %r not used in this function." % name)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            funcargs = {}
 | 
					            funcargs = {}
 | 
				
			||||||
        if id is None:
 | 
					        if id is None:
 | 
				
			||||||
| 
						 | 
					@ -958,6 +945,7 @@ def _idval(val, argname, idx, idfn, config=None):
 | 
				
			||||||
        return val.__name__
 | 
					        return val.__name__
 | 
				
			||||||
    return str(argname)+str(idx)
 | 
					    return str(argname)+str(idx)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _idvalset(idx, parameterset, argnames, idfn, ids, config=None):
 | 
					def _idvalset(idx, parameterset, argnames, idfn, ids, config=None):
 | 
				
			||||||
    if parameterset.id is not None:
 | 
					    if parameterset.id is not None:
 | 
				
			||||||
        return parameterset.id
 | 
					        return parameterset.id
 | 
				
			||||||
| 
						 | 
					@ -968,6 +956,7 @@ def _idvalset(idx, parameterset, argnames, idfn, ids, config=None):
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        return _escape_strings(ids[idx])
 | 
					        return _escape_strings(ids[idx])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def idmaker(argnames, parametersets, idfn=None, ids=None, config=None):
 | 
					def idmaker(argnames, parametersets, idfn=None, ids=None, config=None):
 | 
				
			||||||
    ids = [_idvalset(valindex, parameterset, argnames, idfn, ids, config)
 | 
					    ids = [_idvalset(valindex, parameterset, argnames, idfn, ids, config)
 | 
				
			||||||
           for valindex, parameterset in enumerate(parametersets)]
 | 
					           for valindex, parameterset in enumerate(parametersets)]
 | 
				
			||||||
| 
						 | 
					@ -1046,6 +1035,7 @@ def showfixtures(config):
 | 
				
			||||||
    from _pytest.main import wrap_session
 | 
					    from _pytest.main import wrap_session
 | 
				
			||||||
    return wrap_session(config, _showfixtures_main)
 | 
					    return wrap_session(config, _showfixtures_main)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def _showfixtures_main(config, session):
 | 
					def _showfixtures_main(config, session):
 | 
				
			||||||
    import _pytest.config
 | 
					    import _pytest.config
 | 
				
			||||||
    session.perform_collect()
 | 
					    session.perform_collect()
 | 
				
			||||||
| 
						 | 
					@ -1234,7 +1224,11 @@ def raises(expected_exception, *args, **kwargs):
 | 
				
			||||||
            func(*args[1:], **kwargs)
 | 
					            func(*args[1:], **kwargs)
 | 
				
			||||||
        except expected_exception:
 | 
					        except expected_exception:
 | 
				
			||||||
            return _pytest._code.ExceptionInfo()
 | 
					            return _pytest._code.ExceptionInfo()
 | 
				
			||||||
    pytest.fail(message)
 | 
					    fail(message)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					raises.Exception = fail.Exception
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RaisesContext(object):
 | 
					class RaisesContext(object):
 | 
				
			||||||
    def __init__(self, expected_exception, message, match_expr):
 | 
					    def __init__(self, expected_exception, message, match_expr):
 | 
				
			||||||
| 
						 | 
					@ -1250,7 +1244,7 @@ class RaisesContext(object):
 | 
				
			||||||
    def __exit__(self, *tp):
 | 
					    def __exit__(self, *tp):
 | 
				
			||||||
        __tracebackhide__ = True
 | 
					        __tracebackhide__ = True
 | 
				
			||||||
        if tp[0] is None:
 | 
					        if tp[0] is None:
 | 
				
			||||||
            pytest.fail(self.message)
 | 
					            fail(self.message)
 | 
				
			||||||
        if sys.version_info < (2, 7):
 | 
					        if sys.version_info < (2, 7):
 | 
				
			||||||
            # py26: on __exit__() exc_value often does not contain the
 | 
					            # py26: on __exit__() exc_value often does not contain the
 | 
				
			||||||
            # exception value.
 | 
					            # exception value.
 | 
				
			||||||
| 
						 | 
					@ -1521,7 +1515,7 @@ class ApproxNonIterable(object):
 | 
				
			||||||
#  the basic pytest Function item
 | 
					#  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
 | 
					    """ a Function Item is responsible for setting up and executing a
 | 
				
			||||||
    Python test function.
 | 
					    Python test function.
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,10 +7,10 @@ import _pytest._code
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import warnings
 | 
					import warnings
 | 
				
			||||||
import pytest
 | 
					from _pytest.fixtures import yield_fixture
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.yield_fixture
 | 
					@yield_fixture
 | 
				
			||||||
def recwarn():
 | 
					def recwarn():
 | 
				
			||||||
    """Return a WarningsRecorder instance that provides these methods:
 | 
					    """Return a WarningsRecorder instance that provides these methods:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,11 +26,6 @@ def recwarn():
 | 
				
			||||||
        yield wrec
 | 
					        yield wrec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    return {'deprecated_call': deprecated_call,
 | 
					 | 
				
			||||||
            'warns': warns}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def deprecated_call(func=None, *args, **kwargs):
 | 
					def deprecated_call(func=None, *args, **kwargs):
 | 
				
			||||||
    """ assert that calling ``func(*args, **kwargs)`` triggers a
 | 
					    """ assert that calling ``func(*args, **kwargs)`` triggers a
 | 
				
			||||||
    ``DeprecationWarning`` or ``PendingDeprecationWarning``.
 | 
					    ``DeprecationWarning`` or ``PendingDeprecationWarning``.
 | 
				
			||||||
| 
						 | 
					@ -195,7 +190,8 @@ class WarningsChecker(WarningsRecorder):
 | 
				
			||||||
                if not any(issubclass(r.category, self.expected_warning)
 | 
					                if not any(issubclass(r.category, self.expected_warning)
 | 
				
			||||||
                           for r in self):
 | 
					                           for r in self):
 | 
				
			||||||
                    __tracebackhide__ = True
 | 
					                    __tracebackhide__ = True
 | 
				
			||||||
                    pytest.fail("DID NOT WARN. No warnings of type {0} was emitted. "
 | 
					                    from _pytest.runner import fail
 | 
				
			||||||
                                "The list of emitted warnings is: {1}.".format(
 | 
					                    fail("DID NOT WARN. No warnings of type {0} was emitted. "
 | 
				
			||||||
                                    self.expected_warning,
 | 
					                         "The list of emitted warnings is: {1}.".format(
 | 
				
			||||||
                                    [each.message for each in self]))
 | 
					                            self.expected_warning,
 | 
				
			||||||
 | 
					                            [each.message for each in self]))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,17 +6,9 @@ import sys
 | 
				
			||||||
from time import time
 | 
					from time import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
from _pytest._code.code import TerminalRepr, ExceptionInfo
 | 
					from _pytest._code.code import TerminalRepr, ExceptionInfo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					 | 
				
			||||||
    return {
 | 
					 | 
				
			||||||
        'fail'         : fail,
 | 
					 | 
				
			||||||
        'skip'         : skip,
 | 
					 | 
				
			||||||
        'importorskip' : importorskip,
 | 
					 | 
				
			||||||
        'exit'         : exit,
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# pytest plugin hooks
 | 
					# pytest plugin hooks
 | 
				
			||||||
| 
						 | 
					@ -264,7 +256,7 @@ def pytest_runtest_makereport(item, call):
 | 
				
			||||||
        if not isinstance(excinfo, ExceptionInfo):
 | 
					        if not isinstance(excinfo, ExceptionInfo):
 | 
				
			||||||
            outcome = "failed"
 | 
					            outcome = "failed"
 | 
				
			||||||
            longrepr = excinfo
 | 
					            longrepr = excinfo
 | 
				
			||||||
        elif excinfo.errisinstance(pytest.skip.Exception):
 | 
					        elif excinfo.errisinstance(skip.Exception):
 | 
				
			||||||
            outcome = "skipped"
 | 
					            outcome = "skipped"
 | 
				
			||||||
            r = excinfo._getreprcrash()
 | 
					            r = excinfo._getreprcrash()
 | 
				
			||||||
            longrepr = (str(r.path), r.lineno, r.message)
 | 
					            longrepr = (str(r.path), r.lineno, r.message)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,9 +6,9 @@ import sys
 | 
				
			||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import py
 | 
					import py
 | 
				
			||||||
import pytest
 | 
					from _pytest.config import hookimpl
 | 
				
			||||||
from _pytest.mark import MarkInfo, MarkDecorator
 | 
					from _pytest.mark import MarkInfo, MarkDecorator
 | 
				
			||||||
 | 
					from _pytest.runner import fail, skip
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_addoption(parser):
 | 
					def pytest_addoption(parser):
 | 
				
			||||||
    group = parser.getgroup("general")
 | 
					    group = parser.getgroup("general")
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,8 @@ def pytest_addoption(parser):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_configure(config):
 | 
					def pytest_configure(config):
 | 
				
			||||||
    if config.option.runxfail:
 | 
					    if config.option.runxfail:
 | 
				
			||||||
 | 
					        # yay a hack
 | 
				
			||||||
 | 
					        import pytest
 | 
				
			||||||
        old = pytest.xfail
 | 
					        old = pytest.xfail
 | 
				
			||||||
        config._cleanup.append(lambda: setattr(pytest, "xfail", old))
 | 
					        config._cleanup.append(lambda: setattr(pytest, "xfail", old))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,11 +59,7 @@ def pytest_configure(config):
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_namespace():
 | 
					class XFailed(fail.Exception):
 | 
				
			||||||
    return dict(xfail=xfail)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class XFailed(pytest.fail.Exception):
 | 
					 | 
				
			||||||
    """ raised from an explicit call to pytest.xfail() """
 | 
					    """ raised from an explicit call to pytest.xfail() """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,15 +100,15 @@ class MarkEvaluator(object):
 | 
				
			||||||
        except Exception:
 | 
					        except Exception:
 | 
				
			||||||
            self.exc = sys.exc_info()
 | 
					            self.exc = sys.exc_info()
 | 
				
			||||||
            if isinstance(self.exc[1], SyntaxError):
 | 
					            if isinstance(self.exc[1], SyntaxError):
 | 
				
			||||||
                msg = [" " * (self.exc[1].offset + 4) + "^",]
 | 
					                msg = [" " * (self.exc[1].offset + 4) + "^", ]
 | 
				
			||||||
                msg.append("SyntaxError: invalid syntax")
 | 
					                msg.append("SyntaxError: invalid syntax")
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                msg = traceback.format_exception_only(*self.exc[:2])
 | 
					                msg = traceback.format_exception_only(*self.exc[:2])
 | 
				
			||||||
            pytest.fail("Error evaluating %r expression\n"
 | 
					            fail("Error evaluating %r expression\n"
 | 
				
			||||||
                        "    %s\n"
 | 
					                 "    %s\n"
 | 
				
			||||||
                        "%s"
 | 
					                 "%s"
 | 
				
			||||||
                        %(self.name, self.expr, "\n".join(msg)),
 | 
					                 % (self.name, self.expr, "\n".join(msg)),
 | 
				
			||||||
                        pytrace=False)
 | 
					                 pytrace=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _getglobals(self):
 | 
					    def _getglobals(self):
 | 
				
			||||||
        d = {'os': os, 'sys': sys, 'config': self.item.config}
 | 
					        d = {'os': os, 'sys': sys, 'config': self.item.config}
 | 
				
			||||||
| 
						 | 
					@ -142,7 +140,7 @@ class MarkEvaluator(object):
 | 
				
			||||||
                                # XXX better be checked at collection time
 | 
					                                # XXX better be checked at collection time
 | 
				
			||||||
                                msg = "you need to specify reason=STRING " \
 | 
					                                msg = "you need to specify reason=STRING " \
 | 
				
			||||||
                                      "when using booleans as conditions."
 | 
					                                      "when using booleans as conditions."
 | 
				
			||||||
                                pytest.fail(msg)
 | 
					                                fail(msg)
 | 
				
			||||||
                            result = bool(expr)
 | 
					                            result = bool(expr)
 | 
				
			||||||
                        if result:
 | 
					                        if result:
 | 
				
			||||||
                            self.result = True
 | 
					                            self.result = True
 | 
				
			||||||
| 
						 | 
					@ -166,7 +164,7 @@ class MarkEvaluator(object):
 | 
				
			||||||
        return expl
 | 
					        return expl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(tryfirst=True)
 | 
					@hookimpl(tryfirst=True)
 | 
				
			||||||
def pytest_runtest_setup(item):
 | 
					def pytest_runtest_setup(item):
 | 
				
			||||||
    # Check if skip or skipif are specified as pytest marks
 | 
					    # Check if skip or skipif are specified as pytest marks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -175,23 +173,23 @@ def pytest_runtest_setup(item):
 | 
				
			||||||
        eval_skipif = MarkEvaluator(item, 'skipif')
 | 
					        eval_skipif = MarkEvaluator(item, 'skipif')
 | 
				
			||||||
        if eval_skipif.istrue():
 | 
					        if eval_skipif.istrue():
 | 
				
			||||||
            item._evalskip = eval_skipif
 | 
					            item._evalskip = eval_skipif
 | 
				
			||||||
            pytest.skip(eval_skipif.getexplanation())
 | 
					            skip(eval_skipif.getexplanation())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    skip_info = item.keywords.get('skip')
 | 
					    skip_info = item.keywords.get('skip')
 | 
				
			||||||
    if isinstance(skip_info, (MarkInfo, MarkDecorator)):
 | 
					    if isinstance(skip_info, (MarkInfo, MarkDecorator)):
 | 
				
			||||||
        item._evalskip = True
 | 
					        item._evalskip = True
 | 
				
			||||||
        if 'reason' in skip_info.kwargs:
 | 
					        if 'reason' in skip_info.kwargs:
 | 
				
			||||||
            pytest.skip(skip_info.kwargs['reason'])
 | 
					            skip(skip_info.kwargs['reason'])
 | 
				
			||||||
        elif skip_info.args:
 | 
					        elif skip_info.args:
 | 
				
			||||||
            pytest.skip(skip_info.args[0])
 | 
					            skip(skip_info.args[0])
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            pytest.skip("unconditional skip")
 | 
					            skip("unconditional skip")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    item._evalxfail = MarkEvaluator(item, 'xfail')
 | 
					    item._evalxfail = MarkEvaluator(item, 'xfail')
 | 
				
			||||||
    check_xfail_no_run(item)
 | 
					    check_xfail_no_run(item)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.mark.hookwrapper
 | 
					@hookimpl(hookwrapper=True)
 | 
				
			||||||
def pytest_pyfunc_call(pyfuncitem):
 | 
					def pytest_pyfunc_call(pyfuncitem):
 | 
				
			||||||
    check_xfail_no_run(pyfuncitem)
 | 
					    check_xfail_no_run(pyfuncitem)
 | 
				
			||||||
    outcome = yield
 | 
					    outcome = yield
 | 
				
			||||||
| 
						 | 
					@ -206,7 +204,7 @@ def check_xfail_no_run(item):
 | 
				
			||||||
        evalxfail = item._evalxfail
 | 
					        evalxfail = item._evalxfail
 | 
				
			||||||
        if evalxfail.istrue():
 | 
					        if evalxfail.istrue():
 | 
				
			||||||
            if not evalxfail.get('run', True):
 | 
					            if not evalxfail.get('run', True):
 | 
				
			||||||
                pytest.xfail("[NOTRUN] " + evalxfail.getexplanation())
 | 
					                xfail("[NOTRUN] " + evalxfail.getexplanation())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def check_strict_xfail(pyfuncitem):
 | 
					def check_strict_xfail(pyfuncitem):
 | 
				
			||||||
| 
						 | 
					@ -218,10 +216,10 @@ def check_strict_xfail(pyfuncitem):
 | 
				
			||||||
        if is_strict_xfail:
 | 
					        if is_strict_xfail:
 | 
				
			||||||
            del pyfuncitem._evalxfail
 | 
					            del pyfuncitem._evalxfail
 | 
				
			||||||
            explanation = evalxfail.getexplanation()
 | 
					            explanation = evalxfail.getexplanation()
 | 
				
			||||||
            pytest.fail('[XPASS(strict)] ' + explanation, pytrace=False)
 | 
					            fail('[XPASS(strict)] ' + explanation, pytrace=False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(hookwrapper=True)
 | 
					@hookimpl(hookwrapper=True)
 | 
				
			||||||
def pytest_runtest_makereport(item, call):
 | 
					def pytest_runtest_makereport(item, call):
 | 
				
			||||||
    outcome = yield
 | 
					    outcome = yield
 | 
				
			||||||
    rep = outcome.get_result()
 | 
					    rep = outcome.get_result()
 | 
				
			||||||
| 
						 | 
					@ -241,7 +239,7 @@ def pytest_runtest_makereport(item, call):
 | 
				
			||||||
            rep.wasxfail = rep.longrepr
 | 
					            rep.wasxfail = rep.longrepr
 | 
				
			||||||
    elif item.config.option.runxfail:
 | 
					    elif item.config.option.runxfail:
 | 
				
			||||||
        pass   # don't interefere
 | 
					        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.wasxfail = "reason: " + call.excinfo.value.msg
 | 
				
			||||||
        rep.outcome = "skipped"
 | 
					        rep.outcome = "skipped"
 | 
				
			||||||
    elif evalxfail and not rep.skipped and evalxfail.wasvalid() and \
 | 
					    elif evalxfail and not rep.skipped and evalxfail.wasvalid() and \
 | 
				
			||||||
| 
						 | 
					@ -309,12 +307,14 @@ def pytest_terminal_summary(terminalreporter):
 | 
				
			||||||
        for line in lines:
 | 
					        for line in lines:
 | 
				
			||||||
            tr._tw.line(line)
 | 
					            tr._tw.line(line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def show_simple(terminalreporter, lines, stat, format):
 | 
					def show_simple(terminalreporter, lines, stat, format):
 | 
				
			||||||
    failed = terminalreporter.stats.get(stat)
 | 
					    failed = terminalreporter.stats.get(stat)
 | 
				
			||||||
    if failed:
 | 
					    if failed:
 | 
				
			||||||
        for rep in failed:
 | 
					        for rep in failed:
 | 
				
			||||||
            pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
 | 
					            pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
 | 
				
			||||||
            lines.append(format %(pos,))
 | 
					            lines.append(format % (pos,))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def show_xfailed(terminalreporter, lines):
 | 
					def show_xfailed(terminalreporter, lines):
 | 
				
			||||||
    xfailed = terminalreporter.stats.get("xfailed")
 | 
					    xfailed = terminalreporter.stats.get("xfailed")
 | 
				
			||||||
| 
						 | 
					@ -326,13 +326,15 @@ def show_xfailed(terminalreporter, lines):
 | 
				
			||||||
            if reason:
 | 
					            if reason:
 | 
				
			||||||
                lines.append("  " + str(reason))
 | 
					                lines.append("  " + str(reason))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def show_xpassed(terminalreporter, lines):
 | 
					def show_xpassed(terminalreporter, lines):
 | 
				
			||||||
    xpassed = terminalreporter.stats.get("xpassed")
 | 
					    xpassed = terminalreporter.stats.get("xpassed")
 | 
				
			||||||
    if xpassed:
 | 
					    if xpassed:
 | 
				
			||||||
        for rep in xpassed:
 | 
					        for rep in xpassed:
 | 
				
			||||||
            pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
 | 
					            pos = terminalreporter.config.cwd_relative_nodeid(rep.nodeid)
 | 
				
			||||||
            reason = rep.wasxfail
 | 
					            reason = rep.wasxfail
 | 
				
			||||||
            lines.append("XPASS %s %s" %(pos, reason))
 | 
					            lines.append("XPASS %s %s" % (pos, reason))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def cached_eval(config, expr, d):
 | 
					def cached_eval(config, expr, d):
 | 
				
			||||||
    if not hasattr(config, '_evalcache'):
 | 
					    if not hasattr(config, '_evalcache'):
 | 
				
			||||||
| 
						 | 
					@ -357,6 +359,7 @@ def folded_skips(skipped):
 | 
				
			||||||
        l.append((len(events),) + key)
 | 
					        l.append((len(events),) + key)
 | 
				
			||||||
    return l
 | 
					    return l
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def show_skipped(terminalreporter, lines):
 | 
					def show_skipped(terminalreporter, lines):
 | 
				
			||||||
    tr = terminalreporter
 | 
					    tr = terminalreporter
 | 
				
			||||||
    skipped = tr.stats.get('skipped', [])
 | 
					    skipped = tr.stats.get('skipped', [])
 | 
				
			||||||
| 
						 | 
					@ -372,5 +375,6 @@ def show_skipped(terminalreporter, lines):
 | 
				
			||||||
            for num, fspath, lineno, reason in fskips:
 | 
					            for num, fspath, lineno, reason in fskips:
 | 
				
			||||||
                if reason.startswith("Skipped: "):
 | 
					                if reason.startswith("Skipped: "):
 | 
				
			||||||
                    reason = reason[9:]
 | 
					                    reason = reason[9:]
 | 
				
			||||||
                lines.append("SKIP [%d] %s:%d: %s" %
 | 
					                lines.append(
 | 
				
			||||||
 | 
					                    "SKIP [%d] %s:%d: %s" %
 | 
				
			||||||
                    (num, fspath, lineno, reason))
 | 
					                    (num, fspath, lineno, reason))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,11 +4,12 @@ from __future__ import absolute_import, division, print_function
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import traceback
 | 
					import traceback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					 | 
				
			||||||
# for transferring markers
 | 
					# for transferring markers
 | 
				
			||||||
import _pytest._code
 | 
					import _pytest._code
 | 
				
			||||||
from _pytest.python import transfer_markers
 | 
					from _pytest.config import hookimpl
 | 
				
			||||||
from _pytest.skipping import MarkEvaluator
 | 
					from _pytest.runner import fail, skip
 | 
				
			||||||
 | 
					from _pytest.python import transfer_markers, Class, Module, Function
 | 
				
			||||||
 | 
					from _pytest.skipping import MarkEvaluator, xfail
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def pytest_pycollect_makeitem(collector, name, obj):
 | 
					def pytest_pycollect_makeitem(collector, name, obj):
 | 
				
			||||||
| 
						 | 
					@ -22,7 +23,7 @@ def pytest_pycollect_makeitem(collector, name, obj):
 | 
				
			||||||
    return UnitTestCase(name, parent=collector)
 | 
					    return UnitTestCase(name, parent=collector)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UnitTestCase(pytest.Class):
 | 
					class UnitTestCase(Class):
 | 
				
			||||||
    # marker for fixturemanger.getfixtureinfo()
 | 
					    # marker for fixturemanger.getfixtureinfo()
 | 
				
			||||||
    # to declare that our children do not support funcargs
 | 
					    # to declare that our children do not support funcargs
 | 
				
			||||||
    nofuncargs = True
 | 
					    nofuncargs = True
 | 
				
			||||||
| 
						 | 
					@ -46,7 +47,7 @@ class UnitTestCase(pytest.Class):
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        self.session._fixturemanager.parsefactories(self, unittest=True)
 | 
					        self.session._fixturemanager.parsefactories(self, unittest=True)
 | 
				
			||||||
        loader = TestLoader()
 | 
					        loader = TestLoader()
 | 
				
			||||||
        module = self.getparent(pytest.Module).obj
 | 
					        module = self.getparent(Module).obj
 | 
				
			||||||
        foundsomething = False
 | 
					        foundsomething = False
 | 
				
			||||||
        for name in loader.getTestCaseNames(self.obj):
 | 
					        for name in loader.getTestCaseNames(self.obj):
 | 
				
			||||||
            x = getattr(self.obj, name)
 | 
					            x = getattr(self.obj, name)
 | 
				
			||||||
| 
						 | 
					@ -65,7 +66,7 @@ class UnitTestCase(pytest.Class):
 | 
				
			||||||
                    yield TestCaseFunction('runTest', parent=self)
 | 
					                    yield TestCaseFunction('runTest', parent=self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestCaseFunction(pytest.Function):
 | 
					class TestCaseFunction(Function):
 | 
				
			||||||
    _excinfo = None
 | 
					    _excinfo = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setup(self):
 | 
					    def setup(self):
 | 
				
			||||||
| 
						 | 
					@ -110,36 +111,37 @@ class TestCaseFunction(pytest.Function):
 | 
				
			||||||
                try:
 | 
					                try:
 | 
				
			||||||
                    l = traceback.format_exception(*rawexcinfo)
 | 
					                    l = traceback.format_exception(*rawexcinfo)
 | 
				
			||||||
                    l.insert(0, "NOTE: Incompatible Exception Representation, "
 | 
					                    l.insert(0, "NOTE: Incompatible Exception Representation, "
 | 
				
			||||||
                        "displaying natively:\n\n")
 | 
					                                "displaying natively:\n\n")
 | 
				
			||||||
                    pytest.fail("".join(l), pytrace=False)
 | 
					                    fail("".join(l), pytrace=False)
 | 
				
			||||||
                except (pytest.fail.Exception, KeyboardInterrupt):
 | 
					                except (fail.Exception, KeyboardInterrupt):
 | 
				
			||||||
                    raise
 | 
					                    raise
 | 
				
			||||||
                except:
 | 
					                except:
 | 
				
			||||||
                    pytest.fail("ERROR: Unknown Incompatible Exception "
 | 
					                    fail("ERROR: Unknown Incompatible Exception "
 | 
				
			||||||
                        "representation:\n%r" %(rawexcinfo,), pytrace=False)
 | 
					                         "representation:\n%r" % (rawexcinfo,), pytrace=False)
 | 
				
			||||||
            except KeyboardInterrupt:
 | 
					            except KeyboardInterrupt:
 | 
				
			||||||
                raise
 | 
					                raise
 | 
				
			||||||
            except pytest.fail.Exception:
 | 
					            except fail.Exception:
 | 
				
			||||||
                excinfo = _pytest._code.ExceptionInfo()
 | 
					                excinfo = _pytest._code.ExceptionInfo()
 | 
				
			||||||
        self.__dict__.setdefault('_excinfo', []).append(excinfo)
 | 
					        self.__dict__.setdefault('_excinfo', []).append(excinfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def addError(self, testcase, rawexcinfo):
 | 
					    def addError(self, testcase, rawexcinfo):
 | 
				
			||||||
        self._addexcinfo(rawexcinfo)
 | 
					        self._addexcinfo(rawexcinfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def addFailure(self, testcase, rawexcinfo):
 | 
					    def addFailure(self, testcase, rawexcinfo):
 | 
				
			||||||
        self._addexcinfo(rawexcinfo)
 | 
					        self._addexcinfo(rawexcinfo)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def addSkip(self, testcase, reason):
 | 
					    def addSkip(self, testcase, reason):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            pytest.skip(reason)
 | 
					            skip(reason)
 | 
				
			||||||
        except pytest.skip.Exception:
 | 
					        except skip.Exception:
 | 
				
			||||||
            self._evalskip = MarkEvaluator(self, 'SkipTest')
 | 
					            self._evalskip = MarkEvaluator(self, 'SkipTest')
 | 
				
			||||||
            self._evalskip.result = True
 | 
					            self._evalskip.result = True
 | 
				
			||||||
            self._addexcinfo(sys.exc_info())
 | 
					            self._addexcinfo(sys.exc_info())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def addExpectedFailure(self, testcase, rawexcinfo, reason=""):
 | 
					    def addExpectedFailure(self, testcase, rawexcinfo, reason=""):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            pytest.xfail(str(reason))
 | 
					            xfail(str(reason))
 | 
				
			||||||
        except pytest.xfail.Exception:
 | 
					        except xfail.Exception:
 | 
				
			||||||
            self._addexcinfo(sys.exc_info())
 | 
					            self._addexcinfo(sys.exc_info())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def addUnexpectedSuccess(self, testcase, reason=""):
 | 
					    def addUnexpectedSuccess(self, testcase, reason=""):
 | 
				
			||||||
| 
						 | 
					@ -179,13 +181,14 @@ class TestCaseFunction(pytest.Function):
 | 
				
			||||||
            self._testcase.debug()
 | 
					            self._testcase.debug()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def _prunetraceback(self, excinfo):
 | 
					    def _prunetraceback(self, excinfo):
 | 
				
			||||||
        pytest.Function._prunetraceback(self, excinfo)
 | 
					        Function._prunetraceback(self, excinfo)
 | 
				
			||||||
        traceback = excinfo.traceback.filter(
 | 
					        traceback = excinfo.traceback.filter(
 | 
				
			||||||
            lambda x:not x.frame.f_globals.get('__unittest'))
 | 
					            lambda x: not x.frame.f_globals.get('__unittest'))
 | 
				
			||||||
        if traceback:
 | 
					        if traceback:
 | 
				
			||||||
            excinfo.traceback = traceback
 | 
					            excinfo.traceback = traceback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(tryfirst=True)
 | 
					
 | 
				
			||||||
 | 
					@hookimpl(tryfirst=True)
 | 
				
			||||||
def pytest_runtest_makereport(item, call):
 | 
					def pytest_runtest_makereport(item, call):
 | 
				
			||||||
    if isinstance(item, TestCaseFunction):
 | 
					    if isinstance(item, TestCaseFunction):
 | 
				
			||||||
        if item._excinfo:
 | 
					        if item._excinfo:
 | 
				
			||||||
| 
						 | 
					@ -197,7 +200,8 @@ def pytest_runtest_makereport(item, call):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# twisted trial support
 | 
					# twisted trial support
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@pytest.hookimpl(hookwrapper=True)
 | 
					
 | 
				
			||||||
 | 
					@hookimpl(hookwrapper=True)
 | 
				
			||||||
def pytest_runtest_protocol(item):
 | 
					def pytest_runtest_protocol(item):
 | 
				
			||||||
    if isinstance(item, TestCaseFunction) and \
 | 
					    if isinstance(item, TestCaseFunction) and \
 | 
				
			||||||
       'twisted.trial.unittest' in sys.modules:
 | 
					       'twisted.trial.unittest' in sys.modules:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -517,7 +517,6 @@ Initialization, command line and configuration hooks
 | 
				
			||||||
.. autofunction:: pytest_load_initial_conftests
 | 
					.. autofunction:: pytest_load_initial_conftests
 | 
				
			||||||
.. autofunction:: pytest_cmdline_preparse
 | 
					.. autofunction:: pytest_cmdline_preparse
 | 
				
			||||||
.. autofunction:: pytest_cmdline_parse
 | 
					.. autofunction:: pytest_cmdline_parse
 | 
				
			||||||
.. autofunction:: pytest_namespace
 | 
					 | 
				
			||||||
.. autofunction:: pytest_addoption
 | 
					.. autofunction:: pytest_addoption
 | 
				
			||||||
.. autofunction:: pytest_cmdline_main
 | 
					.. autofunction:: pytest_cmdline_main
 | 
				
			||||||
.. autofunction:: pytest_configure
 | 
					.. autofunction:: pytest_configure
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										76
									
								
								pytest.py
								
								
								
								
							
							
						
						
									
										76
									
								
								pytest.py
								
								
								
								
							| 
						 | 
					@ -2,19 +2,7 @@
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
pytest: unit and functional testing with Python.
 | 
					pytest: unit and functional testing with Python.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
__all__ = [
 | 
					 | 
				
			||||||
    'main',
 | 
					 | 
				
			||||||
    'UsageError',
 | 
					 | 
				
			||||||
    'cmdline',
 | 
					 | 
				
			||||||
    'hookspec',
 | 
					 | 
				
			||||||
    'hookimpl',
 | 
					 | 
				
			||||||
    '__version__',
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__': # if run as a script or by 'python -m pytest'
 | 
					 | 
				
			||||||
    # we trigger the below "else" condition by the following import
 | 
					 | 
				
			||||||
    import pytest
 | 
					 | 
				
			||||||
    raise SystemExit(pytest.main())
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# else we are imported
 | 
					# else we are imported
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +10,69 @@ from _pytest.config import (
 | 
				
			||||||
    main, UsageError, _preloadplugins, cmdline,
 | 
					    main, UsageError, _preloadplugins, cmdline,
 | 
				
			||||||
    hookspec, hookimpl
 | 
					    hookspec, hookimpl
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					from _pytest.fixtures import fixture, yield_fixture
 | 
				
			||||||
 | 
					from _pytest.assertion import register_assert_rewrite
 | 
				
			||||||
 | 
					from _pytest.freeze_support import freeze_includes
 | 
				
			||||||
from _pytest import __version__
 | 
					from _pytest import __version__
 | 
				
			||||||
 | 
					from _pytest.debugging import pytestPDB as __pytestPDB
 | 
				
			||||||
 | 
					from _pytest.recwarn import warns, deprecated_call
 | 
				
			||||||
 | 
					from _pytest.runner import fail, skip, importorskip, exit
 | 
				
			||||||
 | 
					from _pytest.mark import MARK_GEN as mark, param
 | 
				
			||||||
 | 
					from _pytest.skipping import xfail
 | 
				
			||||||
 | 
					from _pytest.main import Item, Collector, File, Session
 | 
				
			||||||
 | 
					from _pytest.fixtures import fillfixtures as _fillfuncargs
 | 
				
			||||||
 | 
					from _pytest.python import (
 | 
				
			||||||
 | 
					    raises, approx,
 | 
				
			||||||
 | 
					    Module, Class, Instance, Function, Generator,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_preloadplugins() # to populate pytest.* namespace so help(pytest) works
 | 
					set_trace = __pytestPDB.set_trace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__all__ = [
 | 
				
			||||||
 | 
					    'main',
 | 
				
			||||||
 | 
					    'UsageError',
 | 
				
			||||||
 | 
					    'cmdline',
 | 
				
			||||||
 | 
					    'hookspec',
 | 
				
			||||||
 | 
					    'hookimpl',
 | 
				
			||||||
 | 
					    '__version__',
 | 
				
			||||||
 | 
					    'register_assert_rewrite',
 | 
				
			||||||
 | 
					    'freeze_includes',
 | 
				
			||||||
 | 
					    'set_trace',
 | 
				
			||||||
 | 
					    'warns',
 | 
				
			||||||
 | 
					    'deprecated_call',
 | 
				
			||||||
 | 
					    'fixture',
 | 
				
			||||||
 | 
					    'yield_fixture',
 | 
				
			||||||
 | 
					    'fail',
 | 
				
			||||||
 | 
					    'skip',
 | 
				
			||||||
 | 
					    'xfail',
 | 
				
			||||||
 | 
					    'importorskip',
 | 
				
			||||||
 | 
					    'exit',
 | 
				
			||||||
 | 
					    'mark',
 | 
				
			||||||
 | 
					    'param',
 | 
				
			||||||
 | 
					    'approx',
 | 
				
			||||||
 | 
					    '_fillfuncargs',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    'Item',
 | 
				
			||||||
 | 
					    'File',
 | 
				
			||||||
 | 
					    'Collector',
 | 
				
			||||||
 | 
					    'Session',
 | 
				
			||||||
 | 
					    'Module',
 | 
				
			||||||
 | 
					    'Class',
 | 
				
			||||||
 | 
					    'Instance',
 | 
				
			||||||
 | 
					    'Function',
 | 
				
			||||||
 | 
					    'Generator',
 | 
				
			||||||
 | 
					    'raises',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    # if run as a script or by 'python -m pytest'
 | 
				
			||||||
 | 
					    # we trigger the below "else" condition by the following import
 | 
				
			||||||
 | 
					    import pytest
 | 
				
			||||||
 | 
					    raise SystemExit(pytest.main())
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    from _pytest.compat import _setup_collect_fakemodule
 | 
				
			||||||
 | 
					    _preloadplugins()  # to populate pytest.* namespace so help(pytest) works
 | 
				
			||||||
 | 
					    _setup_collect_fakemodule()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,25 @@
 | 
				
			||||||
 | 
					import py
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import pytest
 | 
				
			||||||
 | 
					import _pytest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MODSET = [
 | 
				
			||||||
 | 
					    x for x in py.path.local(_pytest.__file__).dirpath().visit('*.py')
 | 
				
			||||||
 | 
					    if x.purebasename != '__init__'
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@pytest.mark.parametrize('modfile', MODSET, ids=lambda x: x.purebasename)
 | 
				
			||||||
 | 
					def test_fileimport(modfile):
 | 
				
			||||||
 | 
					    # this test ensures all internal packages can import
 | 
				
			||||||
 | 
					    # without needing the pytest namespace being set
 | 
				
			||||||
 | 
					    # this is critical for the initialization of xdist
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    res = subprocess.call([
 | 
				
			||||||
 | 
					        sys.executable,
 | 
				
			||||||
 | 
					        '-c', 'import sys, py; py.path.local(sys.argv[1]).pyimport()',
 | 
				
			||||||
 | 
					        modfile.strpath,
 | 
				
			||||||
 | 
					    ])
 | 
				
			||||||
 | 
					    if res:
 | 
				
			||||||
 | 
					        pytest.fail("command result %s" % res)
 | 
				
			||||||
		Loading…
	
		Reference in New Issue