8000 Inject a test that checks the mypy exit status by dmtucker · Pull Request #79 · realpython/pytest-mypy · GitHub
[go: up one dir, main page]

Skip to content

Inject a test that checks the mypy exit status #79

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 8, 2020

Conversation

dmtucker
Copy link
Collaborator
@dmtucker dmtucker commented Mar 1, 2020

Fix #69

From the Mypy docs,

Mypy is designed to doggedly follow all imports, even if the imported module is not a file you explicitly wanted mypy to check.

This is problematic because, if mypy reports errors in a file pytest didn't collect, pytest-mypy has no MypyItem (now MypyFileItem) to match the errors to, and, if there are no other errors to report, the plugin may not force the correct pytest exit status!

To remedy that, this injects a new MypyStatusItem which just checks the mypy exit status and fails if it's nonzero. This means that an extra test will run for every --mypy invocation. Also, both MypyStatusItem and the new MypyFileItem inherit from MypyItem, so some existing checks that currently check for MypyItems may need to be updated to check for MypyFileItems.

@dmtucker dmtucker added this to the 0.6.0 milestone Mar 1, 2020
@dmtucker
Copy link
Collaborator Author
dmtucker commented Mar 1, 2020

There are a couple other nuances to this that I'll highlight:

  • --mypy now affects collection only.
    • CLI options are not checked in pytest_collection_modifyitems, which means that mypy will still run on MypyFileItems injected in any pytest_colleciton_modifyitems implementations.
      • To avoid this, check the CLI options manually before injecting, or invoke pytest_collect_file directly:
        # conftest.py
        import py
        
        def pytest_collection_modifyitems(session, config, items):
            plugin = config.pluginmanager.getplugin('mypy')
            item = plugin.pytest_collect_file(py.path.local('foo.py'), session)
            if item:
                items.append(item)
        Remember, though, that pytest_collect_file will only collect .py.
  • That ☝️ enables a recipe for using the Mypy files directive (related: Running mypy only on certain files #67, cc: @brianmaissy):
    [mypy]
    files = foo.py  # not in tests/
    # conftest.py
    def pytest_collection_modifyitems(session, config, items):
        plugin = config.pluginmanager.getplugin('mypy')
        items.append(
            plugin.MypyStatusItem(plugin.nodeid_name, session, config, session),
        )
    pytest tests/  # no --mypy
    The conftest.py causes mypy to be run on all MypyFileItems, but, since --mypy wasn't passed, there are no MypyFileItems! That means mypy is called without any arguments (by the injected MypyStatusItem) which activates the files directive.

@dmtucker dmtucker merged commit 26c4cbf into realpython:master Mar 8, 2020
@dmtucker dmtucker deleted the status branch March 8, 2020 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

mypy errors do not fail pytest build when using ignore_missing_imports = true
1 participant
0