Black functions#

Contents are subject to change.

Assertions and checks#

black.assert_equivalent(src: str, dst: str) None#

Raise AssertionError if src and dst aren’t equivalent.

black.assert_stable(src: str, dst: str, mode: Mode) None#

Raise AssertionError if dst reformats differently the second time.

black.lines.can_be_split(line: Line) bool#

Return False if the line cannot be split for sure.

This is not an exhaustive search but a cheap heuristic that we can use to avoid some unfortunate formattings (mostly around wrapping unsplittable code in unnecessary parentheses).

black.lines.can_omit_invisible_parens(line: Line, line_length: int) bool#

Does line have a shape safe to reformat without optional parens around it?

Returns True for only a subset of potentially nice looking formattings but the point is to not return false positives that end up producing lines that are too long.

black.nodes.is_empty_tuple(node: Union[Leaf, Node]) bool#

Return True if node holds an empty tuple.

black.nodes.is_import(leaf: Leaf) bool#

Return True if the given leaf starts an import statement.

black.lines.is_line_short_enough(line: Line, *, line_length: int, line_str: str = '') bool#

Return True if line is no longer than line_length.

Uses the provided line_str rendering, if any, otherwise computes a new one.

black.nodes.is_multiline_string(leaf: Leaf) bool#

Return True if leaf is a multiline string that actually spans many lines.

black.nodes.is_one_tuple(node: Union[Leaf, Node]) bool#

Return True if node holds a tuple with one element, with or without parens.

black.brackets.is_split_after_delimiter(leaf: Leaf, previous: Optional[Leaf] = None) int#

Return the priority of the leaf delimiter, given a line break after it.

The delimiter priorities returned here are from those delimiters that would cause a line break after themselves.

Higher numbers are higher priority.

black.brackets.is_split_before_delimiter(leaf: Leaf, previous: Optional[Leaf] = None) int#

Return the priority of the leaf delimiter, given a line break before it.

The delimiter priorities returned here are from those delimiters that would cause a line break before themselves.

Higher numbers are higher priority.

black.nodes.is_stub_body(node: Union[Leaf, Node]) bool#

Return True if node is a simple statement containing an ellipsis.

black.nodes.is_stub_suite(node: Node) bool#

Return True if node is a suite with a stub body.

black.nodes.is_vararg(leaf: Leaf, within: Set[int]) bool#

Return True if leaf is a star or double star in a vararg or kwarg.

If within includes VARARGS_PARENTS, this applies to function signatures. If within includes UNPACKING_PARENTS, it applies to right hand-side extended iterable unpacking (PEP 3132) and additional unpacking generalizations (PEP 448).

black.nodes.is_yield(node: Union[Leaf, Node]) bool#

Return True if node holds a yield or yield from expression.

Formatting#

black.format_file_contents(src_contents: str, *, fast: bool, mode: Mode) str#

Reformat contents of a file and return new contents.

If fast is False, additionally confirm that the reformatted code is valid by calling assert_equivalent() and assert_stable() on it. mode is passed to format_str().

black.format_file_in_place(src: Path, fast: bool, mode: Mode, write_back: WriteBack = WriteBack.NO, lock: Optional[Any] = None) bool#

Format file under src path. Return True if changed.

If write_back is DIFF, write a diff to stdout. If it is YES, write reformatted code to the file. mode and fast options are passed to format_file_contents().

black.format_stdin_to_stdout(fast: bool, *, content: Optional[str] = None, write_back: WriteBack = WriteBack.NO, mode: Mode) bool#

Format file on stdin. Return True if changed.

If content is None, it’s read from sys.stdin.

If write_back is YES, write reformatted code back to stdout. If it is DIFF, write a diff to stdout. The mode argument is passed to format_file_contents().

black.format_str(src_contents: str, *, mode: Mode) str#

Reformat a string and return new contents.

mode determines formatting options, such as how many characters per line are allowed. Example:

>>> import black
>>> print(black.format_str("def f(arg:str='')->None:...", mode=black.Mode()))
def f(arg: str = "") -> None:
    ...

A more complex example:

>>> print(
...   black.format_str(
...     "def f(arg:str='')->None: hey",
...     mode=black.Mode(
...       target_versions={black.TargetVersion.PY36},
...       line_length=10,
...       string_normalization=False,
...       is_pyi=False,
...     ),
...   ),
... )
def f(
    arg: str = '',
) -> None:
    hey
black.reformat_one(src: Path, fast: bool, write_back: WriteBack, mode: Mode, report: Report) None#

