pytest-revealtype-injector 0.8.0__tar.gz → 0.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/PKG-INFO +1 -1
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/__init__.py +1 -1
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/adapter/pyrefly_.py +6 -4
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/adapter/ty_.py +6 -5
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/hooks.py +1 -1
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/tests/test_marker.py +26 -15
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/.gitignore +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/COPYING.mit +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/README.md +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/pyproject.toml +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/adapter/__init__.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/adapter/basedpyright_.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/adapter/mypy_.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/adapter/pyright_.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/log.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/main.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/models.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/plugin.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/src/pytest_revealtype_injector/py.typed +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/tests/conftest.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/tests/test_ast_mode.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/tests/test_import.py +0 -0
- {pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/tests/test_options.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pytest-revealtype-injector
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.0
|
|
4
4
|
Summary: Pytest plugin for replacing reveal_type() calls inside test functions with static and runtime type checking result comparison, for confirming type annotation validity.
|
|
5
5
|
Project-URL: homepage, https://github.com/abelcheung/pytest-revealtype-injector
|
|
6
6
|
Author-email: Abel Cheung <abelcheung@gmail.com>
|
|
@@ -110,10 +110,12 @@ class PyreflyAdapter(TypeCheckerAdapter):
|
|
|
110
110
|
try:
|
|
111
111
|
report = json.loads(proc.stdout)
|
|
112
112
|
except Exception as e:
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
113
|
+
# pyrefly (circa 0.47.0) appends github text formatted annotation at the end of json output
|
|
114
|
+
decoder = json.JSONDecoder()
|
|
115
|
+
report, _ = decoder.raw_decode(proc.stdout.decode())
|
|
116
|
+
_logger.warning(
|
|
117
|
+
f"({self.id}) failed to parse json output, extracted partial json: {e}"
|
|
118
|
+
)
|
|
117
119
|
assert isinstance(report, dict) and "errors" in report
|
|
118
120
|
items = cast(list[_PyreflyDiagItem], report["errors"])
|
|
119
121
|
|
|
@@ -63,7 +63,7 @@ class NameCollector(BareNameCollector):
|
|
|
63
63
|
class TyAdapter(TypeCheckerAdapter):
|
|
64
64
|
id = "ty"
|
|
65
65
|
_executable = "ty"
|
|
66
|
-
_type_mesg_re = re.compile(r
|
|
66
|
+
_type_mesg_re = re.compile(r"Revealed type: `(?P<type>.+?)`")
|
|
67
67
|
_namecollector_class = BareNameCollector
|
|
68
68
|
_schema = s.Schema({
|
|
69
69
|
"check_name": str,
|
|
@@ -78,8 +78,8 @@ class TyAdapter(TypeCheckerAdapter):
|
|
|
78
78
|
"path": str,
|
|
79
79
|
"positions": {
|
|
80
80
|
"begin": {"line": int, "column": int},
|
|
81
|
-
"end"
|
|
82
|
-
}
|
|
81
|
+
"end": {"line": int, "column": int},
|
|
82
|
+
},
|
|
83
83
|
},
|
|
84
84
|
})
|
|
85
85
|
|
|
@@ -152,11 +152,12 @@ class TyAdapter(TypeCheckerAdapter):
|
|
|
152
152
|
filename, lineno = (
|
|
153
153
|
pathlib.Path(diag["location"]["path"]).name,
|
|
154
154
|
diag["location"]["positions"]["begin"]["line"],
|
|
155
|
-
)
|
|
155
|
+
)
|
|
156
156
|
if (m := self._type_mesg_re.search(diag["description"])) is None:
|
|
157
157
|
continue
|
|
158
158
|
pos = FilePos(filename, lineno)
|
|
159
159
|
self.typechecker_result[pos] = VarType(None, ForwardRef(m["type"]))
|
|
160
160
|
|
|
161
|
+
|
|
161
162
|
def generate_adapter() -> TypeCheckerAdapter:
|
|
162
|
-
return TyAdapter()
|
|
163
|
+
return TyAdapter()
|
|
@@ -49,7 +49,7 @@ def pytest_pyfunc_call(pyfuncitem: pytest.Function) -> Iterator[None]:
|
|
|
49
49
|
adapters = {a for a in adp_stash}
|
|
50
50
|
|
|
51
51
|
if not adapters:
|
|
52
|
-
pytest.
|
|
52
|
+
pytest.skip("No type checker is enabled for this test.")
|
|
53
53
|
|
|
54
54
|
# Monkeypatch reveal_type() with our own function, to guarantee
|
|
55
55
|
# each test func can receive different adapters
|
|
@@ -62,7 +62,9 @@ class TestOnlyTypeCheckerMarker:
|
|
|
62
62
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
63
63
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
64
64
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
65
|
-
self.TEST_CONTENT.replace(
|
|
65
|
+
self.TEST_CONTENT.replace(
|
|
66
|
+
"# FUNC MARK", "@pytest.mark.onlytypechecker('mypy')"
|
|
67
|
+
)
|
|
66
68
|
)
|
|
67
69
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
68
70
|
result.assert_outcomes(passed=1, failed=2)
|
|
@@ -71,7 +73,9 @@ class TestOnlyTypeCheckerMarker:
|
|
|
71
73
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
72
74
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
73
75
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
74
|
-
self.TEST_CONTENT.replace(
|
|
76
|
+
self.TEST_CONTENT.replace(
|
|
77
|
+
"# CLASS MARK", "@pytest.mark.onlytypechecker('mypy')"
|
|
78
|
+
)
|
|
75
79
|
)
|
|
76
80
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
77
81
|
result.assert_outcomes(passed=2, failed=1)
|
|
@@ -80,7 +84,9 @@ class TestOnlyTypeCheckerMarker:
|
|
|
80
84
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
81
85
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
82
86
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
83
|
-
self.TEST_CONTENT.replace(
|
|
87
|
+
self.TEST_CONTENT.replace(
|
|
88
|
+
"# GLOBAL MARK", "pytestmark = pytest.mark.onlytypechecker('mypy')"
|
|
89
|
+
)
|
|
84
90
|
)
|
|
85
91
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
86
92
|
result.assert_outcomes(passed=3, failed=0)
|
|
@@ -143,7 +149,9 @@ class TestNoTypeCheckerMarker:
|
|
|
143
149
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
144
150
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
145
151
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
146
|
-
self.TEST_CONTENT.replace(
|
|
152
|
+
self.TEST_CONTENT.replace(
|
|
153
|
+
"# FUNC MARK", "@pytest.mark.notypechecker('mypy')"
|
|
154
|
+
)
|
|
147
155
|
)
|
|
148
156
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
149
157
|
result.assert_outcomes(passed=1, failed=2)
|
|
@@ -152,7 +160,9 @@ class TestNoTypeCheckerMarker:
|
|
|
152
160
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
153
161
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
154
162
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
155
|
-
self.TEST_CONTENT.replace(
|
|
163
|
+
self.TEST_CONTENT.replace(
|
|
164
|
+
"# CLASS MARK", "@pytest.mark.notypechecker('mypy')"
|
|
165
|
+
)
|
|
156
166
|
)
|
|
157
167
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
158
168
|
result.assert_outcomes(passed=2, failed=1)
|
|
@@ -161,11 +171,14 @@ class TestNoTypeCheckerMarker:
|
|
|
161
171
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
162
172
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
163
173
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
164
|
-
self.TEST_CONTENT.replace(
|
|
174
|
+
self.TEST_CONTENT.replace(
|
|
175
|
+
"# GLOBAL MARK", "pytestmark = pytest.mark.notypechecker('mypy')"
|
|
176
|
+
)
|
|
165
177
|
)
|
|
166
178
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
167
179
|
result.assert_outcomes(passed=3, failed=0)
|
|
168
180
|
|
|
181
|
+
|
|
169
182
|
class TestMarkerConflicts:
|
|
170
183
|
PYPROJECT_TOML = """
|
|
171
184
|
[tool.pyright]
|
|
@@ -178,6 +191,7 @@ class TestMarkerConflicts:
|
|
|
178
191
|
def test_foo() -> None:
|
|
179
192
|
pass
|
|
180
193
|
"""
|
|
194
|
+
|
|
181
195
|
def test_typechecker_exclusive(self, pytester: pytest.Pytester) -> None:
|
|
182
196
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
183
197
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
@@ -185,22 +199,19 @@ class TestMarkerConflicts:
|
|
|
185
199
|
textwrap.dedent(self.TEST_CONTENT).replace(
|
|
186
200
|
"# PLACEHOLDER",
|
|
187
201
|
"@pytest.mark.notypechecker('mypy')\n"
|
|
188
|
-
"@pytest.mark.onlytypechecker('pyright')"
|
|
202
|
+
"@pytest.mark.onlytypechecker('pyright')",
|
|
189
203
|
)
|
|
190
204
|
)
|
|
191
205
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
192
|
-
assert result.ret == pytest.ExitCode.
|
|
193
|
-
result.assert_outcomes(
|
|
206
|
+
assert result.ret == pytest.ExitCode.TESTS_FAILED
|
|
207
|
+
result.assert_outcomes(failed=1)
|
|
194
208
|
|
|
195
209
|
def test_no_typechecker_left(self, pytester: pytest.Pytester) -> None:
|
|
196
210
|
pytester.makeconftest("pytest_plugins = ['pytest_revealtype_injector.plugin']")
|
|
197
211
|
pytester.makepyprojecttoml(self.PYPROJECT_TOML)
|
|
198
212
|
pytester.makepyfile( # pyright: ignore[reportUnknownMemberType]
|
|
199
|
-
self.TEST_CONTENT.replace(
|
|
200
|
-
"# PLACEHOLDER",
|
|
201
|
-
"@pytest.mark.onlytypechecker()"
|
|
202
|
-
)
|
|
213
|
+
self.TEST_CONTENT.replace("# PLACEHOLDER", "@pytest.mark.onlytypechecker()")
|
|
203
214
|
)
|
|
204
215
|
result = pytester.runpytest("--tb=short", "-vv")
|
|
205
|
-
assert result.ret == pytest.ExitCode.
|
|
206
|
-
result.assert_outcomes(
|
|
216
|
+
assert result.ret == pytest.ExitCode.OK
|
|
217
|
+
result.assert_outcomes(skipped=1)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pytest_revealtype_injector-0.8.0 → pytest_revealtype_injector-0.9.0}/tests/test_ast_mode.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|