diff --git a/CHANGELOG b/CHANGELOG index 26135beac..b4989bb1f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,9 @@ 2.7.3 (compared to 2.7.2) ----------------------------- +- Allow 'dev', 'rc', or other non-integer version strings in `importorskip`. + Thanks to Eric Hunsberger for the PR. + - fix issue856: consider --color parameter in all outputs (for example --fixtures). Thanks Barney Gale for the report and Bruno Oliveira for the PR. diff --git a/_pytest/runner.py b/_pytest/runner.py index 8accd3b0c..ad106b4b4 100644 --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -3,6 +3,8 @@ import bdb import sys from time import time +from pkg_resources import parse_version + import py import pytest from py._code.code import TerminalRepr @@ -483,8 +485,6 @@ 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. - Note that version comparison only works with simple version strings - like "1.2.3" but not "1.2.3.dev1" or others. """ __tracebackhide__ = True compile(modname, '', 'eval') # to catch syntaxerrors @@ -496,9 +496,7 @@ def importorskip(modname, minversion=None): if minversion is None: return mod verattr = getattr(mod, '__version__', None) - def intver(verstring): - return [int(x) for x in verstring.split(".")] - if verattr is None or intver(verattr) < intver(minversion): + if verattr is None or parse_version(verattr) < parse_version(minversion): skip("module %r has __version__ %r, required is: %r" %( modname, verattr, minversion)) return mod diff --git a/testing/test_runner.py b/testing/test_runner.py index e62aea9f7..167ddc57b 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -439,7 +439,7 @@ def test_exception_printing_skip(): s = excinfo.exconly(tryshort=True) assert s.startswith("Skipped") -def test_importorskip(): +def test_importorskip(monkeypatch): importorskip = pytest.importorskip def f(): importorskip("asdlkj") @@ -457,7 +457,7 @@ def test_importorskip(): pytest.raises(SyntaxError, "pytest.importorskip('x=y')") mod = py.std.types.ModuleType("hello123") mod.__version__ = "1.3" - sys.modules["hello123"] = mod + monkeypatch.setitem(sys.modules, "hello123", mod) pytest.raises(pytest.skip.Exception, """ pytest.importorskip("hello123", minversion="1.3.1") """) @@ -471,6 +471,19 @@ def test_importorskip_imports_last_module_part(): ospath = pytest.importorskip("os.path") assert os.path == ospath +def test_importorskip_dev_module(monkeypatch): + try: + mod = py.std.types.ModuleType("mockmodule") + mod.__version__ = '0.13.0.dev-43290' + monkeypatch.setitem(sys.modules, 'mockmodule', mod) + mod2 = pytest.importorskip('mockmodule', minversion='0.12.0') + assert mod2 == mod + pytest.raises(pytest.skip.Exception, """ + pytest.importorskip('mockmodule1', minversion='0.14.0')""") + except pytest.skip.Exception: + print(py.code.ExceptionInfo()) + pytest.fail("spurious skip") + def test_pytest_cmdline_main(testdir): p = testdir.makepyfile("""