""" exception classes and constants handling test outcomes as well as functions creating them """ from __future__ import absolute_import, division, print_function import py import sys class OutcomeException(BaseException): """ OutcomeException and its subclass instances indicate and contain info about test and collection outcomes. """ def __init__(self, msg=None, pytrace=True): BaseException.__init__(self, msg) self.msg = msg self.pytrace = pytrace def __repr__(self): if self.msg: val = self.msg if isinstance(val, bytes): val = py._builtin._totext(val, errors='replace') return val return "<%s instance>" % (self.__class__.__name__,) __str__ = __repr__ TEST_OUTCOME = (OutcomeException, Exception) class Skipped(OutcomeException): # XXX hackish: on 3k we fake to live in the builtins # in order to have Skipped exception printing shorter/nicer __module__ = 'builtins' def __init__(self, msg=None, pytrace=True, allow_module_level=False): OutcomeException.__init__(self, msg=msg, pytrace=pytrace) self.allow_module_level = allow_module_level class Failed(OutcomeException): """ raised from an explicit call to pytest.fail() """ __module__ = 'builtins' class Exit(KeyboardInterrupt): """ raised for immediate program exits (no tracebacks/summaries)""" def __init__(self, msg="unknown reason"): self.msg = msg KeyboardInterrupt.__init__(self, msg) # exposed helper methods def exit(msg): """ exit testing process as if KeyboardInterrupt was triggered. """ __tracebackhide__ = True raise Exit(msg) exit.Exception = Exit def skip(msg="", **kwargs): """ skip an executing test with the given message. Note: it's usually better to use the pytest.mark.skipif marker to declare a test to be skipped under certain conditions like mismatching platforms or dependencies. See the pytest_skipping plugin for details. :kwarg bool allow_module_level: allows this function to be called at module level, skipping the rest of the module. Default to False. """ __tracebackhide__ = True allow_module_level = kwargs.pop('allow_module_level', False) if kwargs: keys = [k for k in kwargs.keys()] raise TypeError('unexpected keyword arguments: {}'.format(keys)) raise Skipped(msg=msg, allow_module_level=allow_module_level) skip.Exception = Skipped def fail(msg="", pytrace=True): """ explicitly fail a currently-executing test with the given Message. :arg pytrace: if false the msg represents the full failure information and no python traceback will be reported. """ __tracebackhide__ = True raise Failed(msg=msg, pytrace=pytrace) fail.Exception = Failed class XFailed(fail.Exception): """ raised from an explicit call to pytest.xfail() """ def xfail(reason=""): """ xfail an executing test or setup functions with the given reason.""" __tracebackhide__ = True raise XFailed(reason) xfail.Exception = XFailed def importorskip(modname, minversion=None): """ return imported module if it has at least "minversion" as its __version__ attribute. If no minversion is specified the a skip is only triggered if the module can not be imported. """ import warnings __tracebackhide__ = True compile(modname, '', 'eval') # to catch syntaxerrors should_skip = False with warnings.catch_warnings(): # make sure to ignore ImportWarnings that might happen because # of existing directories with the same name we're trying to # import but without a __init__.py file warnings.simplefilter('ignore') try: __import__(modname) except ImportError: # Do not raise chained exception here(#1485) should_skip = True if should_skip: raise Skipped("could not import %r" % (modname,), allow_module_level=True) mod = sys.modules[modname] if minversion is None: return mod verattr = getattr(mod, '__version__', None) if minversion is not None: try: from pkg_resources import parse_version as pv except ImportError: raise Skipped("we have a required version for %r but can not import " "pkg_resources to parse version strings." % (modname,), allow_module_level=True) if verattr is None or pv(verattr) < pv(minversion): raise Skipped("module %r has __version__ %r, required is: %r" % ( modname, verattr, minversion), allow_module_level=True) return mod