Merge branch 'importorskip-ModuleNotFoundError'
This commit is contained in:
commit
1456b71990
|
@ -0,0 +1 @@
|
||||||
|
pytest.importorskip will now skip both ImportError and ModuleNotFoundError.
|
|
@ -11,6 +11,8 @@ from typing import Protocol
|
||||||
from typing import Type
|
from typing import Type
|
||||||
from typing import TypeVar
|
from typing import TypeVar
|
||||||
|
|
||||||
|
from .warning_types import PytestDeprecationWarning
|
||||||
|
|
||||||
|
|
||||||
class OutcomeException(BaseException):
|
class OutcomeException(BaseException):
|
||||||
"""OutcomeException and its subclass instances indicate and contain info
|
"""OutcomeException and its subclass instances indicate and contain info
|
||||||
|
@ -192,7 +194,10 @@ def xfail(reason: str = "") -> NoReturn:
|
||||||
|
|
||||||
|
|
||||||
def importorskip(
|
def importorskip(
|
||||||
modname: str, minversion: Optional[str] = None, reason: Optional[str] = None
|
modname: str,
|
||||||
|
minversion: Optional[str] = None,
|
||||||
|
reason: Optional[str] = None,
|
||||||
|
exc_type: Optional[Type[ImportError]] = None,
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""Import and return the requested module ``modname``, or skip the
|
"""Import and return the requested module ``modname``, or skip the
|
||||||
current test if the module cannot be imported.
|
current test if the module cannot be imported.
|
||||||
|
@ -205,6 +210,8 @@ def importorskip(
|
||||||
:param reason:
|
:param reason:
|
||||||
If given, this reason is shown as the message when the module cannot
|
If given, this reason is shown as the message when the module cannot
|
||||||
be imported.
|
be imported.
|
||||||
|
:param exc_type:
|
||||||
|
If given, modules are skipped if this exception is raised.
|
||||||
|
|
||||||
:returns:
|
:returns:
|
||||||
The imported module. This should be assigned to its canonical name.
|
The imported module. This should be assigned to its canonical name.
|
||||||
|
@ -223,12 +230,24 @@ def importorskip(
|
||||||
# of existing directories with the same name we're trying to
|
# of existing directories with the same name we're trying to
|
||||||
# import but without a __init__.py file.
|
# import but without a __init__.py file.
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
|
|
||||||
|
if exc_type is None:
|
||||||
|
exc_type = ModuleNotFoundError
|
||||||
|
else:
|
||||||
|
exc_type = ImportError
|
||||||
|
warnings.warn(
|
||||||
|
PytestDeprecationWarning(
|
||||||
|
"The Default behaviour will change to ImportError in future",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
__import__(modname)
|
__import__(modname)
|
||||||
except ModuleNotFoundError as exc:
|
except exc_type as exc:
|
||||||
if reason is None:
|
if reason is None:
|
||||||
reason = f"could not import {modname!r}: {exc}"
|
reason = f"could not import {modname!r}: {exc}"
|
||||||
raise Skipped(reason, allow_module_level=True) from None
|
raise Skipped(reason, allow_module_level=True) from None
|
||||||
|
|
||||||
mod = sys.modules[modname]
|
mod = sys.modules[modname]
|
||||||
if minversion is None:
|
if minversion is None:
|
||||||
return mod
|
return mod
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
# mypy: allow-untyped-defs
|
# mypy: allow-untyped-defs
|
||||||
import builtins
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
import inspect
|
import inspect
|
||||||
import os
|
import os
|
||||||
|
@ -8,8 +7,6 @@ import sys
|
||||||
import types
|
import types
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
from typing import List
|
from typing import List
|
||||||
from typing import Mapping
|
|
||||||
from typing import Sequence
|
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Type
|
from typing import Type
|
||||||
|
|
||||||
|
@ -22,6 +19,7 @@ from _pytest.config import ExitCode
|
||||||
from _pytest.monkeypatch import MonkeyPatch
|
from _pytest.monkeypatch import MonkeyPatch
|
||||||
from _pytest.outcomes import OutcomeException
|
from _pytest.outcomes import OutcomeException
|
||||||
from _pytest.pytester import Pytester
|
from _pytest.pytester import Pytester
|
||||||
|
from _pytest.warning_types import PytestDeprecationWarning
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
|
||||||
|
@ -765,25 +763,18 @@ def test_importorskip_imports_last_module_part() -> None:
|
||||||
assert os.path == ospath
|
assert os.path == ospath
|
||||||
|
|
||||||
|
|
||||||
def test_importorskip_importError_Exception() -> None:
|
def test_importorskip_importError_warning(pytester: Pytester) -> None:
|
||||||
## Mocking the import function to raise a importError
|
"""
|
||||||
realimport = builtins.__import__
|
importorskip() will only skip modules by ImportError as well as ModuleNotFoundError
|
||||||
|
will give warning when using ImportError
|
||||||
|
#11523
|
||||||
|
"""
|
||||||
|
fn = pytester.makepyfile("raise ImportError('some specific problem')")
|
||||||
|
pytester.syspathinsert()
|
||||||
|
|
||||||
def myimport(
|
with pytest.raises(pytest.skip.Exception):
|
||||||
name: str,
|
with pytest.warns(PytestDeprecationWarning):
|
||||||
globals: Mapping[str, object] | None = None,
|
pytest.importorskip(fn.stem, exc_type=ImportError)
|
||||||
locals: Mapping[str, object] | None = None,
|
|
||||||
fromlist: Sequence[str] = (),
|
|
||||||
level: int = 0,
|
|
||||||
) -> types.ModuleType:
|
|
||||||
raise ImportError
|
|
||||||
|
|
||||||
builtins.__import__ = myimport
|
|
||||||
|
|
||||||
with pytest.raises(ImportError):
|
|
||||||
pytest.importorskip("abcdefghi")
|
|
||||||
|
|
||||||
builtins.__import__ = realimport
|
|
||||||
|
|
||||||
|
|
||||||
def test_importorskip_dev_module(monkeypatch) -> None:
|
def test_importorskip_dev_module(monkeypatch) -> None:
|
||||||
|
|
Loading…
Reference in New Issue