X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/ae5588cf073be10b51dc48ad2fc513e11c4f3e03..788f87cb58dbdb20df8adbb9ab4efaee1c5e00f2:/black.py?ds=sidebyside diff --git a/black.py b/black.py index 71f42ef..ff373c8 100644 --- a/black.py +++ b/black.py @@ -12,7 +12,7 @@ from multiprocessing import Manager, freeze_support import os from pathlib import Path import pickle -import re +import regex as re import signal import sys import tempfile @@ -51,18 +51,14 @@ from blib2to3.pgen2 import driver, token from blib2to3.pgen2.grammar import Grammar from blib2to3.pgen2.parse import ParseError -from _version import get_versions - -v = get_versions() -__version__ = v.get("closest-tag", v["version"]) -__git_version__ = v.get("full-revisionid") +from _version import version as __version__ DEFAULT_LINE_LENGTH = 88 DEFAULT_EXCLUDES = ( r"/(\.eggs|\.git|\.hg|\.mypy_cache|\.nox|\.tox|\.venv|_build|buck-out|build|dist)/" ) DEFAULT_INCLUDES = r"\.pyi?$" -CACHE_DIR = Path(user_cache_dir("black", version=__git_version__)) +CACHE_DIR = Path(user_cache_dir("black", version=__version__)) # types @@ -1296,7 +1292,7 @@ class Line: return True return False - def contains_inner_type_comments(self) -> bool: + def contains_uncollapsable_type_comments(self) -> bool: ignored_ids = set() try: last_leaf = self.leaves[-1] @@ -1313,13 +1309,54 @@ class Line: except IndexError: return False + # A type comment is uncollapsable if it is attached to a leaf + # that isn't at the end of the line (since that could cause it + # to get associated to a different argument) or if there are + # comments before it (since that could cause it to get hidden + # behind a comment. + comment_seen = False for leaf_id, comments in self.comments.items(): - if leaf_id in ignored_ids: - continue - for comment in comments: if is_type_comment(comment): - return True + if leaf_id not in ignored_ids or comment_seen: + return True + + comment_seen = True + + return False + + def contains_unsplittable_type_ignore(self) -> bool: + if not self.leaves: + return False + + # If a 'type: ignore' is attached to the end of a line, we + # can't split the line, because we can't know which of the + # subexpressions the ignore was meant to apply to. + # + # We only want this to apply to actual physical lines from the + # original source, though: we don't want the presence of a + # 'type: ignore' at the end of a multiline expression to + # justify pushing it all onto one line. Thus we + # (unfortunately) need to check the actual source lines and + # only report an unsplittable 'type: ignore' if this line was + # one line in the original code. + + # Like in the type comment check above, we need to skip a black added + # trailing comma or invisible paren, since it will be the original leaf + # before it that has the original line number. + last_idx = -1 + last_leaf = self.leaves[-1] + if len(self.leaves) > 2 and ( + last_leaf.type == token.COMMA + or (last_leaf.type == token.RPAR and not last_leaf.value) + ): + last_idx = -2 + + if self.leaves[0].lineno == self.leaves[last_idx].lineno: + for node in self.leaves[last_idx:]: + for comment in self.comments.get(id(node), []): + if is_type_comment(comment, " ignore"): + return True return False @@ -2328,9 +2365,12 @@ def split_line( line_str = str(line).strip("\n") if ( - not line.contains_inner_type_comments() + not line.contains_uncollapsable_type_comments() and not line.should_explode - and is_line_short_enough(line, line_length=line_length, line_str=line_str) + and ( + is_line_short_enough(line, line_length=line_length, line_str=line_str) + or line.contains_unsplittable_type_ignore() + ) ): yield line return @@ -2703,12 +2743,14 @@ def is_import(leaf: Leaf) -> bool: ) -def is_type_comment(leaf: Leaf) -> bool: +def is_type_comment(leaf: Leaf, suffix: str = "") -> 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 t in {token.COMMENT, t == STANDALONE_COMMENT} and v.startswith("# type:") + return t in {token.COMMENT, t == STANDALONE_COMMENT} and v.startswith( + "# type:" + suffix + ) def normalize_prefix(leaf: Leaf, *, inside_brackets: bool) -> None: @@ -3768,7 +3810,8 @@ def re_compile_maybe_verbose(regex: str) -> Pattern[str]: """ if "\n" in regex: regex = "(?x)" + regex - return re.compile(regex) + compiled: Pattern[str] = re.compile(regex) + return compiled def enumerate_reversed(sequence: Sequence[T]) -> Iterator[Tuple[Index, T]]: