Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use parentheses with equality check in walrus/assignment statements #2770

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

<!-- Changes that affect Black's preview style -->

- Use parentheses with equality check in walrus/assigment statements (#2770)

### _Blackd_

<!-- Changes to blackd -->
Expand Down
2 changes: 1 addition & 1 deletion src/black/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1095,7 +1095,7 @@ def format_ipynb_string(src_contents: str, *, fast: bool, mode: Mode) -> FileCon
Operate cell-by-cell, only on code cells, only for Python notebooks.
If the ``.ipynb`` originally had a trailing newline, it'll be preserved.
"""
trailing_newline = src_contents[-1] == "\n"
trailing_newline = (src_contents[-1] == "\n")
modified = False
nb = json.loads(src_contents)
validate_metadata(nb)
Expand Down
23 changes: 23 additions & 0 deletions src/black/linegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,29 @@ def visit_default(self, node: LN) -> Iterator[Line]:
self.current_line.append(node)
yield from super().visit_default(node)

def visit_comparison(self, node: Node) -> Iterator[Line]:
parent: Optional[Node] = node.parent
grandparent: Optional[Node] = parent.parent if parent else None
if (
# It is a preview style feature only
Preview.parentheses_in_equality_check_assignments in self.mode
and parent is not None
and Leaf(token.EQEQUAL, "==") in node.children
and (
parent.type == syms.namedexpr_test
or (
grandparent is not None
and grandparent.type in (syms.expr_stmt, syms.annassign)
)
)
):
lpar = Leaf(token.LPAR, "(")
rpar = Leaf(token.RPAR, ")")
node.insert_child(0, lpar)
node.insert_child(len(node.children), rpar)

yield from self.visit_default(node)

def visit_INDENT(self, node: Leaf) -> Iterator[Line]:
"""Increase indentation level, maybe yield a line."""
# In blib2to3 INDENT never holds comments.
Expand Down
1 change: 1 addition & 0 deletions src/black/mode.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ class Preview(Enum):

string_processing = auto()
hug_simple_powers = auto()
parentheses_in_equality_check_assignments = auto()


class Deprecated(UserWarning):
Expand Down
2 changes: 1 addition & 1 deletion src/black/parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@

ast3: Any

_IS_PYPY = platform.python_implementation() == "PyPy"
_IS_PYPY = (platform.python_implementation() == "PyPy")

try:
from typed_ast import ast3
Expand Down
2 changes: 1 addition & 1 deletion src/black/trans.py
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ def passes_all_checks(i: Index) -> bool:
True iff ALL of the conditions listed in the 'Transformations'
section of this classes' docstring would be be met by returning @i.
"""
is_space = string[i] == " "
is_space = (string[i] == " ")

is_not_escaped = True
j = i - 1
Expand Down
6 changes: 3 additions & 3 deletions src/black_primer/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@


TEN_MINUTES_SECONDS = 600
WINDOWS = system() == "Windows"
WINDOWS = (system() == "Windows")
BLACK_BINARY = "black.exe" if WINDOWS else "black"
GIT_BINARY = "git.exe" if WINDOWS else "git"
LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -158,7 +158,7 @@ async def black_run(
)
return

stdin_test = project_name.upper() == "STDIN"
stdin_test = (project_name.upper() == "STDIN")
cmd = [str(which(BLACK_BINARY))]
if "cli_arguments" in project_config and project_config["cli_arguments"]:
cmd.extend(_flatten_cli_args(project_config["cli_arguments"]))
Expand Down Expand Up @@ -348,7 +348,7 @@ async def project_runner(
continue

repo_path: Optional[Path] = Path(__file__)
stdin_project = project_name.upper() == "STDIN"
stdin_project = (project_name.upper() == "STDIN")
if not stdin_project:
repo_path = await git_checkout_or_rebase(work_path, project_config, rebase)
if not repo_path:
Expand Down
2 changes: 1 addition & 1 deletion src/blackd/middlewares.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
def cors(allow_headers: Iterable[str]) -> Middleware:
@middleware
async def impl(request: Request, handler: Handler) -> StreamResponse:
is_options = request.method == "OPTIONS"
is_options = (request.method == "OPTIONS")
is_preflight = is_options and "Access-Control-Request-Method" in request.headers
if is_preflight:
resp = StreamResponse()
Expand Down
63 changes: 63 additions & 0 deletions tests/data/paren_eq_check_in_assigments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
match_count += new_value == old_value

on_windows: bool = (os.name == "nt")

implementation_version = (
platform.python_version() if platform.python_implementation() == "CPython" else "Unknown"
)

is_mac = platform.system() == 'Darwin'

s = y == 2 + y == 4

name1 = name2 = name3

name1 == name2 == name3

check_sockets(on_windows=os.name == "nt")

a = b in c and b == d

a = b == c == d

a = b == c in d

a = b >= c == True

a = b in c

a = b > c

# output

match_count += (new_value == old_value)

on_windows: bool = (os.name == "nt")

implementation_version = (
platform.python_version()
if platform.python_implementation() == "CPython"
else "Unknown"
)

is_mac = (platform.system() == "Darwin")

s = (y == 2 + y == 4)

name1 = name2 = name3

name1 == name2 == name3

check_sockets(on_windows=os.name == "nt")

a = b in c and b == d

a = (b == c == d)

a = (b == c in d)

a = (b >= c == True)

a = b in c

a = b > c
1 change: 1 addition & 0 deletions tests/test_black.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ def test_piping(self) -> None:
black.main,
[
"-",
"--preview",
"--fast",
f"--line-length={black.DEFAULT_LINE_LENGTH}",
f"--config={EMPTY_CONFIG}",
Expand Down
6 changes: 4 additions & 2 deletions tests/test_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import black
from tests.util import (
DEFAULT_MODE,
PREVIEW_MODE,
PY36_VERSIONS,
THIS_DIR,
assert_format,
Expand Down Expand Up @@ -79,6 +80,7 @@
"long_strings__edge_case",
"long_strings__regression",
"percent_precedence",
"paren_eq_check_in_assigments",
]

SOURCES: List[str] = [
Expand Down Expand Up @@ -144,13 +146,13 @@ def test_simple_format(filename: str) -> None:

@pytest.mark.parametrize("filename", PREVIEW_CASES)
def test_preview_format(filename: str) -> None:
check_file(filename, black.Mode(preview=True))
check_file(filename, PREVIEW_MODE)


@pytest.mark.parametrize("filename", SOURCES)
def test_source_is_formatted(filename: str) -> None:
path = THIS_DIR.parent / filename
check_file(str(path), DEFAULT_MODE, data=False)
check_file(str(path), PREVIEW_MODE, data=False)


# =============== #
Expand Down
1 change: 1 addition & 0 deletions tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
}

DEFAULT_MODE = black.Mode()
PREVIEW_MODE = black.Mode(preview=True)
ff = partial(black.format_file_in_place, mode=DEFAULT_MODE, fast=True)
fs = partial(black.format_str, mode=DEFAULT_MODE)

Expand Down