Black: Adapter for pre-commit

Created on 4 Apr 2018  路  17Comments  路  Source: psf/black

I'm not sure if its doable today (given explicit Python 3.6 requirement), but would be great to provide out of the box support for the pre-commit framework: https://pre-commit.com/

All 17 comments

@asottile, hi! Would it be acceptable for me to submit a hook for Black like this one:

https://github.com/pre-commit/pre-commit-hooks/blob/master/pre_commit_hooks/autopep8_wrapper.py

Note that Black requires Python 3.6.0 to work.

This tool looks really cool!

pre-commit has a language_version option which would allow you to require python3.6. Though for a more "future proof" solution, maybe just documentation is enough? (since python3.7 is coming soon and would presumably work. Since it has specific requirements, calling out language_version in the documentation on black's side is probably useful)

Ideally the .pre-commit-hooks.yaml metadata would be added to this repository (such that it's more "official") (I can help with this too!) -- once that's done, we can add it to the official list of hooks via https://github.com/pre-commit/pre-commit.github.io

Let me know if you'd like assistance with this!

Note that the autopep8-wrapper adapter was only necessary because older versions of pre-commit did not detect modifications, it's essentially obsoleted now but sticks around because lots of things use it :S

it's essentially obsoleted now but sticks around because lots of things use it :S

Thanks to this is gets extra visibility though ;) Also, it comes alphabetically first. Therefore, I'd name my plugin aaactually_you_want_black 馃槃

More seriously though, if I wrote a hook like the autopep8 one, I could try to import black first before shelling out. If the import is successful, running Black from within the process is going to be faster. Let me know what you think.

Can you also explain what "mirrors" like https://github.com/pre-commit/mirrors-yapf are for? The name "mirror" suggests to me "FTP mirrors" from old days but this is not what those repositories are.

The ideal situation is that upstream linters provide metadata directly in the repository -- the mirror repositories are to bridge that gap while pre-commit gained popularity (heh), I haven't gone back and tried to upstream metadata in a while (been busy with work). They're a bit of a silly unfortunate hack that's stayed around.

One question about black, does it allow execution like black f1.py f2.py f3.py? (this is how pre-commit will attempt to invoke it) -- if not, it'd be cool to add this feature (I can help with this too!)

Alright, let me add a .pre-commit-hooks.yaml then. Black supports passing multiple files. It outputs human readable messages on stderr. It returns with exit code 0 unless there's an internal error (or --check was used).

And I assume modifies files to fix the formatting? If so -- that's perfect for pre-commit 馃憤

Yes, it modifies files in place.

@asottile will the language version bits work if e.g. one tool requires python 2 and another requires python 3? My hope was you could run black within the pre-commit framework completely sandboxed as long as python 3.6 exists somewhere on the system

Yep, the version of the pre-commit tool itself is completely separate from the hooks it runs. It can also run hooks in any number of languages and language versions.

I don't have any open source examples of mine, but this is an (anonymized) excerpt from a closed source configuration I'm using:

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v1.2.3
    hooks:
    -   id: flake8
    -   id: check-ast
        language_version: python2.7
        files: ^devbox/.*\.py$

(Note that here it's using flake8 via python3.6 (since that's what we're running pre-commit with), but a few files need to be python2.7 compatible so check-ast is used to keep those in line).

Each (repository, rev, language_version, additional_dependencies) quadruplet gets its own isolated environment

@asottile: if I say "python3.6" today, it will stay on 3.6 even after 3.7 is out, right? Any way I can say: "whatever version 3.6+"?

there isn't currently a way to express that to virtualenv unfortunately so it's probably just something that needs to be documented instead

@asottile could you override the version? e.g. have it default to python 3.6 but let the user specify it? I assume you'd have to specify it if it wasnt documented anyways?

(been a while since I configured pre-commit)

My main use case is I'd like to run this with the https://github.com/getsentry/responses project (assuming it doesn't cause any obvious pain) to replace yapf. That project by default runs on Python 2, so I'd want to ensure pre-commit for at least this very specific case is using something other than the default python on my system (which is symlinked to 2).

yep, any defaults provided by the hook can be overridden in the consuming repository's .pre-commit-config.yaml

Looks like there might be an issue w/ implementation:

$ pre-commit run
black................................................(no files to check)Skipped
Fix End of Files.........................................................Passed
Trim Trailing Whitespace.................................................Passed
Debug Statements (Python)............................(no files to check)Skipped
Flake8...............................................(no files to check)Skipped

https://github.com/getsentry/responses/pull/199

Oops, I think I know what pre-commit run is doing now, ignore me.

pre-commit run will only look at staged files, I believe you want pre-commit run --all-files

Was this page helpful?
0 / 5 - 0 ratings