Package: pytest-mypy-plugins
pytest plugin for testing mypy types, stubs, and pluginsInstallationThis package is available onPyPIpipinstallpytest-mypy-pluginsandconda-forgecondainstall-cconda-forgepytest-mypy-pluginsUsageRunningPlugin, after installation, is automatically picked up bypytesttherefore it is sufficient to
just execute:pytestPathsThePYTHONPATHandMYPYPATHenvironment variables, if set, are passed tomypyon invocation.
This may be helpful if you are testing a local plugin and need to provide an import path to it.Be aware that whenmypyis run in a subprocess (the default) the test cases are run in temporary working directories
where relative paths such asPYTHONPATH=./my_plugindo not reference the directory which you are runningpytestfrom.
If you encounter this, consider invokingpytestwith--mypy-same-processor make your paths absolute,
e.g.PYTHONPATH=$(pwd)/my_plugin pytest.You can also specifyPYTHONPATH,MYPYPATH, or any other environment variable inenv:section ofymlspec:- case: mypy_path_from_env
  main: |
    from pair import Pair

    instance: Pair
    reveal_type(instance)  # N: Revealed type is 'pair.Pair'
  env:
    - MYPYPATH=../fixturesWhat is a test case?In general each test case is just an element in an array written in a properly formattedYAMLfile.
On top of that, each case must comply to following types:PropertyTypeDescriptioncasestrName of the test case, complies to[a-zA-Z0-9]patternmainstrPortion of the code as if written in.pyfilefilesOptional[List[File]]=[]*List of extra files to simulate imports if neededdisable_cacheOptional[bool]=FalseSet totruedisablesmypycachingmypy_configOptional[str]Inlinemypyconfiguration, passed directly tomypyas--config-fileoption, possibly joined with--mypy-pyproject-toml-fileor--mypy-ini-filecontents if they are passed. By default is treated asini, treated astomlonly if--mypy-pyproject-toml-fileis passedenvOptional[Dict[str, str]]={}Environmental variables to be provided inside of test runparametrizedOptional[List[Parameter]]=[]*List of parameters, similar to@pytest.mark.parametrizeskipstrExpression evaluated with following globals set:sys,os,pytestandplatformexpect_failboolMark test case as an expected failure, like@pytest.mark.xfailregexstrAllow regular expressions in comments to be matched against actual output. Defaults to "no", i.e. matches full text.(*) Appendix topseudotypes used above:classFile:path:strcontent:Optional[str]=NoneParameter=Mapping[str,Any]Implementation notes:mainmust be non-empty string that evaluates to validPythoncode,contentof each of extra files must evaluate to validPythoncode,parametrizedentries must all be the objects of the sametype. It simply means that each
entry must haveexactsame set of keys,skip- an expression set inskipis passed directly intoeval. It is advised to take a peek and
learn about howevalworks.Repository also offers aJSONSchema, with which
it validates the input. It can also offer your editor auto-completions, descriptions, and validation.All you have to do, add the following line at the top of your YAML file:# yaml-language-server: $schema=https://raw.githubusercontent.com/typeddjango/pytest-mypy-plugins/master/pytest_mypy_plugins/schema.jsonExample1. Inline type expectations# typesafety/test_request.yml-case:request_object_has_user_of_type_auth_user_modelmain:|from django.http.request import HttpRequestreveal_type(HttpRequest().user)  # N: Revealed type is 'myapp.models.MyUser'# check that other fields work okreveal_type(HttpRequest().method)  # N: Revealed type is 'Union[builtins.str, None]'files:-path:myapp/__init__.py-path:myapp/models.pycontent:|from django.db import modelsclass MyUser(models.Model):pass2.@parametrized-case:with_paramsparametrized:-val:1rt:builtins.int-val:1.0rt:builtins.floatmain:|reveal_type({{ val }})  # N: Revealed type is '{{ rt }}'Properties that you can parametrize:mainmypy_configout3. Longer type expectations-case:with_outmain:|reveal_type('abc')out:|main:1: note: Revealed type is 'builtins.str'4. Regular expressions in expectations-case:expected_message_regex_with_outregex:yesmain:|a = 'abc'reveal_type(a)out:|main:2: note: .*str.*5. Regular expressions specific lines of output.-case:expected_single_message_regexmain:|a = 'hello'reveal_type(a)  # NR: .*str.*Optionsmypy-tests:
  --mypy-testing-base=MYPY_TESTING_BASE
                        Base directory for tests to use
  --mypy-pyproject-toml-file=MYPY_PYPROJECT_TOML_FILE
                        Which `pyproject.toml` file to use
                        as a default config for tests.
                        Incompatible with `--mypy-ini-file`
  --mypy-ini-file=MYPY_INI_FILE
                        Which `.ini` file to use as a default config for tests.
                        Incompatible with `--mypy-pyproject-toml-file`
  --mypy-same-process   Run in the same process. Useful for debugging,
                        will create problems with import cache
  --mypy-extension-hook=MYPY_EXTENSION_HOOK
                        Fully qualified path to the extension hook function,
                        in case you need custom yaml keys. Has to be top-level
  --mypy-only-local-stub
                        mypy will ignore errors from site-packagesFurther readingTesting mypy stubs, plugins, and typesLicenseMIT