X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/fe24a15b84955130f23c8ab9490d1cdb98607b53..66aa676278948368dff251dffd58c850cb8b889e:/black.py diff --git a/black.py b/black.py index 8855c37..c4b9132 100644 --- a/black.py +++ b/black.py @@ -6,7 +6,6 @@ from enum import Enum, Flag from functools import lru_cache, partial, wraps import io import itertools -import keyword import logging from multiprocessing import Manager, freeze_support import os @@ -15,6 +14,7 @@ import pickle import re import signal import sys +import tempfile import tokenize from typing import ( Any, @@ -160,7 +160,9 @@ def read_pyproject_toml( pyproject_toml = toml.load(value) config = pyproject_toml.get("tool", {}).get("black", {}) except (toml.TomlDecodeError, OSError) as e: - raise click.BadOptionUsage(f"Error reading configuration file: {e}", ctx) + raise click.FileError( + filename=value, hint=f"Error reading configuration file: {e}" + ) if not config: return None @@ -775,9 +777,7 @@ class DebugVisitor(Visitor[T]): list(v.visit(code)) -KEYWORDS = set(keyword.kwlist) WHITESPACE = {token.DEDENT, token.INDENT, token.NEWLINE} -FLOW_CONTROL = {"return", "raise", "break", "continue"} STATEMENT = { syms.if_stmt, syms.while_stmt, @@ -1606,7 +1606,7 @@ BRACKETS = OPENING_BRACKETS | CLOSING_BRACKETS ALWAYS_NO_SPACE = CLOSING_BRACKETS | {token.COMMA, STANDALONE_COMMENT} -def whitespace(leaf: Leaf, *, complex_subscript: bool) -> str: # noqa C901 +def whitespace(leaf: Leaf, *, complex_subscript: bool) -> str: # noqa: C901 """Return whitespace prefix if needed for the given `leaf`. `complex_subscript` signals whether the given leaf is part of a subscription @@ -2110,8 +2110,19 @@ def split_line( return line_str = str(line).strip("\n") - if not line.should_explode and is_line_short_enough( - line, line_length=line_length, line_str=line_str + + # we don't want to split special comments like type annotations + # https://github.com/python/typing/issues/186 + has_special_comment = False + for leaf in line.leaves: + for comment in line.comments_after(leaf): + if leaf.type == token.COMMA and is_special_comment(comment): + has_special_comment = True + + if ( + not has_special_comment + and not line.should_explode + and is_line_short_enough(line, line_length=line_length, line_str=line_str) ): yield line return @@ -2460,6 +2471,16 @@ def is_import(leaf: Leaf) -> bool: ) +def is_special_comment(leaf: Leaf) -> bool: + """Return True if the given leaf is a special comment. + Only returns true for type comments for now.""" + t = leaf.type + v = leaf.value + return bool( + (t == token.COMMENT or t == STANDALONE_COMMENT) and (v.startswith("# type:")) + ) + + def normalize_prefix(leaf: Leaf, *, inside_brackets: bool) -> None: """Leave existing extra newlines if not `inside_brackets`. Remove everything else. @@ -2949,6 +2970,7 @@ def ensure_visible(leaf: Leaf) -> None: def should_explode(line: Line, opening_bracket: Leaf) -> bool: """Should `line` immediately be split with `delimiter_split()` after RHS?""" + if not ( opening_bracket.parent and opening_bracket.parent.type in {syms.atom, syms.import_from} @@ -3626,11 +3648,11 @@ def write_cache( """Update the cache file.""" cache_file = get_cache_file(line_length, mode) try: - if not CACHE_DIR.exists(): - CACHE_DIR.mkdir(parents=True) + CACHE_DIR.mkdir(parents=True, exist_ok=True) new_cache = {**cache, **{src.resolve(): get_cache_info(src) for src in sources}} - with cache_file.open("wb") as fobj: - pickle.dump(new_cache, fobj, protocol=pickle.HIGHEST_PROTOCOL) + with tempfile.NamedTemporaryFile(dir=str(cache_file.parent), delete=False) as f: + pickle.dump(new_cache, f, protocol=pickle.HIGHEST_PROTOCOL) + os.replace(f.name, cache_file) except OSError: pass