Skip to content

Commit 8f37e84

Browse files
zsolambv
authored andcommitted
Add support for all string literals to lib2to3 (#6457)
1 parent c89b221 commit 8f37e84

File tree

2 files changed

+28
-52
lines changed

2 files changed

+28
-52
lines changed

Lib/lib2to3/pgen2/tokenize.py

Lines changed: 26 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@
4848
def group(*choices): return '(' + '|'.join(choices) + ')'
4949
def any(*choices): return group(*choices) + '*'
5050
def maybe(*choices): return group(*choices) + '?'
51+
def _combinations(*l):
52+
return set(
53+
x + y for x in l for y in l + ("",) if x.casefold() != y.casefold()
54+
)
5155

5256
Whitespace = r'[ \f\t]*'
5357
Comment = r'#[^\r\n]*'
@@ -74,7 +78,7 @@ def maybe(*choices): return group(*choices) + '?'
7478
Single3 = r"[^'\\]*(?:(?:\\.|'(?!''))[^'\\]*)*'''"
7579
# Tail end of """ string.
7680
Double3 = r'[^"\\]*(?:(?:\\.|"(?!""))[^"\\]*)*"""'
77-
_litprefix = r"(?:[uUrRbBfF]|[rR][bB]|[bBuU][rR])?"
81+
_litprefix = r"(?:[uUrRbBfF]|[rR][fFbB]|[fFbBuU][rR])?"
7882
Triple = group(_litprefix + "'''", _litprefix + '"""')
7983
# Single-line ' or " string.
8084
String = group(_litprefix + r"'[^\n'\\]*(?:\\.[^\n'\\]*)*'",
@@ -105,59 +109,29 @@ def maybe(*choices): return group(*choices) + '?'
105109

106110
tokenprog, pseudoprog, single3prog, double3prog = list(map(
107111
re.compile, (Token, PseudoToken, Single3, Double3)))
112+
113+
_strprefixes = (
114+
_combinations('r', 'R', 'f', 'F') |
115+
_combinations('r', 'R', 'b', 'B') |
116+
{'u', 'U', 'ur', 'uR', 'Ur', 'UR'}
117+
)
118+
108119
endprogs = {"'": re.compile(Single), '"': re.compile(Double),
109120
"'''": single3prog, '"""': double3prog,
110-
"r'''": single3prog, 'r"""': double3prog,
111-
"u'''": single3prog, 'u"""': double3prog,
112-
"b'''": single3prog, 'b"""': double3prog,
113-
"f'''": single3prog, 'f"""': double3prog,
114-
"ur'''": single3prog, 'ur"""': double3prog,
115-
"br'''": single3prog, 'br"""': double3prog,
116-
"rb'''": single3prog, 'rb"""': double3prog,
117-
"R'''": single3prog, 'R"""': double3prog,
118-
"U'''": single3prog, 'U"""': double3prog,
119-
"B'''": single3prog, 'B"""': double3prog,
120-
"F'''": single3prog, 'F"""': double3prog,
121-
"uR'''": single3prog, 'uR"""': double3prog,
122-
"Ur'''": single3prog, 'Ur"""': double3prog,
123-
"UR'''": single3prog, 'UR"""': double3prog,
124-
"bR'''": single3prog, 'bR"""': double3prog,
125-
"Br'''": single3prog, 'Br"""': double3prog,
126-
"BR'''": single3prog, 'BR"""': double3prog,
127-
"rB'''": single3prog, 'rB"""': double3prog,
128-
"Rb'''": single3prog, 'Rb"""': double3prog,
129-
"RB'''": single3prog, 'RB"""': double3prog,
130-
'r': None, 'R': None,
131-
'u': None, 'U': None,
132-
'f': None, 'F': None,
133-
'b': None, 'B': None}
134-
135-
triple_quoted = {}
136-
for t in ("'''", '"""',
137-
"r'''", 'r"""', "R'''", 'R"""',
138-
"u'''", 'u"""', "U'''", 'U"""',
139-
"b'''", 'b"""', "B'''", 'B"""',
140-
"f'''", 'f"""', "F'''", 'F"""',
141-
"ur'''", 'ur"""', "Ur'''", 'Ur"""',
142-
"uR'''", 'uR"""', "UR'''", 'UR"""',
143-
"br'''", 'br"""', "Br'''", 'Br"""',
144-
"bR'''", 'bR"""', "BR'''", 'BR"""',
145-
"rb'''", 'rb"""', "Rb'''", 'Rb"""',
146-
"rB'''", 'rB"""', "RB'''", 'RB"""',):
147-
triple_quoted[t] = t
148-
single_quoted = {}
149-
for t in ("'", '"',
150-
"r'", 'r"', "R'", 'R"',
151-
"u'", 'u"', "U'", 'U"',
152-
"b'", 'b"', "B'", 'B"',
153-
"f'", 'f"', "F'", 'F"',
154-
"ur'", 'ur"', "Ur'", 'Ur"',
155-
"uR'", 'uR"', "UR'", 'UR"',
156-
"br'", 'br"', "Br'", 'Br"',
157-
"bR'", 'bR"', "BR'", 'BR"',
158-
"rb'", 'rb"', "Rb'", 'Rb"',
159-
"rB'", 'rB"', "RB'", 'RB"',):
160-
single_quoted[t] = t
121+
**{f"{prefix}'''": single3prog for prefix in _strprefixes},
122+
**{f'{prefix}"""': double3prog for prefix in _strprefixes},
123+
**{prefix: None for prefix in _strprefixes}}
124+
125+
triple_quoted = (
126+
{"'''", '"""'} |
127+
{f"{prefix}'''" for prefix in _strprefixes} |
128+
{f'{prefix}"""' for prefix in _strprefixes}
129+
)
130+
single_quoted = (
131+
{"'", '"'} |
132+
{f"{prefix}'" for prefix in _strprefixes} |
133+
{f'{prefix}"' for prefix in _strprefixes}
134+
)
161135

162136
tabsize = 8
163137

Lib/lib2to3/tests/data/py3_test_grammar.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,8 @@ def testStringLiterals(self):
147147
the \'lazy\' dog.\n\
148148
'
149149
self.assertEquals(x, y)
150+
x = rf"hello \{True}"; y = f"hello \\{True}"
151+
self.assertEquals(x, y)
150152

151153
def testEllipsis(self):
152154
x = ...

0 commit comments

Comments
 (0)