X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/5bc40707afa5fb53bbc2484ed34f69b011b98172..1dadeef47aafeef1c52c64db9aef3b038bd609ea:/README.md diff --git a/README.md b/README.md index 70668f3..9f72a67 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,20 @@ -# black +![Black Logo](https://raw.githubusercontent.com/ambv/black/master/docs/_static/logo2-readme.png) +

The Uncompromising Code Formatter

-[![Build Status](https://travis-ci.org/ambv/black.svg?branch=master)](https://travis-ci.org/ambv/black) +

+Build Status +Documentation Status +Coverage Status +License: MIT +PyPI +Code style: black +

-> Any color you like. +> “Any color you like.” *Black* is the uncompromising Python code formatter. By using it, you -agree to cease control over minutiae of hand-formatting. In return, +agree to cede control over minutiae of hand-formatting. In return, *Black* gives you speed, determinism, and freedom from `pycodestyle` nagging about formatting. You will save time and mental energy for more important matters. @@ -19,43 +27,73 @@ content instead. possible. -## NOTE: This is an early pre-release +## Installation and Usage -*Black* can already successfully format itself and the standard library. -It also sports a decent test suite. However, it is still very new. -Things will probably be wonky for a while. This is made explicit by the -"Alpha" trove classifier, as well as by the "a" in the version number. -What this means for you is that **until the formatter becomes stable, -you should expect some formatting to change in the future**. +### Installation -Also, as a temporary safety measure, *Black* will check that the -reformatted code still produces a valid AST that is equivalent to the -original. This slows it down. If you're feeling confident, use -``--fast``. +*Black* can be installed by running `pip install black`. It requires +Python 3.6.0+ to run but you can reformat Python 2 code with it, too. -## Usage +### Usage -*Black* can be installed by running `pip install black`. +To get started right away with sensible defaults: ``` +black {source_file_or_directory} +``` + +### Command line options + +Black doesn't provide many options. You can list them by running +`black --help`: + +```text black [OPTIONS] [SRC]... Options: -l, --line-length INTEGER Where to wrap around. [default: 88] - --check Don't write back the files, just return the - status. Return code 0 means nothing changed. - Return code 1 means some files were reformatted. - Return code 123 means there was an internal - error. + --check Don't write the files back, just return the + status. Return code 0 means nothing would + change. Return code 1 means some files would be + reformatted. Return code 123 means there was an + internal error. + --diff Don't write the files back, just output a diff + for each file on stdout. --fast / --safe If --fast given, skip temporary sanity checks. [default: --safe] + -q, --quiet Don't emit non-error messages to stderr. Errors + are still emitted, silence those with + 2>/dev/null. --version Show the version and exit. --help Show this message and exit. ``` +*Black* is a well-behaved Unix-style command-line tool: +* it does nothing if no sources are passed to it; +* it will read from standard input and write to standard output if `-` + is used as the filename; +* it only outputs messages to users on standard error; +* exits with code 0 unless an internal error occurred (or `--check` was + used). + -## The philosophy behind *Black* +### NOTE: This is an early pre-release + +*Black* can already successfully format itself and the standard library. +It also sports a decent test suite. However, it is still very new. +Things will probably be wonky for a while. This is made explicit by the +"Alpha" trove classifier, as well as by the "a" in the version number. +What this means for you is that **until the formatter becomes stable, +you should expect some formatting to change in the future**. + +Also, as a temporary safety measure, *Black* will check that the +reformatted code still produces a valid AST that is equivalent to the +original. This slows it down. If you're feeling confident, use +``--fast``. + + +## The *Black* code style *Black* reformats entire files in place. It is not configurable. It doesn't take previous formatting into account. It doesn't reformat @@ -64,24 +102,27 @@ recognizes [YAPF](https://github.com/google/yapf)'s block comments to the same effect, as a courtesy for straddling code. -### How *Black* formats files +### How *Black* wraps lines *Black* ignores previous formatting and applies uniform horizontal and vertical whitespace to your code. The rules for horizontal -whitespace are pretty obvious and can be summarized as: do whatever -makes `pycodestyle` happy. +whitespace can be summarized as: do whatever makes `pycodestyle` happy. +The coding style used by *Black* can be viewed as a strict subset of +PEP 8. As for vertical whitespace, *Black* tries to render one full expression or simple statement per line. If this fits the allotted line length, great. ```py3 # in: + l = [1, 2, 3, ] # out: + l = [1, 2, 3] ``` @@ -89,9 +130,11 @@ If not, *Black* will look at the contents of the first outer matching brackets and put that in a separate indented line. ```py3 # in: + l = [[n for n in list_bosses()], [n for n in list_employees()]] # out: + l = [ [n for n in list_bosses()], [n for n in list_employees()] ] @@ -106,12 +149,14 @@ matching brackets. If that doesn't work, it will put all of them in separate lines. ```py3 # in: + def very_important_function(template: str, *variables, file: os.PathLike, debug: bool = False): """Applies `variables` to the `template` and writes to `file`.""" with open(file, 'w') as f: ... # out: + def very_important_function( template: str, *variables, @@ -119,7 +164,7 @@ def very_important_function( debug: bool = False, ): """Applies `variables` to the `template` and writes to `file`.""" - with open(file, 'w') as f: + with open(file, "w") as f: ... ``` @@ -131,19 +176,13 @@ between two distinct sections of the code that otherwise share the same indentation level (like the arguments list and the docstring in the example above). -Unnecessary trailing commas are removed if an expression fits in one -line. This makes it 1% more likely that your line won't exceed the -allotted line length limit. - -*Black* avoids spurious vertical whitespace. This is in the spirit of -PEP 8 which says that in-function vertical whitespace should only be -used sparingly. One exception is control flow statements: *Black* will -always emit an extra empty line after ``return``, ``raise``, ``break``, -``continue``, and ``yield``. This is to make changes in control flow -more prominent to readers of your code. - -That's it. The rest of the whitespace formatting rules follow PEP 8 and -are designed to keep `pycodestyle` quiet. +If a line of "from" imports cannot fit in the allotted length, it's always split +into one per line. Imports tend to change often and this minimizes diffs, as well +as enables readers of code to easily find which commit introduced a particular +import. This exception also makes *Black* compatible with +[isort](https://pypi.org/p/isort/). Use `multi_line_output=3`, +`include_trailing_comma=True`, `force_grid_wrap=0`, and `line_length=88` in your +isort config. ### Line length @@ -183,14 +222,315 @@ explains it. The tl;dr is "it's like highway speed limits, we won't bother you if you overdo it by a few km/h". -### Editor integration +### Empty lines + +*Black* avoids spurious vertical whitespace. This is in the spirit of +PEP 8 which says that in-function vertical whitespace should only be +used sparingly. + +*Black* will allow single empty lines inside functions, and single and +double empty lines on module level left by the original editors, except +when they're within parenthesized expressions. Since such expressions +are always reformatted to fit minimal space, this whitespace is lost. + +It will also insert proper spacing before and after function definitions. +It's one line before and after inner functions and two lines before and +after module-level functions. *Black* will not put empty lines between +function/class definitions and standalone comments that immediately precede +the given function/class. + + +### Trailing commas + +*Black* will add trailing commas to expressions that are split +by comma where each element is on its own line. This includes function +signatures. + +Unnecessary trailing commas are removed if an expression fits in one +line. This makes it 1% more likely that your line won't exceed the +allotted line length limit. Moreover, in this scenario, if you added +another argument to your call, you'd probably fit it in the same line +anyway. That doesn't make diffs any larger. + +One exception to removing trailing commas is tuple expressions with +just one element. In this case *Black* won't touch the single trailing +comma as this would unexpectedly change the underlying data type. Note +that this is also the case when commas are used while indexing. This is +a tuple in disguise: ```numpy_array[3, ]```. + +One exception to adding trailing commas is function signatures +containing `*`, `*args`, or `**kwargs`. In this case a trailing comma +is only safe to use on Python 3.6. *Black* will detect if your file is +already 3.6+ only and use trailing commas in this situation. If you +wonder how it knows, it looks for f-strings and existing use of trailing +commas in function signatures that have stars in them. In other words, +if you'd like a trailing comma in this situation and *Black* didn't +recognize it was safe to do so, put it there manually and *Black* will +keep it. + +### Strings + +*Black* prefers double quotes (`"` and `"""`) over single quotes (`'` +and `'''`). It will replace the latter with the former as long as it +does not result in more backslash escapes than before. + +*Black* also standardizes string prefixes, making them always lowercase. +On top of that, if your code is already Python 3.6+ only or it's using +the `unicode_literals` future import, *Black* will remove `u` from the +string prefix as it is meaningless in those scenarios. + +The main reason to standardize on a single form of quotes is aesthetics. +Having one kind of quotes everywhere reduces reader distraction. +It will also enable a future version of *Black* to merge consecutive +string literals that ended up on the same line (see +[#26](https://github.com/ambv/black/issues/26) for details). + +Why settle on double quotes? They anticipate apostrophes in English +text. They match the docstring standard described in PEP 257. An +empty string in double quotes (`""`) is impossible to confuse with +a one double-quote regardless of fonts and syntax highlighting used. +On top of this, double quotes for strings are consistent with C which +Python interacts a lot with. + +On certain keyboard layouts like US English, typing single quotes is +a bit easier than double quotes. The latter requires use of the Shift +key. My recommendation here is to keep using whatever is faster to type +and let *Black* handle the transformation. + +### Line Breaks & Binary Operators + +*Black* will break a line before a binary operator when splitting a block +of code over multiple lines. This is so that *Black* is compliant with the +recent changes in the [PEP 8](https://www.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-a-binary-operator) +style guide, which emphasizes that this approach improves readability. + +This behaviour may raise ``W503 line break before binary operator`` warnings in +style guide enforcement tools like Flake8. Since ``W503`` is not PEP 8 compliant, +you should tell Flake8 to ignore these warnings. + +### Slices + +PEP 8 [recommends](https://www.python.org/dev/peps/pep-0008/#whitespace-in-expressions-and-statements) +to treat ``:`` in slices as a binary operator with the lowest priority, and to +leave an equal amount of space on either side, except if a parameter is omitted +(e.g. ``ham[1 + 1 :]``). It also states that for extended slices, both ``:`` +operators have to have the same amount of spacing, except if a parameter is +omitted (``ham[1 + 1 ::]``). *Black* enforces these rules consistently. + +This behaviour may raise ``E203 whitespace before ':'`` warnings in style guide +enforcement tools like Flake8. Since ``E203`` is not PEP 8 compliant, you should +tell Flake8 to ignore these warnings. + +### Parentheses + +Some parentheses are optional in the Python grammar. Any expression can +be wrapped in a pair of parentheses to form an atom. There are a few +interesting cases: + +- `if (...):` +- `while (...):` +- `for (...) in (...):` +- `assert (...), (...)` +- `from X import (...)` +- assignments like: + - `target = (...)` + - `target: type = (...)` + - `some, *un, packing = (...)` + - `augmented += (...)` + +In those cases, parentheses are removed when the entire statement fits +in one line, or if the inner expression doesn't have any delimiters to +further split on. Otherwise, the parentheses are always added. + +### Typing stub files + +PEP 484 describes the syntax for type hints in Python. One of the +use cases for typing is providing type annotations for modules which +cannot contain them directly (they might be written in C, or they might +be third-party, or their implementation may be overly dynamic, and so on). + +To solve this, [stub files with the `.pyi` file +extension](https://www.python.org/dev/peps/pep-0484/#stub-files) can be +used to describe typing information for an external module. Those stub +files omit the implementation of classes and functions they +describe, instead they only contain the structure of the file (listing +globals, functions, and classes with their members). The recommended +code style for those files is more terse than PEP 8: + +* prefer `...` on the same line as the class/function signature; +* avoid vertical whitespace between consecutive module-level functions, + names, or methods and fields within a single class; +* use a single blank line between top-level class definitions, or none + if the classes are very small. + +*Black* enforces the above rules. There are additional guidelines for +formatting `.pyi` file that are not enforced yet but might be in +a future version of the formatter: + +* all function bodies should be empty (contain `...` instead of the body); +* do not use docstrings; +* prefer `...` over `pass`; +* for arguments with a default, use `...` instead of the actual default; +* avoid using string literals in type annotations, stub files support + forward references natively (like Python 3.7 code with `from __future__ + import annotations`); +* use variable annotations instead of type comments, even for stubs that + target older versions of Python; +* for arguments that default to `None`, use `Optional[]` explicitly; +* use `float` instead of `Union[int, float]`. + + +## Editor integration + +### Emacs + +Use [proofit404/blacken](https://github.com/proofit404/blacken). + + +### PyCharm + +1. Install `black`. + + $ pip install black + +2. Locate your `black` installation folder. + + On MacOS / Linux / BSD: + + $ which black + /usr/local/bin/black # possible location + + On Windows: + + $ where black + %LocalAppData%\Programs\Python\Python36-32\Scripts\black.exe # possible location + +3. Open External tools in PyCharm with `File -> Settings -> Tools -> External Tools`. + +4. Click the + icon to add a new external tool with the following values: + - Name: Black + - Description: Black is the uncompromising Python code formatter. + - Program: + - Arguments: $FilePath$ + +5. Format the currently opened file by selecting `Tools -> External Tools -> black`. + - Alternatively, you can set a keyboard shortcut by navigating to `Preferences -> Keymap`. + + +### Vim + +Commands and shortcuts: + +* `,=` or `:Black` to format the entire file (ranges not supported); +* `:BlackUpgrade` to upgrade *Black* inside the virtualenv; +* `:BlackVersion` to get the current version of *Black* inside the + virtualenv. + +Configuration: +* `g:black_fast` (defaults to `0`) +* `g:black_linelength` (defaults to `88`) +* `g:black_virtualenv` (defaults to `~/.vim/black`) + +To install with [vim-plug](https://github.com/junegunn/vim-plug): + +``` +Plug 'ambv/black', +``` + +or with [Vundle](https://github.com/VundleVim/Vundle.vim): + +``` +Plugin 'ambv/black' +``` + +or you can copy the plugin from [plugin/black.vim](https://github.com/ambv/black/tree/master/plugin/black.vim). +Let me know if this requires any changes to work with Vim 8's builtin +`packadd`, or Pathogen, and so on. + +This plugin **requires Vim 7.0+ built with Python 3.6+ support**. It +needs Python 3.6 to be able to run *Black* inside the Vim process which +is much faster than calling an external command. + +On first run, the plugin creates its own virtualenv using the right +Python version and automatically installs *Black*. You can upgrade it later +by calling `:BlackUpgrade` and restarting Vim. + +If you need to do anything special to make your virtualenv work and +install *Black* (for example you want to run a version from master), +create a virtualenv manually and point `g:black_virtualenv` to it. +The plugin will use it. + +**How to get Vim with Python 3.6?** +On Ubuntu 17.10 Vim comes with Python 3.6 by default. +On macOS with HomeBrew run: `brew install vim --with-python3`. +When building Vim from source, use: +`./configure --enable-python3interp=yes`. There's many guides online how +to do this. + + +### Visual Studio Code + +Use [joslarson.black-vscode](https://marketplace.visualstudio.com/items?itemName=joslarson.black-vscode). + +### SublimeText 3 + +Use [sublack plugin](https://github.com/jgirardet/sublack). + +### IPython Notebook Magic + +Use [blackcellmagic](https://github.com/csurfer/blackcellmagic). + +### Other editors -There is currently no integration with any text editors. Vim and -Atom/Nuclide integration is planned by the author, others will require -external contributions. +Atom/Nuclide integration is planned by the author, others will +require external contributions. Patches welcome! ✨ 🍰 ✨ +Any tool that can pipe code through *Black* using its stdio mode (just +[use `-` as the file name](http://www.tldp.org/LDP/abs/html/special-chars.html#DASHREF2)). +The formatted code will be returned on stdout (unless `--check` was +passed). *Black* will still emit messages on stderr but that shouldn't +affect your use case. + +This can be used for example with PyCharm's [File Watchers](https://www.jetbrains.com/help/pycharm/file-watchers.html). + + +## Version control integration + +Use [pre-commit](https://pre-commit.com/). Once you [have it +installed](https://pre-commit.com/#install), add this to the +`.pre-commit-config.yaml` in your repository: +```yaml +repos: +- repo: https://github.com/ambv/black + rev: stable + hooks: + - id: black + args: [--line-length=88, --safe] + python_version: python3.6 +``` +Then run `pre-commit install` and you're ready to go. + +`args` in the above config is optional but shows you how you can change +the line length if you really need to. If you're already using Python +3.7, switch the `python_version` accordingly. Finally, `stable` is a tag +that is pinned to the latest release on PyPI. If you'd rather run on +master, this is also an option. + + +## Ignoring non-modified files + +*Black* remembers files it already formatted, unless the `--diff` flag is used or +code is passed via standard input. This information is stored per-user. The exact +location of the file depends on the black version and the system on which black +is run. The file is non-portable. The standard location on common operating systems +is: + +* Windows: `C:\\Users\\AppData\Local\black\black\Cache\\cache..pickle` +* macOS: `/Users//Library/Caches/black//cache..pickle` +* Linux: `/home//.cache/black//cache..pickle` + ## Testimonials @@ -213,25 +553,15 @@ and [`pipenv`](https://docs.pipenv.org/): > This vastly improves the formatting of our code. Thanks a ton! -## Tests +## Show your style -Just run: +Use the badge in your project's README.md: -``` -python setup.py test +```markdown +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) ``` -## This tool requires Python 3.6.0+ to run - -But you can reformat Python 2 code with it, too. *Black* is able to parse -all of the new syntax supported on Python 3.6 but also *effectively all* -the Python 2 syntax at the same time, as long as you're not using print -statements. - -By making the code exclusively Python 3.6+, I'm able to focus on the -quality of the formatting and re-use all the nice features of the new -releases (check out [pathlib](https://docs.python.org/3/library/pathlib.html) or -f-strings) instead of wasting cycles on Unicode compatibility, and so on. +Looks like this: [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) ## License @@ -239,10 +569,10 @@ f-strings) instead of wasting cycles on Unicode compatibility, and so on. MIT -## Contributing +## Contributing to Black -In terms of inspiration, *Black* is about as configurable as *gofmt* and -*rustfmt* are. This is deliberate. +In terms of inspiration, *Black* is about as configurable as *gofmt*. +This is deliberate. Bug reports and fixes are always welcome! However, before you suggest a new feature or configuration knob, ask yourself why you want it. If it @@ -257,6 +587,164 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md). ## Change Log +### 18.5a0 (unreleased) + +* slices are now formatted according to PEP 8 (#178) + +* parentheses are now also managed automatically on the right-hand side + of assignments and return statements (#140) + +* math operators now use their respective priorities for delimiting multiline + expressions (#148) + +* optional parentheses are now omitted on expressions that start or end + with a bracket and only contain a single operator (#177) + +* empty parentheses in a class definition are now removed (#145, #180) + +* string prefixes are now standardized to lowercase and `u` is removed + on Python 3.6+ only code and Python 2.7+ code with the `unicode_literals` + future import (#188, #198, #199) + +* typing stub files (`.pyi`) are now formatted in a style that is consistent + with PEP 484 (#207, #210) + +* progress when reformatting many files is now reported incrementally + +* fixed trailers (content with brackets) being unnecessarily exploded + into their own lines after a dedented closing bracket (#119) + +* fixed an invalid trailing comma sometimes left in imports (#185) + +* fixed non-deterministic formatting when multiple pairs of removable parentheses + were used (#183) + +* fixed not splitting long from-imports with only a single name + +* fixed Python 3.6+ file discovery by also looking at function calls with + unpacking. This fixed non-deterministic formatting if trailing commas + where used both in function signatures with stars and function calls + with stars but the former would be reformatted to a single line. + +* fixed crash on dealing with optional parentheses (#193) + +* fixed "is", "is not", "in", and "not in" not considered operators for + splitting purposes + +* fixed crash when dead symlinks where encountered + + +### 18.4a4 + +* don't populate the cache on `--check` (#175) + + +### 18.4a3 + +* added a "cache"; files already reformatted that haven't changed on disk + won't be reformatted again (#109) + +* `--check` and `--diff` are no longer mutually exclusive (#149) + +* generalized star expression handling, including double stars; this + fixes multiplication making expressions "unsafe" for trailing commas (#132) + +* Black no longer enforces putting empty lines behind control flow statements + (#90) + +* Black now splits imports like "Mode 3 + trailing comma" of isort (#127) + +* fixed comment indentation when a standalone comment closes a block (#16, #32) + +* fixed standalone comments receiving extra empty lines if immediately preceding + a class, def, or decorator (#56, #154) + +* fixed `--diff` not showing entire path (#130) + +* fixed parsing of complex expressions after star and double stars in + function calls (#2) + +* fixed invalid splitting on comma in lambda arguments (#133) + +* fixed missing splits of ternary expressions (#141) + + +### 18.4a2 + +* fixed parsing of unaligned standalone comments (#99, #112) + +* fixed placement of dictionary unpacking inside dictionary literals (#111) + +* Vim plugin now works on Windows, too + +* fixed unstable formatting when encountering unnecessarily escaped quotes + in a string (#120) + + +### 18.4a1 + +* added `--quiet` (#78) + +* added automatic parentheses management (#4) + +* added [pre-commit](https://pre-commit.com) integration (#103, #104) + +* fixed reporting on `--check` with multiple files (#101, #102) + +* fixed removing backslash escapes from raw strings (#100, #105) + + +### 18.4a0 + +* added `--diff` (#87) + +* add line breaks before all delimiters, except in cases like commas, to + better comply with PEP 8 (#73) + +* standardize string literals to use double quotes (almost) everywhere + (#75) + +* fixed handling of standalone comments within nested bracketed + expressions; Black will no longer produce super long lines or put all + standalone comments at the end of the expression (#22) + +* fixed 18.3a4 regression: don't crash and burn on empty lines with + trailing whitespace (#80) + +* fixed 18.3a4 regression: `# yapf: disable` usage as trailing comment + would cause Black to not emit the rest of the file (#95) + +* when CTRL+C is pressed while formatting many files, Black no longer + freaks out with a flurry of asyncio-related exceptions + +* only allow up to two empty lines on module level and only single empty + lines within functions (#74) + + +### 18.3a4 + +* `# fmt: off` and `# fmt: on` are implemented (#5) + +* automatic detection of deprecated Python 2 forms of print statements + and exec statements in the formatted file (#49) + +* use proper spaces for complex expressions in default values of typed + function arguments (#60) + +* only return exit code 1 when --check is used (#50) + +* don't remove single trailing commas from square bracket indexing + (#59) + +* don't omit whitespace if the previous factor leaf wasn't a math + operator (#55) + +* omit extra space in kwarg unpacking if it's the first argument (#46) + +* omit extra space in [Sphinx auto-attribute comments](http://www.sphinx-doc.org/en/stable/ext/autodoc.html#directive-autoattribute) + (#68) + + ### 18.3a3 * don't remove single empty lines outside of bracketed expressions @@ -329,3 +817,23 @@ More details can be found in [CONTRIBUTING](CONTRIBUTING.md). ## Authors Glued together by [Łukasz Langa](mailto:lukasz@langa.pl). + +Maintained with [Carol Willing](mailto:carolcode@willingconsulting.com), +[Carl Meyer](mailto:carl@oddbird.net), +[Mika Naylor](mailto:mail@autophagy.io), and +[Zsolt Dollenstein](mailto:zsol.zsol@gmail.com). + +Multiple contributions by: +* [Anthony Sottile](mailto:asottile@umich.edu) +* [Artem Malyshev](mailto:proofit404@gmail.com) +* [Christian Heimes](mailto:christian@python.org) +* [Daniel M. Capella](mailto:polycitizen@gmail.com) +* [Eli Treuherz](mailto:eli.treuherz@cgi.com) +* Hugo van Kemenade +* [Ivan Katanić](mailto:ivan.katanic@gmail.com) +* [Jelle Zijlstra](mailto:jelle.zijlstra@gmail.com) +* [Jonas Obrist](mailto:ojiidotch@gmail.com) +* [Miguel Gaiowski](mailto:miggaiowski@gmail.com) +* [Osaetin Daniel](mailto:osaetindaniel@gmail.com) +* [Sunil Kapil](mailto:snlkapil@gmail.com) +* [Vishwas B Sharma](mailto:sharma.vishwas88@gmail.com)