Try running Nitpick with the new Command-line interface instead of a flake8 plugin.

In the future, there are plans to make flake8 an optional dependency.

Flake8 plugin

Nitpick is not a proper flake8 plugin; it piggybacks on flake8’s messaging system though.

Flake8 lints Python files; Nitpick “lints” configuration (text) files instead.

To act like a flake8 plugin, Nitpick does the following:

  1. Find any Python file in your project;

  2. Use the first Python file found and ignore other Python files in the project.

  3. Check the style file and compare with the configuration/text files.

  4. Report violations on behalf of that Python file, and not on the configuration file that’s actually wrong.

So, if you have a violation on setup.cfg, it will be reported like this:

./ NIP323 File setup.cfg: [flake8]max-line-length is 80 but it should be like this:
max-line-length = 120

Notice the at the beginning of the line, and not setup.cfg.


To run Nitpick as a Flake8 plugin, the project must have at least one Python file*.

If your project is not a Python project, creating a file on the root of the project is enough.

Pre-commit hook and flake8

Currently, the default pre-commit hook uses flake8 in an unconventional and not recommended way.

It calls flake8 directly:

flake8 --select=NIP

This current default pre-commit hook (called nitpick) is a placeholder for the future, when flake8 will be only an optional dependency.

Why always_run: true?

This in intentional, because Nitpick is not a conventional flake8 plugin.

Since flake8 only lints Python files, the pre-commit hook will only run when a Python file is modified. It won’t run when a config/text changes.

An example: suppose you’re using a remote Nitpick style (like the style from WeMake).

At the moment, their style currently checks setup.cfg only.

Suppose they change or add an option on their isort.toml file.

If the nitpick pre-commit hook had always_run: false and pass_filenames: true, your local setup.cfg would only be verified:

  1. If a Python file was changed.

  2. If you ran pre-commit run --all-files.

So basically the pre-commit hook would be useless to guarantee that your config files would always match the remote style… which is precisely the purpose of Nitpick.


To avoid this, use the other pre-commit hooks, the ones that call the Nitpick CLI directly instead of running flake8.

Root dir of the project

Nitpick tries to find the root dir of the project using some hardcoded assumptions.

  1. Starting from the current working directory, it will search for files that are usually in the root of a project:

  • .pre-commit-config.yaml (pre-commit)

  • pyproject.toml


  • setup.cfg

  • requirements*.txt

  • Pipfile (Pipenv)

  • tox.ini (tox)

  • package.json (JavaScript, NodeJS)

  • Cargo.* (Rust)

  • go.mod, go.sum (Golang)

  • and (Flask CLI)

  • (Flask)

  1. If none of these root files were found, search for On Django projects, it can be in another dir inside the root dir (issue 21).

  2. If multiple roots are found, get the top one in the dir tree.

Main Python file

After finding the root dir of the project, Nitpick searches for a main Python file. Every project must have at least one *.py file, otherwise flake8 won’t even work.

Those are the Python files that are considered:


  • and (Flask CLI)



  • any *.py file