From c98a6f134f4b2b831e7e659de0c217c118270a61 Mon Sep 17 00:00:00 2001 From: Carol Willing Date: Fri, 23 Mar 2018 14:27:04 -0700 Subject: [PATCH] add sphinx docs skeleton (#71) --- .gitignore | 2 + docs/Makefile | 20 ++++ docs/changelog.md | 91 +++++++++++++++ docs/conf.py | 208 +++++++++++++++++++++++++++++++++++ docs/contributors_guide.md | 9 ++ docs/index.rst | 63 +++++++++++ docs/make.bat | 36 ++++++ docs/requirements-docs.txt | 2 + docs/technical_philosophy.md | 167 ++++++++++++++++++++++++++++ docs/usage.md | 59 ++++++++++ 10 files changed, 657 insertions(+) create mode 100644 docs/Makefile create mode 100644 docs/changelog.md create mode 100644 docs/conf.py create mode 100644 docs/contributors_guide.md create mode 100644 docs/index.rst create mode 100644 docs/make.bat create mode 100644 docs/requirements-docs.txt create mode 100644 docs/technical_philosophy.md create mode 100644 docs/usage.md diff --git a/.gitignore b/.gitignore index 6350e98..88f07d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ .coverage +_build +.DS_Store \ No newline at end of file diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..2e0e5ee --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = black +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..df5262f --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1,91 @@ +## Change Log + +### 18.3a4 (unreleased) + +* 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 new file mode 100644 index 0000000..efb6359 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,208 @@ +# -*- coding: utf-8 -*- +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +import os +import sys + +import recommonmark + + +sys.path.insert(0, os.path.abspath('.' )) + +# -- Project information ----------------------------------------------------- + +project = 'Black' +copyright = '2018, Łukasz Langa and contributors to Black' +author = 'Łukasz Langa and contributors to Black' + +# Autopopulate version +import black +# The short X.Y version. +# TODO: fix for 2 digit month +version = f'{black.__version__[:4]}' +# The full version, including alpha/beta/rc tags. +release = black.__version__ + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.intersphinx', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +source_parsers = { + '.md': 'recommonmark.parser.CommonMarkParser', +} + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +source_suffix = ['.rst', '.md'] + +# The master toctree document. +master_doc = 'index' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path . +exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' + +html_sidebars = { + '**': [ + 'about.html', + 'navigation.html', + 'relations.html', + 'sourcelink.html', + 'searchbox.html' + ] +} + +html_theme_options = { + 'show_related': True, + 'description': 'The uncompromising Python code formatter', + 'github_user': 'ambv', + 'github_repo': 'black', + 'github_button': True, + 'show_powered_by': True, + 'fixed_sidebar': True, +} + + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Custom sidebar templates, must be a dictionary that maps document names +# to template names. +# +# The default sidebars (for documents that don't match any pattern) are +# defined by theme itself. Builtin themes are using these templates by +# default: ``['localtoc.html', 'relations.html', 'sourcelink.html', +# 'searchbox.html']``. +# +# html_sidebars = {} + + +# -- Options for HTMLHelp output --------------------------------------------- + +# Output file base name for HTML help builder. +htmlhelp_basename = 'blackdoc' + + +# -- Options for LaTeX output ------------------------------------------------ + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'black.tex', 'Documentation for Black', + 'Łukasz Langa and contributors to Black', 'manual'), +] + + +# -- Options for manual page output ------------------------------------------ + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'black', 'Documentation for black', + [author], 1) +] + + +# -- Options for Texinfo output ---------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'Black', 'Documentation for Black', + author, 'Black', 'The uncompromising Python code formatter', + 'Miscellaneous'), +] + + +# -- Options for Epub output ------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + + +# -- Extension configuration ------------------------------------------------- + +# -- Options for intersphinx extension --------------------------------------- + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/3/': None} \ No newline at end of file diff --git a/docs/contributors_guide.md b/docs/contributors_guide.md new file mode 100644 index 0000000..6b82bb4 --- /dev/null +++ b/docs/contributors_guide.md @@ -0,0 +1,9 @@ +# Contributors Guide + +## Tests + +Just run: + +```bash +python setup.py test +``` \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..0106c9c --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,63 @@ +.. black documentation master file, created by + sphinx-quickstart on Fri Mar 23 10:53:30 2018. + +Black +===== + +**Black** is the uncompromising Python code formatter. + +By using *Black*, you +agree to cease 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. + +*Black* makes code review faster by producing the smallest diffs +possible. Blackened code looks the same regardless of the project +you're reading. Formatting becomes transparent after a while and you +can focus on the content instead. + +.. note:: + + Black is an early pre-release. + + +Testimonials +------------ + +**Dusty Phillips**, `writer `_: + + *Black is opinionated so you don't have to be.* + +**Hynek Schlawack**, creator of `attrs `_, core +developer of Twisted and CPython: + + *An auto-formatter that doesn't suck is all I want for Xmas!* + +**Carl Meyer**, `Django `_ core developer: + + *At least the name is good.* + +**Kenneth Reitz**, creator of `requests `_ +and `pipenv `_: + + *This vastly improves the formatting of our code. Thanks a ton!* + +Contents +-------- + +.. toctree:: + :maxdepth: 2 + + usage + technical_philosophy + contributors_guide + changelog + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..eecd650 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=black + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt new file mode 100644 index 0000000..5e5376b --- /dev/null +++ b/docs/requirements-docs.txt @@ -0,0 +1,2 @@ +sphinx>=1.7 +recommonmark==0.4.0 \ No newline at end of file diff --git a/docs/technical_philosophy.md b/docs/technical_philosophy.md new file mode 100644 index 0000000..1052f0c --- /dev/null +++ b/docs/technical_philosophy.md @@ -0,0 +1,167 @@ +# 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/usage.md b/docs/usage.md new file mode 100644 index 0000000..c27c744 --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,59 @@ +# Installation and Usage + +## Installation + +*Black* can be installed by running `pip install black`. + +## Usage + +To get started right away with sensible defaults: + +``` +black {source_file} +``` + +### Command line options + +Some basics about the command line help, `black --help`: + +``` +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). + +## Important note about the pre-release of Black + +*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``. -- 2.39.2