49

I want to configure black in pre-commit and exclude precommit from checking any migrations folder.

My pyproject.toml looks like this

[tool.black]
line-length = 79
target-version = ['py37']
include = '\.pyi?$'
exclude = '''

(
  /(
      \.eggs
    | \.git
    | \.hg
    | \.mypy_cache
    | \.tox
    | \.venv
    | _build
    | buck-out
    | build
    | dist
  )/
  | ^migrations/
'''

I have also configured precommit. But on running pre-commit run --all-files Black formats the migration folders also how can I configure black

anthony sottile
  • 61,815
  • 15
  • 148
  • 207
Suyash Salampuria
  • 765
  • 2
  • 6
  • 9

2 Answers2

108

This issue on the black issue tracker outlines your particular problem

pre-commit finds all the python files, then applies pre-commit's exclusion, and then passes that list of files to the underlying tools (in this case black)

black currently (at the time of writing) will format all files listed on the command line -- independent of black's exclude pattern

the suggestion is to use pre-commit's exclusion (via your .pre-commit-config.yaml) such that those files are never passed to black at all:

-   id: black
    exclude: ^migrations/

note: unlike black, pre-commit will only ever lint files which are checked into your git repository, so the laundry list of exclusion is unnecessary here (.git / .mypy_cache / etc.)


disclaimer: I'm the author of pre-commit

vvvvv
  • 25,404
  • 19
  • 49
  • 81
anthony sottile
  • 61,815
  • 15
  • 148
  • 207
  • 9
    dumb question but, how do I exclude multiple directories – Jam M. Hernandez Quiceno Feb 17 '21 at 18:03
  • 37
    @JamM.HernandezQuiceno `exclude` is a regular expression, so you'd use `|` -- for example: `exclude: ^(migrations/|other/folder/)` -- more on this [in the docs](https://pre-commit.com/#regular-expressions) – anthony sottile Feb 17 '21 at 19:14
  • Thanks! This works also well for `pydocstyle` – felice Jan 19 '22 at 11:35
  • 1
    @AnthonySottile request you add this example to the docs. I tried the regex approach (?x)^(...) for a mix of files and folders and couldn't get it working. I found your answer here and it worked like a charm. – Brent Jan 27 '22 at 22:43
  • 2
    it is in the docs: https://pre-commit.com/#regular-expressions – anthony sottile Jan 28 '22 at 02:32
  • I'm getting "did not find expected '-' indicator" when trying to do exactly as you did in my .pre-commit-config.yaml – allinws Dec 20 '22 at 08:23
  • @allinws sounds like you made invalid yaml -- I can't help without seeing the full file though and could only guess at the many ways you can make invalid yaml – anthony sottile Dec 20 '22 at 18:49
  • It would be a helluva lot nicer if `exclude` allowed globs or a YAML list of paths. – wheeler Feb 01 '23 at 18:52
  • globs are less powerful, and lists are ambiguous -- so no it would not be "nicer" -- it would be more complex, and more confusing – anthony sottile Feb 01 '23 at 21:36
  • No, lists are not "ambiguous". And no it would not be confusing. The actual thing that is more confusing is requiring multi-lined regexes to specify multiple, well-defined paths. – wheeler Feb 02 '23 at 09:41
  • I'm in favor of simplicity over complexity--requiring someone to know special non-Yaml syntax inside of a Yaml file for something that could be very easily accomplished with a Yaml list, is the very definition of complexity. – wheeler Feb 02 '23 at 09:46
  • It looks like you had an opportunity to improve the `excludes` syntax with pre-commit/pre-commit#591, but sadly you rejected it in favor of more complex syntax. – wheeler Feb 02 '23 at 09:50
  • lists are ambigious -- is it "and" or "or" -- as someone who has spent literal years thinking about these problems please trust that you do not know what you're talking about. also there is no "non-yaml" syntax -- there is no extension of the parser whatsoever. there is *one way to do things* and that is best. – anthony sottile Feb 02 '23 at 14:13
10

Currently, you can use black option --force-exclude. As indicated in the documentation:

--force-exclude TEXT Like --exclude, but files and directories matching this regex will be excluded even when they are passed explicitly as arguments.

So, in your pyproject.toml change exclude to force-exclude.