Reformat a single file under src without spawning child processes.

fast, write_back, and mode options are passed to format_file_in_place() or format_stdin_to_stdout().

async black.concurrency.schedule_formatting(sources: Set[Path], fast: bool, write_back: WriteBack, mode: Mode, report: Report, loop: AbstractEventLoop, executor: Executor) None#

Run formatting of sources in parallel using the provided executor.

(Use ProcessPoolExecutors for actual parallelism.)

write_back, fast, and mode options are passed to format_file_in_place().

File operations#

black.dump_to_file(*output: str, ensure_final_newline: bool = True) str#

Dump output to a temporary file. Return path to the file.

black.find_project_root(srcs: Sequence[str], stdin_filename: Optional[str] = None) Tuple[Path, str]#

Return a directory containing .git, .hg, or pyproject.toml.

That directory will be a common parent of all files and directories passed in srcs.

If no directory in the tree contains a marker that would specify it’s the project root, the root of the file system is returned.

Returns a two-tuple with the first element as the project root path and the second element as a string describing the method by which the project root was discovered.

black.gen_python_files(paths: Iterable[Path], root: Path, include: Pattern[str], exclude: Pattern[str], extend_exclude: Optional[Pattern[str]], force_exclude: Optional[Pattern[str]], report: Report, gitignore_dict: Optional[Dict[Path, PathSpec]], *, verbose: bool, quiet: bool) Iterator[Path]#

Generate all files under path whose paths are not excluded by the exclude_regex, extend_exclude, or force_exclude regexes, but are included by the include regex.

Symbolic links pointing outside of the root directory are ignored.

report is where output about exclusions goes.

black.read_pyproject_toml(ctx: Context, param: Parameter, value: Optional[str]) Optional[str]#

Inject Black configuration from “pyproject.toml” into defaults in ctx.

Returns the path to a successfully found and read configuration file, None otherwise.

Parsing#

black.decode_bytes(src: bytes) Tuple[str, str, str]#

Return a tuple of (decoded_contents, encoding, newline).

newline is either CRLF or LF but decoded_contents is decoded with universal newlines (i.e. only contains LF).

black.parsing.lib2to3_parse(src_txt: str, target_versions: Iterable[TargetVersion] = ()) Node#

Given a string with source, return the lib2to3 Node.

black.parsing.lib2to3_unparse(node: Node) str#

Given a lib2to3 node, return its string representation.

Split functions#

black.linegen.bracket_split_build_line(leaves: List[Leaf], original: Line, opening_bracket: Leaf, *, component: _BracketSplitComponent) Line#

Return a new line with given leaves and respective comments from original.

If it’s the head component, brackets will be tracked so trailing commas are respected.

If it’s the body component, the result line is one-indented inside brackets and as such has its first leaf’s prefix normalized and a trailing comma added when expected.

black.linegen.bracket_split_succeeded_or_raise(head: Line, body: Line, tail: Line) None#

Raise CannotSplit if the last left- or right-hand split failed.

Do nothing otherwise.

A left- or right-hand split is based on a pair of brackets. Content before (and including) the opening bracket is left on one line, content inside the brackets is put on a separate line, and finally content starting with and following the closing bracket is put on a separate line.

Those are called head, body, and tail, respectively. If the split produced the same line (all content in head) or ended up with an empty body and the tail is just the closing bracket, then it’s considered failed.

black.linegen.delimiter_split(line: Line, features: Collection[Feature] = ()) Iterator[Line]#

Split according to delimiters of the highest priority.

If the appropriate Features are given, the split will add trailing commas also in function signatures and calls that contain * and **.

black.linegen.left_hand_split(line: Line, _features: Collection[Feature] = ()) Iterator[Line]#

Split line into many lines, starting with the first matching bracket pair.

Note: this usually looks weird, only use this for function definitions. Prefer RHS otherwise. This is why this function is not symmetrical with right_hand_split() which also handles optional parentheses.

black.linegen.right_hand_split(line: Line, line_length: int, features: Collection[Feature] = (), omit: Collection[int] = ()) Iterator[Line]#

Split line into many lines, starting with the last matching bracket pair.

If the split was by optional parentheses, attempt splitting without them, too. omit is a collection of closing bracket IDs that shouldn’t be considered for this split.

Note: running this function modifies bracket_depth on the leaves of line.

black.linegen.standalone_comment_split(line: Line, features: Collection[Feature] = ()) Iterator[Line]#

