-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
make Test Outcomes inherit from BaseException instead of exception
fixes #580
- Loading branch information
1 parent
1712196
commit 06a4933
Showing
13 changed files
with
176 additions
and
156 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
""" | ||
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=""): | ||
""" 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. | ||
""" | ||
__tracebackhide__ = True | ||
raise Skipped(msg=msg) | ||
|
||
|
||
skip.Exception = Skipped | ||
|
||
|
||
def fail(msg="", pytrace=True): | ||
""" explicitly fail an 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.