diff --git a/CHANGES.md b/CHANGES.md index 68a2fe35205..ddeb351b3cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,8 @@ - Fix crash when `# fmt: off` is used before a closing parenthesis or bracket. (#4363) +- Fix `# fmt: skip` issues of not formating other line when that line is connected to + fmt: skip line (#4380) ### Preview style diff --git a/docs/contributing/release_process.md b/docs/contributing/release_process.md index c66ffae8ace..2c904fb95c4 100644 --- a/docs/contributing/release_process.md +++ b/docs/contributing/release_process.md @@ -29,8 +29,8 @@ frequently than monthly nets rapidly diminishing returns. **You must have `write` permissions for the _Black_ repository to cut a release.** The 10,000 foot view of the release process is that you prepare a release PR and then -publish a [GitHub Release]. This triggers [release automation](#release-workflows) that -builds all release artifacts and publishes them to the various platforms we publish to. +publish a [GitHub Release]. This triggers [release automation](#release-workflows) that builds +all release artifacts and publishes them to the various platforms we publish to. We now have a `scripts/release.py` script to help with cutting the release PRs. @@ -96,9 +96,8 @@ In the end, use your best judgement and ask other maintainers for their thoughts ## Release workflows -All of _Black_'s release automation uses [GitHub Actions]. All workflows are therefore -configured using YAML files in the `.github/workflows` directory of the _Black_ -repository. +All of _Black_'s release automation uses [GitHub Actions]. All workflows are therefore configured +using YAML files in the `.github/workflows` directory of the _Black_ repository. They are triggered by the publication of a [GitHub Release]. diff --git a/docs/usage_and_configuration/black_docker_image.md b/docs/usage_and_configuration/black_docker_image.md index c97c25af328..72969b7b68a 100644 --- a/docs/usage_and_configuration/black_docker_image.md +++ b/docs/usage_and_configuration/black_docker_image.md @@ -8,16 +8,16 @@ _Black_ images with the following tags are available: - release numbers, e.g. `21.5b2`, `21.6b0`, `21.7b0` etc.\ ℹ Recommended for users who want to use a particular version of _Black_. - `latest_release` - tag created when a new version of _Black_ is released.\ - ℹ Recommended for users who want to use released versions of _Black_. It maps to [the latest release](https://github.com/psf/black/releases/latest) - of _Black_. + ℹ Recommended for users who want to use released versions of _Black_. It maps to + [the latest release](https://github.com/psf/black/releases/latest) of _Black_. - `latest_prerelease` - tag created when a new alpha (prerelease) version of _Black_ is released.\ - ℹ Recommended for users who want to preview or test alpha versions of _Black_. Note that - the most recent release may be newer than any prerelease, because no prereleases are created - before most releases. + ℹ Recommended for users who want to preview or test alpha versions of _Black_. Note + that the most recent release may be newer than any prerelease, because no prereleases + are created before most releases. - `latest` - tag used for the newest image of _Black_.\ - ℹ Recommended for users who always want to use the latest version of _Black_, even before - it is released. + ℹ Recommended for users who always want to use the latest version of _Black_, even + before it is released. There is one more tag used for _Black_ Docker images - `latest_non_release`. It is created for all unreleased diff --git a/src/black/comments.py b/src/black/comments.py index a835f58a900..2fa4ae5daf3 100644 --- a/src/black/comments.py +++ b/src/black/comments.py @@ -12,7 +12,6 @@ first_leaf_of, make_simple_prefix, preceding_leaf, - syms, ) from blib2to3.pgen2 import token from blib2to3.pytree import Leaf, Node @@ -233,7 +232,7 @@ def convert_one_fmt_off_pair( fmt_off_prefix = fmt_off_prefix.split("\n")[-1] standalone_comment_prefix += fmt_off_prefix hidden_value = comment.value + "\n" + hidden_value - if is_fmt_skip: + if is_fmt_skip and comment.value not in hidden_value: hidden_value += ( comment.leading_whitespace if Preview.no_normalize_fmt_skip_whitespace in mode @@ -315,42 +314,62 @@ def _generate_ignored_nodes_from_fmt_skip( leaf: Leaf, comment: ProtoComment ) -> Iterator[LN]: """Generate all leaves that should be ignored by the `# fmt: skip` from `leaf`.""" + prefix = leaf.prefix + leaf.prefix = "" prev_sibling = leaf.prev_sibling - parent = leaf.parent + # This is when the next thing after the "fmt: skip" comment is not a newline. + # Means it is inside of an node or previous_sibling is a node + if leaf.value != "\n" or prev_sibling is None: + prev_sibling = preceding_leaf(leaf) # Need to properly format the leaf prefix to compare it to comment.value, # which is also formatted - comments = list_comments(leaf.prefix, is_endmarker=False) + comments = list_comments(prefix, is_endmarker=False) if not comments or comment.value != comments[0].value: return - if prev_sibling is not None: - leaf.prefix = "" + + if prev_sibling: + comment_line_no = prev_sibling.get_lineno() siblings = [prev_sibling] - while "\n" not in prev_sibling.prefix and prev_sibling.prev_sibling is not None: + while prev_sibling is not None and "\n" not in prev_sibling.prefix: + previous_sibling = preceding_leaf(prev_sibling) prev_sibling = prev_sibling.prev_sibling - siblings.insert(0, prev_sibling) - yield from siblings - elif ( - parent is not None and parent.type == syms.suite and leaf.type == token.NEWLINE - ): - # The `# fmt: skip` is on the colon line of the if/while/def/class/... - # statements. The ignored nodes should be previous siblings of the - # parent suite node. - leaf.prefix = "" - ignored_nodes: List[LN] = [] - parent_sibling = parent.prev_sibling - while parent_sibling is not None and parent_sibling.type != syms.suite: - ignored_nodes.insert(0, parent_sibling) - parent_sibling = parent_sibling.prev_sibling - # Special case for `async_stmt` where the ASYNC token is on the - # grandparent node. - grandparent = parent.parent - if ( - grandparent is not None - and grandparent.prev_sibling is not None - and grandparent.prev_sibling.type == token.ASYNC - ): - ignored_nodes.insert(0, grandparent.prev_sibling) - yield from iter(ignored_nodes) + # prev_sibling can be non if the there is it is new line + # or preivous sibling is a node + if ( + prev_sibling is None + and previous_sibling is not None + and previous_sibling.get_lineno() == comment_line_no + ): + parent_sibling = siblings[-1] + siblings = [] + # insert parents Node if it on same line of comment + while ( + parent_sibling.get_lineno() == comment_line_no + and parent_sibling.type != 256 + ): + parents_prev_siblings = preceding_leaf(parent_sibling) + siblings = [parent_sibling] + if parent_sibling.parent is None: + break + leaf.prefix = prefix + parent_sibling = parent_sibling.parent + + if previous_sibling and previous_sibling.type == token.INDENT: + break + # if previous_sibling is on same line + # and its parents are't then insert previous_sibling from here + if ( + parents_prev_siblings == previous_sibling + and previous_sibling.get_lineno() == comment_line_no + ): + prev_sibling = previous_sibling + siblings.insert(0, prev_sibling) + + elif prev_sibling and prev_sibling.get_lineno() == comment_line_no: + siblings.insert(0, prev_sibling) + else: + break + yield from iter(siblings) def is_fmt_on(container: LN) -> bool: diff --git a/tests/data/cases/single_line_format_skip_with_multiple_comments.py b/tests/data/cases/single_line_format_skip_with_multiple_comments.py index 7212740fc42..793a68b067d 100644 --- a/tests/data/cases/single_line_format_skip_with_multiple_comments.py +++ b/tests/data/cases/single_line_format_skip_with_multiple_comments.py @@ -11,7 +11,7 @@ foo = 123 # fmt: skip # noqa: E501 # pylint bar = ( - 123 , + 123, ( 1 + 5 ) # pylint # fmt:skip ) baz = "a" + "b" # pylint; fmt: skip; noqa: E501