importorskip: Allow non-integer version strings

Use `pkg_resources.parse_version` to parse version strings.
This can handle 'dev', 'rc', alpha and beta version strings,
among others.
This commit is contained in:
Eric Hunsberger 2015-07-23 16:38:25 -04:00
parent 5a17e797c7
commit d104487282
3 changed files with 19 additions and 5 deletions

View File

@ -1,6 +1,9 @@
2.7.3 (compared to 2.7.2) 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 - fix issue856: consider --color parameter in all outputs (for example
--fixtures). Thanks Barney Gale for the report and Bruno Oliveira for the PR. --fixtures). Thanks Barney Gale for the report and Bruno Oliveira for the PR.

View File

@ -3,6 +3,8 @@ import bdb
import sys import sys
from time import time from time import time
from pkg_resources import parse_version
import py import py
import pytest import pytest
from py._code.code import TerminalRepr 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 """ return imported module if it has at least "minversion" as its
__version__ attribute. If no minversion is specified the a skip __version__ attribute. If no minversion is specified the a skip
is only triggered if the module can not be imported. 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 __tracebackhide__ = True
compile(modname, '', 'eval') # to catch syntaxerrors compile(modname, '', 'eval') # to catch syntaxerrors
@ -496,9 +496,7 @@ def importorskip(modname, minversion=None):
if minversion is None: if minversion is None:
return mod return mod
verattr = getattr(mod, '__version__', None) verattr = getattr(mod, '__version__', None)
def intver(verstring): if verattr is None or parse_version(verattr) < parse_version(minversion):
return [int(x) for x in verstring.split(".")]
if verattr is None or intver(verattr) < intver(minversion):
skip("module %r has __version__ %r, required is: %r" %( skip("module %r has __version__ %r, required is: %r" %(
modname, verattr, minversion)) modname, verattr, minversion))
return mod return mod

View File

@ -471,6 +471,19 @@ def test_importorskip_imports_last_module_part():
ospath = pytest.importorskip("os.path") ospath = pytest.importorskip("os.path")
assert os.path == ospath assert os.path == ospath
def test_importorskip_dev_module():
try:
mod = py.std.types.ModuleType("mockmodule")
mod.__version__ = '0.13.0.dev-43290'
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): def test_pytest_cmdline_main(testdir):
p = testdir.makepyfile(""" p = testdir.makepyfile("""