Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelog/4599.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
``pytest.importorskip`` now supports a ``reason`` parameter, which will be shown when the
requested module cannot be imported.
17 changes: 12 additions & 5 deletions src/_pytest/outcomes.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,15 @@ def xfail(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.
def importorskip(modname, minversion=None, reason=None):
"""Imports and returns the requested module ``modname``, or skip the current test
if the module cannot be imported.

:param str modname: the name of the module to import
:param str minversion: if given, the imported module ``__version__`` attribute must be
at least this minimal version, otherwise the test is still skipped.
:param str reason: if given, this reason is shown as the message when the module
cannot be imported.
"""
import warnings

Expand All @@ -159,7 +164,9 @@ def importorskip(modname, minversion=None):
# Do not raise chained exception here(#1485)
should_skip = True
if should_skip:
raise Skipped("could not import %r" % (modname,), allow_module_level=True)
if reason is None:
reason = "could not import %r" % (modname,)
raise Skipped(reason, allow_module_level=True)
mod = sys.modules[modname]
if minversion is None:
return mod
Expand Down
16 changes: 16 additions & 0 deletions testing/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,22 @@ def test_foo():
result.stdout.fnmatch_lines(["*collected 0 items / 1 skipped*"])


def test_importorskip_custom_reason(testdir):
"""make sure custom reasons are used"""
testdir.makepyfile(
"""
import pytest
foobarbaz = pytest.importorskip("foobarbaz2", reason="just because")

def test_foo():
pass
"""
)
result = testdir.runpytest("-ra")
result.stdout.fnmatch_lines(["*just because*"])
result.stdout.fnmatch_lines(["*collected 0 items / 1 skipped*"])


def test_pytest_cmdline_main(testdir):
p = testdir.makepyfile(
"""
Expand Down