From 42b7ec8106ed191fd4201f565f1fb73962e743cc Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 01:25:57 +0530 Subject: [PATCH 1/7] prevent wrapping of multiline fstrings in parens --- src/black/linegen.py | 12 ++++-------- src/black/nodes.py | 19 ++++++++++++++++++- tests/data/cases/pep_701.py | 6 ++++++ 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/black/linegen.py b/src/black/linegen.py index 4b29a049dba..0cb4a96f598 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -37,12 +37,14 @@ WHITESPACE, Visitor, ensure_visible, + fstring_to_string, get_annotation_type, is_arith_like, is_async_stmt_or_funcdef, is_atom_with_invisible_parens, is_docstring, is_empty_tuple, + is_fstring, is_lpar_token, is_multiline_string, is_name_token, @@ -504,7 +506,7 @@ def visit_NUMBER(self, leaf: Leaf) -> Iterator[Line]: def visit_fstring(self, node: Node) -> Iterator[Line]: # currently we don't want to format and split f-strings at all. - string_leaf = _fstring_to_string(node) + string_leaf = fstring_to_string(node) node.replace(string_leaf) yield from self.visit_STRING(string_leaf) @@ -574,12 +576,6 @@ def __post_init__(self) -> None: self.visit_guard = partial(v, keywords=Ø, parens={"if"}) -def _fstring_to_string(node: Node) -> Leaf: - """Converts an fstring node back to a string node.""" - string_without_prefix = str(node)[len(node.prefix) :] - return Leaf(token.STRING, string_without_prefix, prefix=node.prefix) - - def _hugging_power_ops_line_to_string( line: Line, features: Collection[Feature], @@ -1421,7 +1417,7 @@ def normalize_invisible_parens( # noqa: C901 # of case will be not parsed as a Python keyword. break - elif not (isinstance(child, Leaf) and is_multiline_string(child)): + elif not is_multiline_string(child): wrap_in_parentheses(node, child, visible=False) comma_check = child.type == token.COMMA diff --git a/src/black/nodes.py b/src/black/nodes.py index f75e0848663..2109ef34580 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -762,8 +762,25 @@ def is_vararg(leaf: Leaf, within: Set[NodeType]) -> bool: return p.type in within -def is_multiline_string(leaf: Leaf) -> bool: +def is_fstring(node: Node) -> bool: + """Return True if the node is an f-string""" + return node.type == syms.fstring + + + +def fstring_to_string(node: Node) -> Leaf: + """Converts an fstring node back to a string node.""" + string_without_prefix = str(node)[len(node.prefix) :] + return Leaf(token.STRING, string_without_prefix, prefix=node.prefix) + + +def is_multiline_string(node: LN) -> bool: """Return True if `leaf` is a multiline string that actually spans many lines.""" + if is_fstring(node): + leaf = fstring_to_string(node) + else: + leaf = node + return has_triple_quotes(leaf.value) and "\n" in leaf.value diff --git a/tests/data/cases/pep_701.py b/tests/data/cases/pep_701.py index c5bc48e95f2..e0a0df862b6 100644 --- a/tests/data/cases/pep_701.py +++ b/tests/data/cases/pep_701.py @@ -110,6 +110,9 @@ {1}_cte AS ()'''} """ +value: str = f'''foo +''' + # output x = f"foo" @@ -222,3 +225,6 @@ WITH {f''' {1}_cte AS ()'''} """ + +value: str = f"""foo +""" \ No newline at end of file From fcf3656e68a3a0aa090111256636419a22e58087 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 01:27:03 +0530 Subject: [PATCH 2/7] newline --- tests/data/cases/pep_701.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/cases/pep_701.py b/tests/data/cases/pep_701.py index e0a0df862b6..f2bf015302d 100644 --- a/tests/data/cases/pep_701.py +++ b/tests/data/cases/pep_701.py @@ -227,4 +227,4 @@ """ value: str = f"""foo -""" \ No newline at end of file +""" From b0c6f87bbcd8b4dbd0ebe536aef8a7692fae9b73 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 01:28:24 +0530 Subject: [PATCH 3/7] fix failing tests --- src/black/nodes.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/black/nodes.py b/src/black/nodes.py index 2109ef34580..b5d3636847f 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -778,8 +778,10 @@ def is_multiline_string(node: LN) -> bool: """Return True if `leaf` is a multiline string that actually spans many lines.""" if is_fstring(node): leaf = fstring_to_string(node) - else: + elif isinstance(node, Leaf): leaf = node + else: + return False return has_triple_quotes(leaf.value) and "\n" in leaf.value From 895766ff8c00e2f1bdf858e86a8062787b2bb584 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 01:31:23 +0530 Subject: [PATCH 4/7] fix mypy --- src/black/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/black/nodes.py b/src/black/nodes.py index b5d3636847f..bf3ae777cfe 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -776,7 +776,7 @@ def fstring_to_string(node: Node) -> Leaf: def is_multiline_string(node: LN) -> bool: """Return True if `leaf` is a multiline string that actually spans many lines.""" - if is_fstring(node): + if isinstance(node, Node) and is_fstring(node): leaf = fstring_to_string(node) elif isinstance(node, Leaf): leaf = node From 0ec8c01a343d2d523924c4c015248e7e3c49c9a2 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 01:33:29 +0530 Subject: [PATCH 5/7] lints --- src/black/linegen.py | 1 - src/black/nodes.py | 1 - 2 files changed, 2 deletions(-) diff --git a/src/black/linegen.py b/src/black/linegen.py index 0cb4a96f598..980785e94fa 100644 --- a/src/black/linegen.py +++ b/src/black/linegen.py @@ -44,7 +44,6 @@ is_atom_with_invisible_parens, is_docstring, is_empty_tuple, - is_fstring, is_lpar_token, is_multiline_string, is_name_token, diff --git a/src/black/nodes.py b/src/black/nodes.py index bf3ae777cfe..85aeca2caf8 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -767,7 +767,6 @@ def is_fstring(node: Node) -> bool: return node.type == syms.fstring - def fstring_to_string(node: Node) -> Leaf: """Converts an fstring node back to a string node.""" string_without_prefix = str(node)[len(node.prefix) :] From 44b7692ef7a3161c39e2154c2f59d4c0bdd6b2cc Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 02:27:37 +0530 Subject: [PATCH 6/7] fix lineno not present in string leaves --- src/black/nodes.py | 4 +++- tests/data/cases/pep_701.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/black/nodes.py b/src/black/nodes.py index 85aeca2caf8..283eba7b01d 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -770,7 +770,9 @@ def is_fstring(node: Node) -> bool: def fstring_to_string(node: Node) -> Leaf: """Converts an fstring node back to a string node.""" string_without_prefix = str(node)[len(node.prefix) :] - return Leaf(token.STRING, string_without_prefix, prefix=node.prefix) + string_leaf = Leaf(token.STRING, string_without_prefix, prefix=node.prefix) + string_leaf.lineno = node.get_lineno() + return string_leaf def is_multiline_string(node: LN) -> bool: diff --git a/tests/data/cases/pep_701.py b/tests/data/cases/pep_701.py index f2bf015302d..f4a69e47413 100644 --- a/tests/data/cases/pep_701.py +++ b/tests/data/cases/pep_701.py @@ -113,6 +113,12 @@ value: str = f'''foo ''' +log( + f"Received operation {server_operation.name} from " + f"{self.writer._transport.get_extra_info('peername')}", # type: ignore[attr-defined] + level=0, +) + # output x = f"foo" @@ -228,3 +234,9 @@ value: str = f"""foo """ + +log( + f"Received operation {server_operation.name} from " + f"{self.writer._transport.get_extra_info('peername')}", # type: ignore[attr-defined] + level=0, +) From b5df1ae76cccea6b0d0f1ea342b335494ecba188 Mon Sep 17 00:00:00 2001 From: Tushar Sadhwani Date: Wed, 24 Apr 2024 02:29:39 +0530 Subject: [PATCH 7/7] fix mypy --- src/black/nodes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/black/nodes.py b/src/black/nodes.py index 283eba7b01d..9579b715ad2 100644 --- a/src/black/nodes.py +++ b/src/black/nodes.py @@ -771,7 +771,7 @@ def fstring_to_string(node: Node) -> Leaf: """Converts an fstring node back to a string node.""" string_without_prefix = str(node)[len(node.prefix) :] string_leaf = Leaf(token.STRING, string_without_prefix, prefix=node.prefix) - string_leaf.lineno = node.get_lineno() + string_leaf.lineno = node.get_lineno() or 0 return string_leaf