Search code examples
pythonpython-3.xmypypre-commitpre-commit.com

Run mypy from pre-commit for different directories


I have the following structure for my project:

project/
├── backend
│   ├── api_v1
│   ├── api_v2
│   └── api_v3
└── frontend

Each of the API dirs, api_v1, api_v2, and api_v3, have python files.

I would like to run pre-commit for each of these directories only if there is a change in the code. For eg., I would like to run mypy -p api_v1 if there is a change in the directory api_v1. I'm aware of the keys files and types of the pre-commit, but I cannot figure out a way to run mypy as if it was running from the directory backend. Also, I cannot run mypy separately for api_v1, api_v2, or api_v3, when I have changes in more than 1 of these directories.

Is it not possible or am


Solution

  • pre-commit operates on files so what you're trying to do isn't exactly supported but anything is possible. when not running on files you're going to take some efficiency concessions as you'll be linting much more often than you need to be

    here's a rough sketch for how you would do this:

    -   repo: https://github.com/pre-commit/mirrors-mypy
        rev: ...
        hooks:
        -   id: mypy
            pass_filenames: false  # suppress the normal filename passing
            files: ^backend/api_v1/  # filter the files down to a specific subdirectory
            # pre-commit only supports running at the root of a repo since that's where
            # git hooks run.  but it also allows running arbitrary code so you can
            # step outside of those bounds
            # note that `bash` will reduce your portability slightly
            entry: bash -c 'cd backend && mypy -p api_v1 "$@"' --
    
        # and then repeat ...
        -   id: mypy
            pass_filenames: false
            files: ^backend/api_v2/
            entry: bash -c 'cd backend && mypy -p api_v2 "$@"' --
    
        # etc.
    

    disclaimer: I wrote pre-commit