-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathtest_compat.py
More file actions
153 lines (129 loc) · 4.65 KB
/
test_compat.py
File metadata and controls
153 lines (129 loc) · 4.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from __future__ import annotations
import sys
import types
from contextlib import ExitStack as does_not_raise # noqa: N813
import pytest
from _pytask.compat import _MINIMUM_VERSIONS
from pytask import check_for_optional_program
from pytask import import_optional_dependency
@pytest.mark.parametrize(
("name", "extra", "errors", "caller", "expectation", "expected"),
[
pytest.param(
"python",
"",
"raise",
"pytask",
does_not_raise(),
True,
id="program exists",
),
pytest.param(
"unknown_program",
"",
"raise",
"pytask",
pytest.raises(RuntimeError, match="pytask requires the optional program"),
None,
id="program does not exist and error raised",
),
pytest.param(
"unknown_program",
"",
"warn",
"pytask",
pytest.warns(UserWarning, match="pytask requires the optional program"),
False,
id="program does not exist and warning",
),
pytest.param(
"unknown_program",
"extra included",
"warn",
"pytask",
pytest.warns(UserWarning, match="extra included"),
False,
id="program does not exist and warning and extra",
),
pytest.param(
"unknown_program",
"extra included",
"ignore",
"pytask",
does_not_raise(),
False,
id="program does not exist and ignore and extra",
),
pytest.param(
None,
"",
"unknown_errors",
"pytask",
pytest.raises(ValueError, match="'errors' must be one of"),
None,
id="unknown errors",
),
],
)
def test_check_for_optional_program( # noqa: PLR0913
name, extra, errors, caller, expectation, expected
):
with expectation:
program_exists = check_for_optional_program(name, extra, errors, caller)
assert program_exists is expected
def test_import_optional():
match = "pytask requires .*notapackage.* pip .* conda .* 'notapackage'"
with pytest.raises(ImportError, match=match) as exc_info:
import_optional_dependency("notapackage")
# The original exception should be there as context:
assert isinstance(exc_info.value.__context__, ImportError)
result = import_optional_dependency("notapackage", errors="ignore")
assert result is None
def test_sqlalchemy_version_fallback():
pytest.importorskip("sqlalchemy")
import_optional_dependency("sqlalchemy")
def test_bad_version(monkeypatch):
name = "fakemodule"
module = types.ModuleType(name)
module.__version__ = "0.9.0"
sys.modules[name] = module
monkeypatch.setitem(_MINIMUM_VERSIONS, name, "1.0.0")
match = "pytask requires .*1.0.0.* of .fakemodule.*'0.9.0'"
with pytest.raises(ImportError, match=match):
import_optional_dependency("fakemodule")
# Test min_version parameter
result = import_optional_dependency("fakemodule", min_version="0.8")
assert result is module
with pytest.warns(UserWarning, match=match):
result = import_optional_dependency("fakemodule", errors="warn")
assert result is None
module.__version__ = "1.0.0" # exact match is OK
result = import_optional_dependency("fakemodule")
assert result is module
def test_submodule(monkeypatch):
# Create a fake module with a submodule
name = "fakemodule"
module = types.ModuleType(name)
module.__version__ = "0.9.0"
sys.modules[name] = module
sub_name = "submodule"
submodule = types.ModuleType(sub_name)
setattr(module, sub_name, submodule)
sys.modules[f"{name}.{sub_name}"] = submodule
monkeypatch.setitem(_MINIMUM_VERSIONS, name, "1.0.0")
match = "pytask requires .*1.0.0.* of .fakemodule.*'0.9.0'"
with pytest.raises(ImportError, match=match):
import_optional_dependency("fakemodule.submodule")
with pytest.warns(UserWarning, match=match):
result = import_optional_dependency("fakemodule.submodule", errors="warn")
assert result is None
module.__version__ = "1.0.0" # exact match is OK
result = import_optional_dependency("fakemodule.submodule")
assert result is submodule
def test_no_version_raises(monkeypatch):
name = "fakemodule"
module = types.ModuleType(name)
sys.modules[name] = module
monkeypatch.setitem(_MINIMUM_VERSIONS, name, "1.0.0")
with pytest.raises(ImportError, match=r"Can't determine .* fakemodule"):
import_optional_dependency(name)