gh-108469: Update ast.unparse for unescaped quote support from PEP701 [3.12] (#108553)

Co-authored-by: sunmy2019 <59365878+sunmy2019@users.noreply.github.com>
This commit is contained in:
Anthony Shaw
2023-09-06 06:01:23 +10:00
committed by GitHub
parent 9bf350b066
commit 2c4c26c4ce
4 changed files with 30 additions and 27 deletions

View File

@@ -1225,17 +1225,7 @@ class _Unparser(NodeVisitor):
def visit_JoinedStr(self, node):
self.write("f")
if self._avoid_backslashes:
with self.buffered() as buffer:
self._write_fstring_inner(node)
return self._write_str_avoiding_backslashes("".join(buffer))
# If we don't need to avoid backslashes globally (i.e., we only need
# to avoid them inside FormattedValues), it's cosmetically preferred
# to use escaped whitespace. That is, it's preferred to use backslashes
# for cases like: f"{x}\n". To accomplish this, we keep track of what
# in our buffer corresponds to FormattedValues and what corresponds to
# Constant parts of the f-string, and allow escapes accordingly.
fstring_parts = []
for value in node.values:
with self.buffered() as buffer:
@@ -1247,11 +1237,14 @@ class _Unparser(NodeVisitor):
new_fstring_parts = []
quote_types = list(_ALL_QUOTES)
for value, is_constant in fstring_parts:
value, quote_types = self._str_literal_helper(
value,
quote_types=quote_types,
escape_special_whitespace=is_constant,
)
if is_constant:
value, quote_types = self._str_literal_helper(
value,
quote_types=quote_types,
escape_special_whitespace=True,
)
elif "\n" in value:
quote_types = [q for q in quote_types if q in _MULTI_QUOTES]
new_fstring_parts.append(value)
value = "".join(new_fstring_parts)
@@ -1273,16 +1266,12 @@ class _Unparser(NodeVisitor):
def visit_FormattedValue(self, node):
def unparse_inner(inner):
unparser = type(self)(_avoid_backslashes=True)
unparser = type(self)()
unparser.set_precedence(_Precedence.TEST.next(), inner)
return unparser.visit(inner)
with self.delimit("{", "}"):
expr = unparse_inner(node.value)
if "\\" in expr:
raise ValueError(
"Unable to avoid backslash in f-string expression part"
)
if expr.startswith("{"):
# Separate pair of opening brackets as "{ {"
self.write(" ")