From 8b48621687f1a4bbc4832d1c2b852bec061dbfff Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 4 Jan 2019 17:56:13 +0000 Subject: [PATCH 1/3] Allow providing a custom reason for `importorskip` --- src/_pytest/outcomes.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index 714be3088..cdda8630e 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -137,7 +137,7 @@ def xfail(reason=""): xfail.Exception = XFailed -def importorskip(modname, minversion=None): +def importorskip(modname, minversion=None, reason=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. @@ -159,7 +159,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 From be7eb22e8871fb9cb332bacfd3810a698f52636b Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 4 Jan 2019 19:02:07 +0000 Subject: [PATCH 2/3] Add test case for `importorskip` custom reason --- testing/test_runner.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/testing/test_runner.py b/testing/test_runner.py index ae129d06d..91f7d2700 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -738,6 +738,22 @@ def test_importorskip_module_level(testdir): 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( """ From 0c4898670c98fa39b393d396062d08808941ae5f Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 5 Jan 2019 12:55:39 -0200 Subject: [PATCH 3/3] Add changelog entry and update docs for importorskip --- changelog/4599.feature.rst | 2 ++ src/_pytest/outcomes.py | 11 ++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 changelog/4599.feature.rst diff --git a/changelog/4599.feature.rst b/changelog/4599.feature.rst new file mode 100644 index 000000000..12ed20b23 --- /dev/null +++ b/changelog/4599.feature.rst @@ -0,0 +1,2 @@ +``pytest.importorskip`` now supports a ``reason`` parameter, which will be shown when the +requested module cannot be imported. diff --git a/src/_pytest/outcomes.py b/src/_pytest/outcomes.py index cdda8630e..d27939e30 100644 --- a/src/_pytest/outcomes.py +++ b/src/_pytest/outcomes.py @@ -138,9 +138,14 @@ xfail.Exception = XFailed def importorskip(modname, minversion=None, reason=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. + """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