diff --git a/README.md b/README.md index d74d436..1cd1ef0 100644 --- a/README.md +++ b/README.md @@ -27,33 +27,28 @@ 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**. - -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``. - - -## Installation +### Installation *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. -*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. -## Usage +### Usage +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: @@ -78,7 +73,22 @@ Options: 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 @@ -87,12 +97,13 @@ 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. +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, @@ -160,20 +171,6 @@ 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. - ### Line length @@ -214,6 +211,13 @@ bother you if you overdo it by a few km/h". ### 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. 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. + *Black* will allow single empty lines left by the original editors, except when they're added within parenthesized expressions. Since such expressions are always reformatted to fit minimal space, this whitespace @@ -228,7 +232,36 @@ entire function, use a docstring or put a leading comment in the function body. -### Editor integration +### 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. + + +## Editor integration * Visual Studio Code: [joslarson.black-vscode](https://marketplace.visualstudio.com/items?itemName=joslarson.black-vscode) * Emacs: [proofit404/blacken](https://github.com/proofit404/blacken) @@ -282,7 +315,7 @@ Looks like this: [![Code style: black](https://img.shields.io/badge/code%20style MIT -## Contributing +## Contributing to Black In terms of inspiration, *Black* is about as configurable as *gofmt* and *rustfmt* are. This is deliberate. diff --git a/docs/authors.md b/docs/authors.md new file mode 120000 index 0000000..704a421 --- /dev/null +++ b/docs/authors.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/authors.md \ No newline at end of file diff --git a/docs/change_log.md b/docs/change_log.md new file mode 120000 index 0000000..36bf3dc --- /dev/null +++ b/docs/change_log.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/change_log.md \ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md deleted file mode 100644 index af78900..0000000 --- a/docs/changelog.md +++ /dev/null @@ -1,93 +0,0 @@ -## Change Log - -### 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 - (#19) - -* added ability to pipe formatting from stdin to stdin (#25) - -* restored ability to format code with legacy usage of `async` as - a name (#20, #42) - -* even better handling of numpy-style array indexing (#33, again) - - -### 18.3a2 - -* changed positioning of binary operators to occur at beginning of lines - instead of at the end, following [a recent change to PEP8](https://github.com/python/peps/commit/c59c4376ad233a62ca4b3a6060c81368bd21e85b) - (#21) - -* ignore empty bracket pairs while splitting. This avoids very weirdly - looking formattings (#34, #35) - -* remove a trailing comma if there is a single argument to a call - -* if top level functions were separated by a comment, don't put four - empty lines after the upper function - -* fixed unstable formatting of newlines with imports - -* fixed unintentional folding of post scriptum standalone comments - into last statement if it was a simple statement (#18, #28) - -* fixed missing space in numpy-style array indexing (#33) - -* fixed spurious space after star-based unary expressions (#31) - - -### 18.3a1 - -* added `--check` - -* only put trailing commas in function signatures and calls if it's - safe to do so. If the file is Python 3.6+ it's always safe, otherwise - only safe if there are no `*args` or `**kwargs` used in the signature - or call. (#8) - -* fixed invalid spacing of dots in relative imports (#6, #13) - -* fixed invalid splitting after comma on unpacked variables in for-loops - (#23) - -* fixed spurious space in parenthesized set expressions (#7) - -* fixed spurious space after opening parentheses and in default - arguments (#14, #17) - -* fixed spurious space after unary operators when the operand was - a complex expression (#15) - - -### 18.3a0 - -* first published version, Happy 🍰 Day 2018! - -* alpha quality - -* date-versioned (see: https://calver.org/) diff --git a/docs/conf.py b/docs/conf.py index 5d0e9e3..6edddba 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,6 +15,7 @@ import ast from pathlib import Path import re +import shutil import string from recommonmark.parser import CommonMarkParser @@ -40,6 +41,48 @@ def make_pypi_svg(version): f.write(svg) +def make_filename(line): + non_letters = re.compile(r'[^a-z]+') + filename = line[3:].rstrip().lower() + filename = non_letters.sub('_', filename) + if filename.startswith('_'): + filename = filename[1:] + if filename.endswith('_'): + filename = filename[:-1] + return filename + '.md' + + +def generate_sections_from_readme(): + target_dir = CURRENT_DIR / '_build' / 'generated' + readme = CURRENT_DIR / '..' / 'README.md' + shutil.rmtree(str(target_dir), ignore_errors=True) + target_dir.mkdir(parents=True) + + output = None + with open(str(readme), 'r', encoding='utf8') as f: + for line in f: + if line.startswith('## '): + if output is not None: + output.close() + filename = make_filename(line) + output_path = CURRENT_DIR / filename + if output_path.is_symlink() or output_path.is_file(): + output_path.unlink() + output_path.symlink_to(target_dir / filename) + output = open(str(output_path), 'w', encoding='utf8') + output.write( + '[//]: # (NOTE: THIS FILE IS AUTOGENERATED FROM README.md)\n\n' + ) + + if output is None: + continue + + if line.startswith('##'): + line = line[1:] + + output.write(line) + + # -- Project information ----------------------------------------------------- project = 'Black' @@ -54,6 +97,7 @@ def make_pypi_svg(version): for sp in 'abcfr': version = version.split(sp)[0] make_pypi_svg(release) +generate_sections_from_readme() # -- General configuration --------------------------------------------------- diff --git a/docs/contributing_to_black.md b/docs/contributing_to_black.md new file mode 120000 index 0000000..079bd4a --- /dev/null +++ b/docs/contributing_to_black.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/contributing_to_black.md \ No newline at end of file diff --git a/docs/editor_integration.md b/docs/editor_integration.md new file mode 120000 index 0000000..e234140 --- /dev/null +++ b/docs/editor_integration.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/editor_integration.md \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 7a0995b..9422402 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -16,7 +16,7 @@ can focus on the content instead. .. note:: - `Black is an early pre-release `_. + `Black is an early pre-release `_. Testimonials @@ -46,10 +46,12 @@ Contents .. toctree:: :maxdepth: 2 - usage - technical_philosophy + installation_and_usage + the_black_code_style + editor_integration contributing - changelog + change_log + authors Indices and tables diff --git a/docs/installation_and_usage.md b/docs/installation_and_usage.md new file mode 120000 index 0000000..64caa30 --- /dev/null +++ b/docs/installation_and_usage.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/installation_and_usage.md \ No newline at end of file diff --git a/docs/license.md b/docs/license.md new file mode 120000 index 0000000..cf360a1 --- /dev/null +++ b/docs/license.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/license.md \ No newline at end of file diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt deleted file mode 100644 index 5e5376b..0000000 --- a/docs/requirements-docs.txt +++ /dev/null @@ -1,2 +0,0 @@ -sphinx>=1.7 -recommonmark==0.4.0 \ No newline at end of file diff --git a/docs/show_your_style.md b/docs/show_your_style.md new file mode 120000 index 0000000..15ad1c1 --- /dev/null +++ b/docs/show_your_style.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/show_your_style.md \ No newline at end of file diff --git a/docs/technical_philosophy.md b/docs/technical_philosophy.md deleted file mode 100644 index 1052f0c..0000000 --- a/docs/technical_philosophy.md +++ /dev/null @@ -1,167 +0,0 @@ -# Technical Overview - -## The philosophy behind *Black* - -*Black* reformats entire files in place. It is not configurable. It -doesn't take previous formatting into account. It doesn't reformat -blocks that start with `# fmt: off` and end with `# fmt: on`. It also -recognizes [YAPF](https://github.com/google/yapf)'s block comments to -the same effect, as a courtesy for straddling code. - -## How *Black* formats files - -*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. - -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] -``` - -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()] -] -``` - -If that still doesn't fit the bill, it will decompose the internal -expression further using the same rule, indenting matching brackets -every time. If the contents of the matching brackets pair are -comma-separated (like an argument list, or a dict literal, and so on) -then *Black* will first try to keep them on the same line with the -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, - file: os.PathLike, - debug: bool = False, -): - """Applies `variables` to the `template` and writes to `file`.""" - with open(file, 'w') as f: - ... -``` - -You might have noticed that closing brackets are always dedented and -that a trailing comma is always added. Such formatting produces smaller -diffs; when you add or remove an element, it's always just one line. -Also, having the closing bracket dedented provides a clear delimiter -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. - -## Line length - -You probably noticed the peculiar default line length. *Black* defaults -to 88 characters per line, which happens to be 10% over 80. This number -was found to produce significantly shorter files than sticking with 80 -(the most popular), or even 79 (used by the standard library). In -general, [90-ish seems like the wise choice](https://youtu.be/wf-BqAjZb8M?t=260). - -If you're paid by the line of code you write, you can pass -`--line-length` with a lower number. *Black* will try to respect that. -However, sometimes it won't be able to without breaking other rules. In -those rare cases, auto-formatted code will exceed your allotted limit. - -You can also increase it, but remember that people with sight disabilities -find it harder to work with line lengths exceeding 100 characters. -It also adversely affects side-by-side diff review on typical screen -resolutions. Long lines also make it harder to present code neatly -in documentation or talk slides. - -If you're using Flake8, you can bump `max-line-length` to 88 and forget -about it. Alternatively, use [Bugbear](https://github.com/PyCQA/flake8-bugbear)'s -B950 warning instead of E501 and keep the max line length at 80 which -you are probably already using. You'd do it like this: - -```ini -[flake8] -max-line-length = 80 -... -select = C,E,F,W,B,B950 -ignore = E501 -``` - -You'll find *Black*'s own .flake8 config file is configured like this. -If you're curious about the reasoning behind B950, Bugbear's documentation -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". - -## Empty lines - -*Black* will allow single empty lines left by the original editors, -except when they're added 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 put those empty lines also -between the function definition and any standalone comments that -immediately precede the given function. If you want to comment on the -entire function, use a docstring or put a leading comment in the function -body. - -## Editor integration - -* Visual Studio Code: [joslarson.black-vscode](https://marketplace.visualstudio.com/items?itemName=joslarson.black-vscode) - -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. - -There is currently no integration with any other text editors. Vim and -Atom/Nuclide integration is planned by the author, others will require -external contributions. - -Patches welcome! ✨ 🍰 ✨ diff --git a/docs/testimonials.md b/docs/testimonials.md new file mode 120000 index 0000000..03fc5ae --- /dev/null +++ b/docs/testimonials.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/testimonials.md \ No newline at end of file diff --git a/docs/the_black_code_style.md b/docs/the_black_code_style.md new file mode 120000 index 0000000..29b288b --- /dev/null +++ b/docs/the_black_code_style.md @@ -0,0 +1 @@ +/Users/ambv/Dropbox (Personal)/Python/black/docs/_build/generated/the_black_code_style.md \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md deleted file mode 100644 index 69ce846..0000000 --- a/docs/usage.md +++ /dev/null @@ -1,64 +0,0 @@ -# Installation and Usage - -## Installation - -*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 - -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 -Usage: black [OPTIONS] [SRC]... - - The uncompromising code formatter. - -Options: - -l, --line-length INTEGER How many character per line to allow. - [default: 88] - --check Don't write back the files, 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. - --fast / --safe If --fast given, skip temporary sanity checks. - [default: --safe] - --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 occured (or `--check` was - used). - - -## NOTE: This tool is alpha quality at the moment - -*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``.