'mypy - erroring when there are no Python files

Is there a way to stop mypy erroring when it doesn't find any .py files? In essence, this isn't an error. What Im looking to do is hide or silence this one error.

$ poetry run mypy .
There are no .py[i] files in directory '.'
Error: Process completed with exit code 2.

Thanks,



Solution 1:[1]

From mypy's source it doesn't look like there is any way to do this from mypy directly. The function that reports the error does provide an argument for ignoring this error, but the argument is only passed from within tests https://github.com/python/mypy/blob/99f4d5af147d364eda1d4b99e79770c171896f13/mypy/find_sources.py#L20-L47.

Without ignoring other errors, as far as I can tell you'd have to submit each path to mypy individually (if you're passing it multiple) and ignore the 2 error code if it reports the error you want to ignore.

Patching mypy would be an another option, but mypy is precompiled through mypyc so you'd have to get rid of the binaries and lose out on a bunch of performance with monkey-patching, or build it yourself with the function changed and install the patched module.

Solution 2:[2]

You can install mypy without the binaries, but it's going to be slower.

python3 -m pip install --no-binary mypy -U mypy

Once this is installed, you can create a patch, say mypy-custom.py like so:

import sys
from typing import List, Optional, Sequence

import mypy.main
from mypy.modulefinder import BuildSource
from mypy.fscache import FileSystemCache
from mypy.options import Options


orig_create_source_list = mypy.main.create_source_list

def create_source_list(paths: Sequence[str], options: Options,
                       fscache: Optional[FileSystemCache] = None,
                       allow_empty_dir: bool = True) -> List[BuildSource]:
    return orig_create_source_list(paths, options, fscache, allow_empty_dir)

mypy.main.create_source_list = create_source_list

mypy.main.main(None, sys.stdout, sys.stderr)

The patched version should be called with:

python mypy-custom.py [<options>] <path>

If you pass a folder without any .py files, you should get an exit code of 0 with the following output:

Nothing to do?!
Success: no issues found in 0 source files

As suggested by @Numerlor, the patch can also be written like so:

import sys
from functools import partial

import mypy.find_sources
from mypy import api


orig_create_source_list = mypy.find_sources.create_source_list

create_source_list = partial(orig_create_source_list, allow_empty_dir=True)

mypy.find_sources.create_source_list = create_source_list

result = api.run(sys.argv[1:])

if result[0]:
    print(result[0])
    
if result[1]:
    print(result[1])
    
exit(result[2])

With this patch, the allow_empty_dir=False option becomes unavailable to the rest of the module, but it doesn't seem to break anything... yet!

Solution 3:[3]

The patching method has a major inconvenient of negating the benefit of compiled libraries.

To avoid this, you could use a bash script that checks for the presence of .py files in the directory tree before calling mypy:

#! /bin/bash

if [ -n "$(find "$1" -type f -name '*.py')" ]; then 
  mypy "$@"
fi

With this, you would have to pass the directory as the first argument, then the options.

If you want the folder to be the last argument, you can substitute "$1" with "${*: -1}" in the find command.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Numerlor
Solution 2
Solution 3