92 lines
3.0 KiB
Python
92 lines
3.0 KiB
Python
|
import os
|
||
|
import re
|
||
|
import shutil
|
||
|
import sys
|
||
|
from pathlib import Path
|
||
|
|
||
|
import pytest
|
||
|
|
||
|
mypy = pytest.importorskip("mypy")
|
||
|
|
||
|
# You can change the following variable to True during development to overwrite expected output with generated output
|
||
|
GENERATE = False
|
||
|
|
||
|
cases = [
|
||
|
("mypy-plugin.ini", "success_plugin.py", "success-plugin.txt"),
|
||
|
("mypy-plugin.ini", "fail_plugin.py", "fail-plugin.txt"),
|
||
|
("mypy-default.ini", "success_no_plugin.py", "success-no-plugin.txt"),
|
||
|
("mypy-default.ini", "fail_no_plugin.py", "fail-no-plugin.txt"),
|
||
|
]
|
||
|
|
||
|
|
||
|
@pytest.mark.skipif(
|
||
|
mypy.__file__.endswith(".py"), reason="Non-compiled mypy is too slow"
|
||
|
)
|
||
|
@pytest.mark.parametrize("config_filename,python_filename,output_filename", cases)
|
||
|
def test_mypy_results(
|
||
|
config_filename, python_filename, output_filename, tmpdir, monkeypatch
|
||
|
):
|
||
|
from mypy import api as mypy_api
|
||
|
|
||
|
os.chdir(tmpdir)
|
||
|
root_dir = Path(__file__).parent
|
||
|
thinc_root_dir = Path(__file__).parent.parent.parent.parent
|
||
|
if "--pyargs" not in sys.argv:
|
||
|
monkeypatch.setenv("MYPYPATH", str(thinc_root_dir))
|
||
|
tmpdir_path = Path(tmpdir)
|
||
|
|
||
|
full_config_path: Path = root_dir / f"configs/{config_filename}"
|
||
|
full_module_path: Path = root_dir / f"modules/{python_filename}"
|
||
|
full_output_path: Path = root_dir / f"outputs/{output_filename}"
|
||
|
|
||
|
full_tmp_config_path: Path = tmpdir_path / config_filename
|
||
|
full_tmp_module_path: Path = tmpdir_path / python_filename
|
||
|
|
||
|
shutil.copy(str(full_config_path), tmpdir)
|
||
|
shutil.copy(str(full_module_path), tmpdir)
|
||
|
|
||
|
expected_out = ""
|
||
|
expected_err = ""
|
||
|
expected_returncode = 1
|
||
|
expected_out = full_output_path.read_text()
|
||
|
|
||
|
# Specifying a different cache dir for each configuration dramatically speeds up subsequent execution
|
||
|
# It also prevents cache-invalidation-related bugs in the tests
|
||
|
cache_dir = tmpdir_path / f".mypy_cache/test-{config_filename[:-4]}"
|
||
|
command = [
|
||
|
str(full_tmp_module_path),
|
||
|
"--config-file",
|
||
|
str(full_tmp_config_path),
|
||
|
"--cache-dir",
|
||
|
str(cache_dir),
|
||
|
"--show-error-codes",
|
||
|
]
|
||
|
print(
|
||
|
f"\nExecuting: mypy {' '.join(command)}"
|
||
|
) # makes it easier to debug as necessary
|
||
|
actual_result = mypy_api.run(command)
|
||
|
actual_out, actual_err, actual_returncode = actual_result
|
||
|
# Need to strip filenames due to differences in formatting by OS
|
||
|
actual_out = "\n".join(
|
||
|
[".py:".join(line.split(".py:")[1:]) for line in actual_out.split("\n") if line]
|
||
|
).strip()
|
||
|
actual_out = re.sub(r"\n\s*\n", r"\n", actual_out)
|
||
|
|
||
|
if GENERATE and output_filename is not None:
|
||
|
full_output_path.write_text(actual_out)
|
||
|
else:
|
||
|
assert actual_out.strip() == expected_out.strip(), actual_out
|
||
|
|
||
|
assert actual_err == expected_err
|
||
|
assert actual_returncode == expected_returncode
|
||
|
|
||
|
|
||
|
@pytest.mark.skipif(
|
||
|
mypy.__file__.endswith(".py"), reason="Non-compiled mypy is too slow"
|
||
|
)
|
||
|
def test_generation_is_disabled():
|
||
|
"""
|
||
|
Makes sure we don't accidentally leave generation on
|
||
|
"""
|
||
|
assert not GENERATE
|