20

I'm trying to set up mypy type checking for a project. I want to exclude a bunch of files/directories to start so that we can at least enforce that type checking passes on new code, then we can burn down the exclude list over time. Unfortunately mypy is ignoring my exclude configuration and I can't figure out why.

I've created a mypy.ini config file with the following content:

[mypy]
python_version = 3.8
exclude = /examples/

But when I run mypy --verbose ., it still discovers and errors on files in that directory. The log messages tell me it is seeing my exclude configuration but apparently ignoring it:

LOG:  Mypy Version:           0.812
LOG:  Config File:            mypy.ini
LOG:  Configured Executable:  /Library/Developer/CommandLineTools/usr/bin/python
3
LOG:  Current Executable:     /Library/Developer/CommandLineTools/usr/bin/python
3
LOG:  Cache Dir:              .mypy_cache
LOG:  Compiled:               True
LOG:  Exclude:                /examples/
<snipped>
LOG:  Found source:           BuildSource(path='./examples/fib.py', module='fib', has_text=False, base_dir='/Users/user/a/examples')
LOG:  Found source:           BuildSource(path='./examples/fib_iter.py', module='fib_iter', has_text=False, base_dir='/Users/user/a/examples')
<snipped>
examples/fib.py: error: Duplicate module named 'fib' (also at './examples/a/fib.py')
examples/fib.py: note: Are you missing an __init__.py? Alternatively, consider using --exclude to avoid checking one of them.
Found 1 error in 1 file (errors prevented further checking)

Why is my exclude configuration not working?

Eddie Aftandilian
  • 219
  • 1
  • 2
  • 4
  • 4
    Because "/examples/" is an absolute path that starts at the root of the file system. You want either `"./examples/"` or just `"examples/"`. – Tim Roberts Apr 16 '21 at 19:11
  • 2
    Huh, you're right: `examples/` works (but `./examples/` does not). I used the `/examples/` format because that's what the docs said to do: https://mypy.readthedocs.io/en/stable/command_line.html#cmdoption-mypy-exclude Could you please post your comment as an answer so I can accept it? – Eddie Aftandilian Apr 16 '21 at 21:11

3 Answers3

14

for my case, even though I was correctly excluding the folder, mypy was still checking it because it was being imported in a separate package where mypy was enabled.

So let's say the folder I want to exclude (which is also a package) is called examples. To exclude it, I would need to add the following to the mypy.ini file

[mypy]
python_version = 3.8
exclude = examples/

But this wasn't enough to keep mypy from checking it because, I had a separate package (which mypy was allowed to check) importing the examples folder.

So to fix the issue I also had to set follow_imports = silent in the mypy.ini file like so:

[mypy-examples.*]
follow_imports = skip

This would tell mypy to skip the type check of the examples package whenever it is found imported anywhere else in the codebase.

ifedapo olarewaju
  • 3,031
  • 1
  • 21
  • 25
8

You should not use /examples/, instead you should use either examples/ or examples, because the first one is asking to exclude a path at the root of the file system. Meanwhile the other ones declare a local path and mypy can treat folders as files so you can omit the / symbol if you want.

mypy.ini

[mypy]
python_version = 3.8
exclude = examples/

If you change your mypy.ini file to this one, it should work.

Bernardo Duarte
  • 4,074
  • 4
  • 19
  • 34
6

Just leaving another answer here for folks like me who are using pre-commit with mypy.

Took me a while to realize that pre-commit sends all changed files explicitly as parameters to mypy, thereby bypassing the exclude setting since the files aren't discovered recursively.
So if you want to exclude files when running mypy from pre-commit you need to set the excludes in your .pre-commit-config.yaml like this (for a django project):

- repo: https://github.com/pre-commit/mirrors-mypy
  rev: v1.0.0
  hooks:
  - id: mypy
    exclude: "/migrations/.*\\.py"
swenzel
  • 6,745
  • 3
  • 23
  • 37
  • thank you!! Took me a while too to figure out why my regex in config file isn't working. This is the right answer. – Bruno Gelb Jul 11 '23 at 04:29