diff options
author | Shantanu <12621235+hauntsaninja@users.noreply.github.com> | 2023-09-18 13:56:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-18 13:56:19 (GMT) |
commit | 23f9f6f46454455bc6015e83ae5b5e946dae7698 (patch) | |
tree | 7a11c11779c51118016423ed45ed7fd305565f9e /Lib/ast.py | |
parent | 4dd47c63a97b3c39cd964ad12431fcdaf76dc823 (diff) | |
download | cpython-23f9f6f46454455bc6015e83ae5b5e946dae7698.zip cpython-23f9f6f46454455bc6015e83ae5b5e946dae7698.tar.gz cpython-23f9f6f46454455bc6015e83ae5b5e946dae7698.tar.bz2 |
gh-108843: fix ast.unparse for f-string with many quotes (#108981)
Diffstat (limited to 'Lib/ast.py')
-rw-r--r-- | Lib/ast.py | 21 |
1 files changed, 20 insertions, 1 deletions
@@ -1236,17 +1236,36 @@ class _Unparser(NodeVisitor): new_fstring_parts = [] quote_types = list(_ALL_QUOTES) + fallback_to_repr = False for value, is_constant in fstring_parts: if is_constant: - value, quote_types = self._str_literal_helper( + value, new_quote_types = self._str_literal_helper( value, quote_types=quote_types, escape_special_whitespace=True, ) + if set(new_quote_types).isdisjoint(quote_types): + fallback_to_repr = True + break + quote_types = new_quote_types elif "\n" in value: quote_types = [q for q in quote_types if q in _MULTI_QUOTES] + assert quote_types new_fstring_parts.append(value) + if fallback_to_repr: + # If we weren't able to find a quote type that works for all parts + # of the JoinedStr, fallback to using repr and triple single quotes. + quote_types = ["'''"] + new_fstring_parts.clear() + for value, is_constant in fstring_parts: + if is_constant: + value = repr('"' + value) # force repr to use single quotes + expected_prefix = "'\"" + assert value.startswith(expected_prefix), repr(value) + value = value[len(expected_prefix):-1] + new_fstring_parts.append(value) + value = "".join(new_fstring_parts) quote_type = quote_types[0] self.write(f"{quote_type}{value}{quote_type}") |