Split standalone comments from the rest of the line.

black.linegen.transform_line(line: Line, mode: Mode, features: Collection[Feature] = ()) Iterator[Line]#

Transform a line, potentially splitting it into many lines.

They should fit in the allotted line_length but might not be able to.

features are syntactical features that may be used in the output.

Caching#

black.cache.filter_cached(cache: Dict[str, Tuple[float, int]], sources: Iterable[Path]) Tuple[Set[Path], Set[Path]]#

Split an iterable of paths in sources into two sets.

The first contains paths of files that modified on disk or are not in the cache. The other contains paths to non-modified files.

black.cache.get_cache_dir() Path#

Get the cache directory used by black.

Users can customize this directory on all systems using BLACK_CACHE_DIR environment variable. By default, the cache directory is the user cache directory under the black application.

This result is immediately set to a constant black.cache.CACHE_DIR as to avoid repeated calls.

black.cache.get_cache_file(mode: Mode) Path#
black.cache.get_cache_info(path: Path) Tuple[float, int]#

Return the information used to check if a file is already formatted or not.

black.cache.read_cache(mode: Mode) Dict[str, Tuple[float, int]]#

Read the cache if it exists and is well formed.

If it is not well formed, the call to write_cache later should resolve the issue.

black.cache.write_cache(cache: Dict[str, Tuple[float, int]], sources: Iterable[Path], mode: Mode) None#

Update the cache file.

Utilities#

black.debug.DebugVisitor.show(code: str) None#

Pretty-print the lib2to3 AST of a given string of code.

black.concurrency.cancel(tasks: Iterable[asyncio.Task[Any]]) None#

asyncio signal handler that cancels all tasks and reports to stderr.

black.nodes.child_towards(ancestor: Node, descendant: Union[Leaf, Node]) Optional[Union[Leaf, Node]]#

Return the child of ancestor that contains descendant.

black.nodes.container_of(leaf: Leaf) Union[Leaf, Node]#

Return leaf or one of its ancestors that is the topmost container of it.

By “container” we mean a node where leaf is the very first child.

black.comments.convert_one_fmt_off_pair(node: Node, *, preview: bool) bool#

Convert content of a single # fmt: off/# fmt: on into a standalone comment.

Returns True if a pair was converted.

black.diff(a: str, b: str, a_name: str, b_name: str) str#

Return a unified diff string between strings a and b.

black.linegen.dont_increase_indentation(split_func: Callable[[Line, Collection[Feature]], Iterator[Line]]) Callable[[Line, Collection[Feature]], Iterator[Line]]#

Normalize prefix of the first leaf in every line returned by split_func.

This is a decorator over relevant split functions.

black.numerics.format_float_or_int_string(text: str) str#

Formats a float string like “1.0”.

black.nodes.ensure_visible(leaf: Leaf) None#

Make sure parentheses are visible.

They could be invisible as part of some statements (see normalize_invisible_parens() and visit_import_from()).

black.lines.enumerate_reversed(sequence: Sequence[T]) Iterator[Tuple[int, T]]#

Like reversed(enumerate(sequence)) if that were possible.

black.comments.generate_comments(leaf: Union[Leaf, Node], *, preview: bool) Iterator[Leaf]#

Clean the prefix of the leaf and generate comments from it, if any.

Comments in lib2to3 are shoved into the whitespace prefix. This happens in pgen2/driver.py:Driver.parse_tokens(). This was a brilliant implementation move because it does away with modifying the grammar to include all the possible places in which comments can be placed.

The sad consequence for us though is that comments don’t “belong” anywhere. This is why this function generates simple parentless Leaf objects for comments. We simply don’t know what the correct parent should be.

No matter though, we can live without this. We really only need to differentiate between inline and standalone comments. The latter don’t share the line with any code.

Inline comments are emitted as regular token.COMMENT leaves. Standalone are emitted with a fake STANDALONE_COMMENT token identifier.

black.comments.generate_ignored_nodes(leaf: Leaf, comment: ProtoComment, *, preview: bool) Iterator[Union[Leaf, Node]]#

Starting from the container of leaf, generate all leaves until # fmt: on.

If comment is skip, returns leaf only. Stops at the end of the block.

black.comments.is_fmt_on(container: Union[Leaf, Node], preview: bool) bool#

Determine whether formatting is switched on within a container. Determined by whether the last # fmt: comment is on or off.

black.comments.children_contains_fmt_on(container: Union[Leaf, Node], *, preview: bool) bool#

