The following test uses mypy to check the correctness of Python code using
typing, largely introduced in 3.5 and 3.6.
The two tests check all package code and all test code in the tests
directory, respectively.
Testing frameworks such as 'nose2' will automatically run the tests and will fail if any typing error
is detected (see step #3 below for more on this).
- Add the file below to your
tests
directory, which should be at the top-level in your repository alongside your module directory. - Modify the first line in
__init__
that setsself.pkgname
to match your library's package name. This assumes one package per repo, so the test would need to be changed if this isn't how the repo structure works. - If you run across typechecking errors in your code and you have a good reason for
mypy
to ignore them, you should be able to add# type: ignore
along with an actual comment describing why the type checking should be ignored on this line.
import os
import glob
import subprocess
import unittest
from typing import List
class MyPyTest(unittest.TestCase):
def test_run_mypy_module(self):
"""Run mypy on all module sources"""
mypy_call: List[str] = ["mypy"] + self.mypy_opts + ["-p", self.pkgname]
browse_result: int = subprocess.call(mypy_call, env=os.environ, cwd=self.pypath)
self.assertEqual(browse_result, 0, 'mypy on browse')
def test_run_mypy_tests(self):
"""Run mypy on all tests in module under the tests directory"""
for test_file in glob.iglob(f'{os.getcwd()}/tests/**/*.py', recursive=True):
mypy_call: List[str] = ["mypy"] + self.mypy_opts + [test_file]
test_result: int = subprocess.call(mypy_call, env=os.environ, cwd=self.pypath)
self.assertEqual(test_result, 0, f'mypy on test {test_file}')
def __init__(self, *args, **kwargs) -> None:
self.pkgname: str = "browse"
super(MyPyTest, self).__init__(*args, **kwargs)
my_env = os.environ.copy()
self.pypath: str = my_env.get("PYTHONPATH", os.getcwd())
self.mypy_opts: List[str] = ['--ignore-missing-imports']
if __name__ == '__main__':
unittest.main()
Thanks for this. What's the license if I'd like to include it in my project?