Skip to content

Commit

Permalink
Merge branch 'main' into cm
Browse files Browse the repository at this point in the history
  • Loading branch information
yilei committed Jan 19, 2023
2 parents a81d7b4 + 18fb884 commit 95bca0f
Show file tree
Hide file tree
Showing 14 changed files with 253 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .flake8
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[flake8]
# B905 should be enabled when we drop support for 3.9
ignore = E203, E266, E501, W503, B905
ignore = E203, E266, E501, W503, B905, B907
# line length is intentionally set to 80 here because black uses Bugbear
# See https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#line-length for more details
max-line-length = 80
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,12 @@
- Long values in dict literals are now wrapped in parentheses; correspondingly
unnecessary parentheses around short values in dict literals are now removed; long
string lambda values are now wrapped in parentheses (#3440)
- Fix two crashes in preview style involving edge cases with docstrings (#3451)
- Exclude string type annotations from improved string processing; fix crash when the
return type annotation is stringified and spans across multiple lines (#3462)
- Wrap multiple context managers in parentheses when targeting Python 3.9+ (#3489)
- Fix several crashes in preview style with walrus operators used in `with` statements
or tuples (#3473)

### Configuration

Expand Down Expand Up @@ -64,6 +67,8 @@

- Verbose logging now shows the values of `pyproject.toml` configuration variables
(#3392)
- Fix false symlink detection messages in verbose output due to using an incorrect
relative path to the project root (#3385)

### _Blackd_

Expand Down
106 changes: 106 additions & 0 deletions docs/integrations/editors.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ Options include the following:

## PyCharm/IntelliJ IDEA

There are three different ways you can use _Black_ from PyCharm:

1. As local server using the BlackConnect plugin
1. As external tool
1. As file watcher

The first option is the simplest to set up and formats the fastest (by spinning up
{doc}`Black's HTTP server </usage_and_configuration/black_as_a_server>`, avoiding the
startup cost on subsequent formats), but if you would prefer to not install a
third-party plugin or blackd's extra dependencies, the other two are also great options.

### As local server

1. Install _Black_ with the `d` extra.

```console
Expand Down Expand Up @@ -46,6 +59,99 @@ Options include the following:
- In `Trigger Settings` section of plugin configuration check
`Trigger when saving changed files`.

### As external tool

1. Install `black`.

```console
$ pip install black
```

1. Locate your `black` installation folder.

On macOS / Linux / BSD:

```console
$ which black
/usr/local/bin/black # possible location
```

On Windows:

```console
$ where black
%LocalAppData%\Programs\Python\Python36-32\Scripts\black.exe # possible location
```

Note that if you are using a virtual environment detected by PyCharm, this is an
unneeded step. In this case the path to `black` is `$PyInterpreterDirectory$/black`.

1. Open External tools in PyCharm/IntelliJ IDEA

On macOS:

`PyCharm -> Preferences -> Tools -> External Tools`

On Windows / Linux / BSD:

`File -> Settings -> Tools -> External Tools`

1. Click the + icon to add a new external tool with the following values:

- Name: Black
- Description: Black is the uncompromising Python code formatter.
- Program: \<install_location_from_step_2>
- Arguments: `"$FilePath$"`

1. Format the currently opened file by selecting `Tools -> External Tools -> black`.

- Alternatively, you can set a keyboard shortcut by navigating to
`Preferences or Settings -> Keymap -> External Tools -> External Tools - Black`.

### As file watcher

1. Install `black`.

```console
$ pip install black
```

1. Locate your `black` installation folder.

On macOS / Linux / BSD:

```console
$ which black
/usr/local/bin/black # possible location
```

On Windows:

```console
$ where black
%LocalAppData%\Programs\Python\Python36-32\Scripts\black.exe # possible location
```

Note that if you are using a virtual environment detected by PyCharm, this is an
unneeded step. In this case the path to `black` is `$PyInterpreterDirectory$/black`.

1. Make sure you have the
[File Watchers](https://plugins.jetbrains.com/plugin/7177-file-watchers) plugin
installed.
1. Go to `Preferences or Settings -> Tools -> File Watchers` and click `+` to add a new
watcher:
- Name: Black
- File type: Python
- Scope: Project Files
- Program: \<install_location_from_step_2>
- Arguments: `$FilePath$`
- Output paths to refresh: `$FilePath$`
- Working directory: `$ProjectFileDir$`

- In Advanced Options
- Uncheck "Auto-save edited files to trigger the watcher"
- Uncheck "Trigger the watcher on external changes"

## Wing IDE

Wing IDE supports `black` via **Preference Settings** for system wide settings and
Expand Down
6 changes: 3 additions & 3 deletions docs/the_black_code_style/future_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ with make_context_manager1() as cm1, make_context_manager2() as cm2, make_contex
... # nothing to split on - line too long
```

So _Black_ will eventually format it like this:
So _Black_ will, when we implement this, format it like this:

```py3
with \
Expand All @@ -31,8 +31,8 @@ with \
... # backslashes and an ugly stranded colon
```

Although when the target version is Python 3.9 or higher, _Black_ will use parentheses
instead since they're allowed in Python 3.9 and higher.
Although when the target version is Python 3.9 or higher, _Black_ will, when we
implement this, use parentheses instead since they're allowed in Python 3.9 and higher.

An alternative to consider if the backslashes in the above formatting are undesirable is
to use {external:py:obj}`contextlib.ExitStack` to combine context managers in the
Expand Down
6 changes: 3 additions & 3 deletions docs/usage_and_configuration/the_basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ so style options are deliberately limited and rarely added.

</details>

Note that all command-line options listed above can also be configured using a
`pyproject.toml` file (more on that below).

### Code input alternatives

#### Standard Input
Expand Down Expand Up @@ -287,9 +290,6 @@ file hierarchy.

## Next steps

You've probably noted that not all of the options you can pass to _Black_ have been
covered. Don't worry, the rest will be covered in a later section.

A good next step would be configuring auto-discovery so `black .` is all you need
instead of laborously listing every file or directory. You can get started by heading
over to [File collection and discovery](./file_collection_and_discovery.md).
Expand Down
3 changes: 2 additions & 1 deletion src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,10 +673,11 @@ def get_sources(

sources.add(p)
elif p.is_dir():
p = root / normalize_path_maybe_ignore(p, ctx.obj["root"], report)
if using_default_exclude:
gitignore = {
root: root_gitignore,
root / p: get_gitignore(p),
p: get_gitignore(p),
}
sources.update(
gen_python_files(
Expand Down
8 changes: 8 additions & 0 deletions src/black/linegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
is_rpar_token,
is_stub_body,
is_stub_suite,
is_tuple_containing_walrus,
is_vararg,
is_walrus_assignment,
is_yield,
Expand Down Expand Up @@ -406,6 +407,7 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]:
else:
docstring = docstring.strip()

has_trailing_backslash = False
if docstring:
# Add some padding if the docstring starts / ends with a quote mark.
if docstring[0] == quote_char:
Expand All @@ -418,6 +420,7 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]:
# Odd number of tailing backslashes, add some padding to
# avoid escaping the closing string quote.
docstring += " "
has_trailing_backslash = True
elif not docstring_started_empty:
docstring = " "

Expand All @@ -440,6 +443,8 @@ def visit_STRING(self, leaf: Leaf) -> Iterator[Line]:
if (
len(lines) > 1
and last_line_length + quote_len > self.mode.line_length
and len(indent) + quote_len <= self.mode.line_length
and not has_trailing_backslash
):
leaf.value = prefix + quote + docstring + "\n" + indent + quote
else:
Expand Down Expand Up @@ -1336,6 +1341,7 @@ def maybe_make_parens_invisible_in_atom(
not remove_brackets_around_comma
and max_delimiter_priority_in_atom(node) >= COMMA_PRIORITY
)
or is_tuple_containing_walrus(node)
):
return False

Expand All @@ -1347,9 +1353,11 @@ def maybe_make_parens_invisible_in_atom(
syms.return_stmt,
syms.except_clause,
syms.funcdef,
syms.with_stmt,
# these ones aren't useful to end users, but they do please fuzzers
syms.for_stmt,
syms.del_stmt,
syms.for_stmt,
]:
return False

Expand Down
11 changes: 11 additions & 0 deletions src/black/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,17 @@ def is_one_tuple(node: LN) -> bool:
)


def is_tuple_containing_walrus(node: LN) -> bool:
"""Return True if `node` holds a tuple that contains a walrus operator."""
if node.type != syms.atom:
return False
gexp = unwrap_singleton_parenthesis(node)
if gexp is None or gexp.type != syms.testlist_gexp:
return False

return any(child.type == syms.namedexpr_test for child in gexp.children)


def is_one_sequence_between(
opening: Leaf,
closing: Leaf,
Expand Down
4 changes: 4 additions & 0 deletions tests/data/fast/pep_572_do_not_remove_parens.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@
@(please := stop)
def sigh():
pass


for (x := 3, y := 4) in y:
pass
5 changes: 5 additions & 0 deletions tests/data/miscellaneous/linelength6.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Regression test for #3427, which reproes only with line length <= 6
def f():
"""
x
"""
40 changes: 40 additions & 0 deletions tests/data/py_38/pep_572_remove_parens.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@ def a():
def this_is_so_dumb() -> (please := no):
pass

async def await_the_walrus():
with (x := y):
pass

with (x := y) as z, (a := b) as c:
pass

with (x := await y):
pass

with (x := await a, y := await b):
pass

# Ideally we should remove one set of parentheses
with ((x := await a, y := await b)):
pass

with (x := await a), (y := await b):
pass


# output
if foo := 0:
Expand Down Expand Up @@ -103,3 +123,23 @@ def a():
def this_is_so_dumb() -> (please := no):
pass


async def await_the_walrus():
with (x := y):
pass

with (x := y) as z, (a := b) as c:
pass

with (x := await y):
pass

with (x := await a, y := await b):
pass

# Ideally we should remove one set of parentheses
with ((x := await a, y := await b)):
pass

with (x := await a), (y := await b):
pass
11 changes: 11 additions & 0 deletions tests/data/simple_cases/docstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ def multiline_backslash_2():
'''
hey there \ '''

# Regression test for #3425
def multiline_backslash_really_long_dont_crash():
"""
hey there hello guten tag hi hoow are you ola zdravstvuyte ciao como estas ca va \ """


def multiline_backslash_3():
'''
Expand Down Expand Up @@ -391,6 +396,12 @@ def multiline_backslash_2():
hey there \ """


# Regression test for #3425
def multiline_backslash_really_long_dont_crash():
"""
hey there hello guten tag hi hoow are you ola zdravstvuyte ciao como estas ca va \ """


def multiline_backslash_3():
"""
already escaped \\"""
Expand Down
Loading

0 comments on commit 95bca0f

Please sign in to comment.