Determine if children have formatting switched on.

black.nodes.first_leaf_of(node: Union[Leaf, Node]) Optional[Leaf]#

Returns the first leaf of the node tree.

black.linegen.generate_trailers_to_omit(line: Line, line_length: int) Iterator[Set[int]]#

Generate sets of closing bracket IDs that should be omitted in a RHS.

Brackets can be omitted if the entire trailer up to and including a preceding closing bracket fits in one line.

Yielded sets are cumulative (contain results of previous yields, too). First set is empty, unless the line should explode, in which case bracket pairs until the one that needs to explode are omitted.

black.get_future_imports(node: Node) Set[str]#

Return a set of __future__ imports in the file.

black.comments.list_comments(prefix: str, *, is_endmarker: bool, preview: bool) List[ProtoComment]#

Return a list of ProtoComment objects parsed from the given prefix.

black.comments.make_comment(content: str, *, preview: bool) str#

Return a consistently formatted comment from the given content string.

All comments (except for “##”, “#!”, “#:”, ‘#’”) should have a single space between the hash sign and the content.

If content didn’t start with a hash sign, one is provided.

black.linegen.maybe_make_parens_invisible_in_atom(node: Union[Leaf, Node], parent: Union[Leaf, Node], remove_brackets_around_comma: bool = False) bool#

If it’s safe, make the parens in the atom node invisible, recursively. Additionally, remove repeated, adjacent invisible parens from the atom node as they are redundant.

Returns whether the node should itself be wrapped in invisible parentheses.

black.brackets.max_delimiter_priority_in_atom(node: Union[Leaf, Node]) int#

Return maximum delimiter priority inside node.

This is specific to atoms with contents contained in a pair of parentheses. If node isn’t an atom or there are no enclosing parentheses, returns 0.

black.normalize_fmt_off(node: Node, *, preview: bool) None#

Convert content between # fmt: off/# fmt: on into standalone comments.

black.numerics.normalize_numeric_literal(leaf: Leaf) None#

Normalizes numeric (float, int, and complex) literals.

All letters used in the representation are normalized to lowercase.

black.linegen.normalize_prefix(leaf: Leaf, *, inside_brackets: bool) None#

Leave existing extra newlines if not inside_brackets. Remove everything else.

Note: don’t use backslashes for formatting or you’ll lose your voting rights.

black.strings.normalize_string_prefix(s: str) str#

Make all string prefixes lowercase.

black.strings.normalize_string_quotes(s: str) str#

Prefer double quotes but only if it doesn’t cause more escaping.

Adds or removes backslashes as appropriate. Doesn’t parse and fix strings nested in f-strings.

black.linegen.normalize_invisible_parens(node: Node, parens_after: Set[str], *, preview: bool) None#

Make existing optional parentheses invisible or create new ones.

parens_after is a set of string leaf values immediately after which parens should be put.

Standardizes on visible parentheses for single-element tuples, and keeps existing visible parentheses for other tuples and generator expressions.

black.patch_click() None#

Make Click not crash on Python 3.6 with LANG=C.

On certain misconfigured environments, Python 3 selects the ASCII encoding as the default which restricts paths that it can access during the lifetime of the application. Click refuses to work in this scenario by raising a RuntimeError.

In case of Black the likelihood that non-ASCII characters are going to be used in file paths is minimal since it’s Python source code. Moreover, this crash was spurious on Python 3.7 thanks to PEP 538 and PEP 540.

black.nodes.preceding_leaf(node: Optional[Union[Leaf, Node]]) Optional[Leaf]#

Return the first leaf that precedes node, if any.

black.re_compile_maybe_verbose(regex: str) Pattern[str]#

Compile a regular expression string in regex.

If it contains newlines, use verbose mode.

black.linegen.should_split_line(line: Line, opening_bracket: Leaf) bool#

Should line be immediately split with delimiter_split() after RHS?

black.concurrency.shutdown(loop: AbstractEventLoop) None#

Cancel all pending tasks on loop, wait for them, and close the loop.

black.strings.sub_twice(regex: Pattern[str], replacement: str, original: str) str#

Replace regex with replacement twice on original.

This is used by string normalization to perform replaces on overlapping matches.

black.nodes.whitespace(leaf: Leaf, *, complex_subscript: bool) str#

Return whitespace prefix if needed for the given leaf.

complex_subscript signals whether the given leaf is part of a subscription which has non-trivial arguments, like arithmetic expressions or function calls.