1# -*- coding: utf-8 -*-
2# There are tests here with unicode string literals and
3# identifiers. There's a code in ast.c that was added because of a
4# failure with a non-ascii-only expression.  So, I have tests for
5# that.  There are workarounds that would let me run tests for that
6# code without unicode identifiers and strings, but just using them
7# directly seems like the easiest and therefore safest thing to do.
8# Unicode identifiers in tests is allowed by PEP 3131.
9
10import ast
11import os
12import re
13import types
14import decimal
15import unittest
16from test.support.os_helper import temp_cwd
17from test.support.script_helper import assert_python_failure
18
19a_global = 'global variable'
20
21# You could argue that I'm too strict in looking for specific error
22#  values with assertRaisesRegex, but without it it's way too easy to
23#  make a syntax error in the test strings. Especially with all of the
24#  triple quotes, raw strings, backslashes, etc. I think it's a
25#  worthwhile tradeoff. When I switched to this method, I found many
26#  examples where I wasn't testing what I thought I was.
27
28class TestCase(unittest.TestCase):
29    def assertAllRaise(self, exception_type, regex, error_strings):
30        for str in error_strings:
31            with self.subTest(str=str):
32                with self.assertRaisesRegex(exception_type, regex):
33                    eval(str)
34
35    def test__format__lookup(self):
36        # Make sure __format__ is looked up on the type, not the instance.
37        class X:
38            def __format__(self, spec):
39                return 'class'
40
41        x = X()
42
43        # Add a bound __format__ method to the 'y' instance, but not
44        #  the 'x' instance.
45        y = X()
46        y.__format__ = types.MethodType(lambda self, spec: 'instance', y)
47
48        self.assertEqual(f'{y}', format(y))
49        self.assertEqual(f'{y}', 'class')
50        self.assertEqual(format(x), format(y))
51
52        # __format__ is not called this way, but still make sure it
53        #  returns what we expect (so we can make sure we're bypassing
54        #  it).
55        self.assertEqual(x.__format__(''), 'class')
56        self.assertEqual(y.__format__(''), 'instance')
57
58        # This is how __format__ is actually called.
59        self.assertEqual(type(x).__format__(x, ''), 'class')
60        self.assertEqual(type(y).__format__(y, ''), 'class')
61
62    def test_ast(self):
63        # Inspired by http://bugs.python.org/issue24975
64        class X:
65            def __init__(self):
66                self.called = False
67            def __call__(self):
68                self.called = True
69                return 4
70        x = X()
71        expr = """
72a = 10
73f'{a * x()}'"""
74        t = ast.parse(expr)
75        c = compile(t, '', 'exec')
76
77        # Make sure x was not called.
78        self.assertFalse(x.called)
79
80        # Actually run the code.
81        exec(c)
82
83        # Make sure x was called.
84        self.assertTrue(x.called)
85
86    def test_ast_line_numbers(self):
87        expr = """
88a = 10
89f'{a * x()}'"""
90        t = ast.parse(expr)
91        self.assertEqual(type(t), ast.Module)
92        self.assertEqual(len(t.body), 2)
93        # check `a = 10`
94        self.assertEqual(type(t.body[0]), ast.Assign)
95        self.assertEqual(t.body[0].lineno, 2)
96        # check `f'...'`
97        self.assertEqual(type(t.body[1]), ast.Expr)
98        self.assertEqual(type(t.body[1].value), ast.JoinedStr)
99        self.assertEqual(len(t.body[1].value.values), 1)
100        self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
101        self.assertEqual(t.body[1].lineno, 3)
102        self.assertEqual(t.body[1].value.lineno, 3)
103        self.assertEqual(t.body[1].value.values[0].lineno, 3)
104        # check the binop location
105        binop = t.body[1].value.values[0].value
106        self.assertEqual(type(binop), ast.BinOp)
107        self.assertEqual(type(binop.left), ast.Name)
108        self.assertEqual(type(binop.op), ast.Mult)
109        self.assertEqual(type(binop.right), ast.Call)
110        self.assertEqual(binop.lineno, 3)
111        self.assertEqual(binop.left.lineno, 3)
112        self.assertEqual(binop.right.lineno, 3)
113        self.assertEqual(binop.col_offset, 3)
114        self.assertEqual(binop.left.col_offset, 3)
115        self.assertEqual(binop.right.col_offset, 7)
116
117    def test_ast_line_numbers_multiple_formattedvalues(self):
118        expr = """
119f'no formatted values'
120f'eggs {a * x()} spam {b + y()}'"""
121        t = ast.parse(expr)
122        self.assertEqual(type(t), ast.Module)
123        self.assertEqual(len(t.body), 2)
124        # check `f'no formatted value'`
125        self.assertEqual(type(t.body[0]), ast.Expr)
126        self.assertEqual(type(t.body[0].value), ast.JoinedStr)
127        self.assertEqual(t.body[0].lineno, 2)
128        # check `f'...'`
129        self.assertEqual(type(t.body[1]), ast.Expr)
130        self.assertEqual(type(t.body[1].value), ast.JoinedStr)
131        self.assertEqual(len(t.body[1].value.values), 4)
132        self.assertEqual(type(t.body[1].value.values[0]), ast.Constant)
133        self.assertEqual(type(t.body[1].value.values[0].value), str)
134        self.assertEqual(type(t.body[1].value.values[1]), ast.FormattedValue)
135        self.assertEqual(type(t.body[1].value.values[2]), ast.Constant)
136        self.assertEqual(type(t.body[1].value.values[2].value), str)
137        self.assertEqual(type(t.body[1].value.values[3]), ast.FormattedValue)
138        self.assertEqual(t.body[1].lineno, 3)
139        self.assertEqual(t.body[1].value.lineno, 3)
140        self.assertEqual(t.body[1].value.values[0].lineno, 3)
141        self.assertEqual(t.body[1].value.values[1].lineno, 3)
142        self.assertEqual(t.body[1].value.values[2].lineno, 3)
143        self.assertEqual(t.body[1].value.values[3].lineno, 3)
144        # check the first binop location
145        binop1 = t.body[1].value.values[1].value
146        self.assertEqual(type(binop1), ast.BinOp)
147        self.assertEqual(type(binop1.left), ast.Name)
148        self.assertEqual(type(binop1.op), ast.Mult)
149        self.assertEqual(type(binop1.right), ast.Call)
150        self.assertEqual(binop1.lineno, 3)
151        self.assertEqual(binop1.left.lineno, 3)
152        self.assertEqual(binop1.right.lineno, 3)
153        self.assertEqual(binop1.col_offset, 8)
154        self.assertEqual(binop1.left.col_offset, 8)
155        self.assertEqual(binop1.right.col_offset, 12)
156        # check the second binop location
157        binop2 = t.body[1].value.values[3].value
158        self.assertEqual(type(binop2), ast.BinOp)
159        self.assertEqual(type(binop2.left), ast.Name)
160        self.assertEqual(type(binop2.op), ast.Add)
161        self.assertEqual(type(binop2.right), ast.Call)
162        self.assertEqual(binop2.lineno, 3)
163        self.assertEqual(binop2.left.lineno, 3)
164        self.assertEqual(binop2.right.lineno, 3)
165        self.assertEqual(binop2.col_offset, 23)
166        self.assertEqual(binop2.left.col_offset, 23)
167        self.assertEqual(binop2.right.col_offset, 27)
168
169    def test_ast_line_numbers_nested(self):
170        expr = """
171a = 10
172f'{a * f"-{x()}-"}'"""
173        t = ast.parse(expr)
174        self.assertEqual(type(t), ast.Module)
175        self.assertEqual(len(t.body), 2)
176        # check `a = 10`
177        self.assertEqual(type(t.body[0]), ast.Assign)
178        self.assertEqual(t.body[0].lineno, 2)
179        # check `f'...'`
180        self.assertEqual(type(t.body[1]), ast.Expr)
181        self.assertEqual(type(t.body[1].value), ast.JoinedStr)
182        self.assertEqual(len(t.body[1].value.values), 1)
183        self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
184        self.assertEqual(t.body[1].lineno, 3)
185        self.assertEqual(t.body[1].value.lineno, 3)
186        self.assertEqual(t.body[1].value.values[0].lineno, 3)
187        # check the binop location
188        binop = t.body[1].value.values[0].value
189        self.assertEqual(type(binop), ast.BinOp)
190        self.assertEqual(type(binop.left), ast.Name)
191        self.assertEqual(type(binop.op), ast.Mult)
192        self.assertEqual(type(binop.right), ast.JoinedStr)
193        self.assertEqual(binop.lineno, 3)
194        self.assertEqual(binop.left.lineno, 3)
195        self.assertEqual(binop.right.lineno, 3)
196        self.assertEqual(binop.col_offset, 3)
197        self.assertEqual(binop.left.col_offset, 3)
198        self.assertEqual(binop.right.col_offset, 7)
199        # check the nested call location
200        self.assertEqual(len(binop.right.values), 3)
201        self.assertEqual(type(binop.right.values[0]), ast.Constant)
202        self.assertEqual(type(binop.right.values[0].value), str)
203        self.assertEqual(type(binop.right.values[1]), ast.FormattedValue)
204        self.assertEqual(type(binop.right.values[2]), ast.Constant)
205        self.assertEqual(type(binop.right.values[2].value), str)
206        self.assertEqual(binop.right.values[0].lineno, 3)
207        self.assertEqual(binop.right.values[1].lineno, 3)
208        self.assertEqual(binop.right.values[2].lineno, 3)
209        call = binop.right.values[1].value
210        self.assertEqual(type(call), ast.Call)
211        self.assertEqual(call.lineno, 3)
212        self.assertEqual(call.col_offset, 11)
213
214    def test_ast_line_numbers_duplicate_expression(self):
215        expr = """
216a = 10
217f'{a * x()} {a * x()} {a * x()}'
218"""
219        t = ast.parse(expr)
220        self.assertEqual(type(t), ast.Module)
221        self.assertEqual(len(t.body), 2)
222        # check `a = 10`
223        self.assertEqual(type(t.body[0]), ast.Assign)
224        self.assertEqual(t.body[0].lineno, 2)
225        # check `f'...'`
226        self.assertEqual(type(t.body[1]), ast.Expr)
227        self.assertEqual(type(t.body[1].value), ast.JoinedStr)
228        self.assertEqual(len(t.body[1].value.values), 5)
229        self.assertEqual(type(t.body[1].value.values[0]), ast.FormattedValue)
230        self.assertEqual(type(t.body[1].value.values[1]), ast.Constant)
231        self.assertEqual(type(t.body[1].value.values[1].value), str)
232        self.assertEqual(type(t.body[1].value.values[2]), ast.FormattedValue)
233        self.assertEqual(type(t.body[1].value.values[3]), ast.Constant)
234        self.assertEqual(type(t.body[1].value.values[3].value), str)
235        self.assertEqual(type(t.body[1].value.values[4]), ast.FormattedValue)
236        self.assertEqual(t.body[1].lineno, 3)
237        self.assertEqual(t.body[1].value.lineno, 3)
238        self.assertEqual(t.body[1].value.values[0].lineno, 3)
239        self.assertEqual(t.body[1].value.values[1].lineno, 3)
240        self.assertEqual(t.body[1].value.values[2].lineno, 3)
241        self.assertEqual(t.body[1].value.values[3].lineno, 3)
242        self.assertEqual(t.body[1].value.values[4].lineno, 3)
243        # check the first binop location
244        binop = t.body[1].value.values[0].value
245        self.assertEqual(type(binop), ast.BinOp)
246        self.assertEqual(type(binop.left), ast.Name)
247        self.assertEqual(type(binop.op), ast.Mult)
248        self.assertEqual(type(binop.right), ast.Call)
249        self.assertEqual(binop.lineno, 3)
250        self.assertEqual(binop.left.lineno, 3)
251        self.assertEqual(binop.right.lineno, 3)
252        self.assertEqual(binop.col_offset, 3)
253        self.assertEqual(binop.left.col_offset, 3)
254        self.assertEqual(binop.right.col_offset, 7)
255        # check the second binop location
256        binop = t.body[1].value.values[2].value
257        self.assertEqual(type(binop), ast.BinOp)
258        self.assertEqual(type(binop.left), ast.Name)
259        self.assertEqual(type(binop.op), ast.Mult)
260        self.assertEqual(type(binop.right), ast.Call)
261        self.assertEqual(binop.lineno, 3)
262        self.assertEqual(binop.left.lineno, 3)
263        self.assertEqual(binop.right.lineno, 3)
264        self.assertEqual(binop.col_offset, 13)
265        self.assertEqual(binop.left.col_offset, 13)
266        self.assertEqual(binop.right.col_offset, 17)
267        # check the third binop location
268        binop = t.body[1].value.values[4].value
269        self.assertEqual(type(binop), ast.BinOp)
270        self.assertEqual(type(binop.left), ast.Name)
271        self.assertEqual(type(binop.op), ast.Mult)
272        self.assertEqual(type(binop.right), ast.Call)
273        self.assertEqual(binop.lineno, 3)
274        self.assertEqual(binop.left.lineno, 3)
275        self.assertEqual(binop.right.lineno, 3)
276        self.assertEqual(binop.col_offset, 23)
277        self.assertEqual(binop.left.col_offset, 23)
278        self.assertEqual(binop.right.col_offset, 27)
279
280    def test_ast_numbers_fstring_with_formatting(self):
281
282        t = ast.parse('f"Here is that pesky {xxx:.3f} again"')
283        self.assertEqual(len(t.body), 1)
284        self.assertEqual(t.body[0].lineno, 1)
285
286        self.assertEqual(type(t.body[0]), ast.Expr)
287        self.assertEqual(type(t.body[0].value), ast.JoinedStr)
288        self.assertEqual(len(t.body[0].value.values), 3)
289
290        self.assertEqual(type(t.body[0].value.values[0]), ast.Constant)
291        self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue)
292        self.assertEqual(type(t.body[0].value.values[2]), ast.Constant)
293
294        _, expr, _ = t.body[0].value.values
295
296        name = expr.value
297        self.assertEqual(type(name), ast.Name)
298        self.assertEqual(name.lineno, 1)
299        self.assertEqual(name.end_lineno, 1)
300        self.assertEqual(name.col_offset, 22)
301        self.assertEqual(name.end_col_offset, 25)
302
303    def test_ast_line_numbers_multiline_fstring(self):
304        # See bpo-30465 for details.
305        expr = """
306a = 10
307f'''
308  {a
309     *
310       x()}
311non-important content
312'''
313"""
314        t = ast.parse(expr)
315        self.assertEqual(type(t), ast.Module)
316        self.assertEqual(len(t.body), 2)
317        # check `a = 10`
318        self.assertEqual(type(t.body[0]), ast.Assign)
319        self.assertEqual(t.body[0].lineno, 2)
320        # check `f'...'`
321        self.assertEqual(type(t.body[1]), ast.Expr)
322        self.assertEqual(type(t.body[1].value), ast.JoinedStr)
323        self.assertEqual(len(t.body[1].value.values), 3)
324        self.assertEqual(type(t.body[1].value.values[0]), ast.Constant)
325        self.assertEqual(type(t.body[1].value.values[0].value), str)
326        self.assertEqual(type(t.body[1].value.values[1]), ast.FormattedValue)
327        self.assertEqual(type(t.body[1].value.values[2]), ast.Constant)
328        self.assertEqual(type(t.body[1].value.values[2].value), str)
329        self.assertEqual(t.body[1].lineno, 3)
330        self.assertEqual(t.body[1].value.lineno, 3)
331        self.assertEqual(t.body[1].value.values[0].lineno, 3)
332        self.assertEqual(t.body[1].value.values[1].lineno, 3)
333        self.assertEqual(t.body[1].value.values[2].lineno, 3)
334        self.assertEqual(t.body[1].col_offset, 0)
335        self.assertEqual(t.body[1].value.col_offset, 0)
336        self.assertEqual(t.body[1].value.values[0].col_offset, 0)
337        self.assertEqual(t.body[1].value.values[1].col_offset, 0)
338        self.assertEqual(t.body[1].value.values[2].col_offset, 0)
339        # NOTE: the following lineno information and col_offset is correct for
340        # expressions within FormattedValues.
341        binop = t.body[1].value.values[1].value
342        self.assertEqual(type(binop), ast.BinOp)
343        self.assertEqual(type(binop.left), ast.Name)
344        self.assertEqual(type(binop.op), ast.Mult)
345        self.assertEqual(type(binop.right), ast.Call)
346        self.assertEqual(binop.lineno, 4)
347        self.assertEqual(binop.left.lineno, 4)
348        self.assertEqual(binop.right.lineno, 6)
349        self.assertEqual(binop.col_offset, 3)
350        self.assertEqual(binop.left.col_offset, 3)
351        self.assertEqual(binop.right.col_offset, 7)
352
353        expr = """
354a = f'''
355          {blech}
356    '''
357"""
358        t = ast.parse(expr)
359        self.assertEqual(type(t), ast.Module)
360        self.assertEqual(len(t.body), 1)
361        # Check f'...'
362        self.assertEqual(type(t.body[0]), ast.Assign)
363        self.assertEqual(type(t.body[0].value), ast.JoinedStr)
364        self.assertEqual(len(t.body[0].value.values), 3)
365        self.assertEqual(type(t.body[0].value.values[1]), ast.FormattedValue)
366        self.assertEqual(t.body[0].lineno, 2)
367        self.assertEqual(t.body[0].value.lineno, 2)
368        self.assertEqual(t.body[0].value.values[0].lineno, 2)
369        self.assertEqual(t.body[0].value.values[1].lineno, 2)
370        self.assertEqual(t.body[0].value.values[2].lineno, 2)
371        self.assertEqual(t.body[0].col_offset, 0)
372        self.assertEqual(t.body[0].value.col_offset, 4)
373        self.assertEqual(t.body[0].value.values[0].col_offset, 4)
374        self.assertEqual(t.body[0].value.values[1].col_offset, 4)
375        self.assertEqual(t.body[0].value.values[2].col_offset, 4)
376        # Check {blech}
377        self.assertEqual(t.body[0].value.values[1].value.lineno, 3)
378        self.assertEqual(t.body[0].value.values[1].value.end_lineno, 3)
379        self.assertEqual(t.body[0].value.values[1].value.col_offset, 11)
380        self.assertEqual(t.body[0].value.values[1].value.end_col_offset, 16)
381
382    def test_ast_line_numbers_with_parentheses(self):
383        expr = """
384x = (
385    f" {test(t)}"
386)"""
387        t = ast.parse(expr)
388        self.assertEqual(type(t), ast.Module)
389        self.assertEqual(len(t.body), 1)
390        # check the test(t) location
391        call = t.body[0].value.values[1].value
392        self.assertEqual(type(call), ast.Call)
393        self.assertEqual(call.lineno, 3)
394        self.assertEqual(call.end_lineno, 3)
395        self.assertEqual(call.col_offset, 8)
396        self.assertEqual(call.end_col_offset, 15)
397
398        expr = """
399x = (
400        'PERL_MM_OPT', (
401            f'wat'
402            f'some_string={f(x)} '
403            f'wat'
404        ),
405)
406"""
407        t = ast.parse(expr)
408        self.assertEqual(type(t), ast.Module)
409        self.assertEqual(len(t.body), 1)
410        # check the fstring
411        fstring = t.body[0].value.elts[1]
412        self.assertEqual(type(fstring), ast.JoinedStr)
413        self.assertEqual(len(fstring.values), 3)
414        wat1, middle, wat2 = fstring.values
415        # check the first wat
416        self.assertEqual(type(wat1), ast.Constant)
417        self.assertEqual(wat1.lineno, 4)
418        self.assertEqual(wat1.end_lineno, 6)
419        self.assertEqual(wat1.col_offset, 12)
420        self.assertEqual(wat1.end_col_offset, 18)
421        # check the call
422        call = middle.value
423        self.assertEqual(type(call), ast.Call)
424        self.assertEqual(call.lineno, 5)
425        self.assertEqual(call.end_lineno, 5)
426        self.assertEqual(call.col_offset, 27)
427        self.assertEqual(call.end_col_offset, 31)
428        # check the second wat
429        self.assertEqual(type(wat2), ast.Constant)
430        self.assertEqual(wat2.lineno, 4)
431        self.assertEqual(wat2.end_lineno, 6)
432        self.assertEqual(wat2.col_offset, 12)
433        self.assertEqual(wat2.end_col_offset, 18)
434
435    def test_docstring(self):
436        def f():
437            f'''Not a docstring'''
438        self.assertIsNone(f.__doc__)
439        def g():
440            '''Not a docstring''' \
441            f''
442        self.assertIsNone(g.__doc__)
443
444    def test_literal_eval(self):
445        with self.assertRaisesRegex(ValueError, 'malformed node or string'):
446            ast.literal_eval("f'x'")
447
448    def test_ast_compile_time_concat(self):
449        x = ['']
450
451        expr = """x[0] = 'foo' f'{3}'"""
452        t = ast.parse(expr)
453        c = compile(t, '', 'exec')
454        exec(c)
455        self.assertEqual(x[0], 'foo3')
456
457    def test_compile_time_concat_errors(self):
458        self.assertAllRaise(SyntaxError,
459                            'cannot mix bytes and nonbytes literals',
460                            [r"""f'' b''""",
461                             r"""b'' f''""",
462                             ])
463
464    def test_literal(self):
465        self.assertEqual(f'', '')
466        self.assertEqual(f'a', 'a')
467        self.assertEqual(f' ', ' ')
468
469    def test_unterminated_string(self):
470        self.assertAllRaise(SyntaxError, 'f-string: unterminated string',
471                            [r"""f'{"x'""",
472                             r"""f'{"x}'""",
473                             r"""f'{("x'""",
474                             r"""f'{("x}'""",
475                             ])
476
477    def test_mismatched_parens(self):
478        self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' "
479                            r"does not match opening parenthesis '\('",
480                            ["f'{((}'",
481                             ])
482        self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\)' "
483                            r"does not match opening parenthesis '\['",
484                            ["f'{a[4)}'",
485                            ])
486        self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\]' "
487                            r"does not match opening parenthesis '\('",
488                            ["f'{a(4]}'",
489                            ])
490        self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' "
491                            r"does not match opening parenthesis '\['",
492                            ["f'{a[4}'",
493                            ])
494        self.assertAllRaise(SyntaxError, r"f-string: closing parenthesis '\}' "
495                            r"does not match opening parenthesis '\('",
496                            ["f'{a(4}'",
497                            ])
498        self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'")
499
500    def test_double_braces(self):
501        self.assertEqual(f'{{', '{')
502        self.assertEqual(f'a{{', 'a{')
503        self.assertEqual(f'{{b', '{b')
504        self.assertEqual(f'a{{b', 'a{b')
505        self.assertEqual(f'}}', '}')
506        self.assertEqual(f'a}}', 'a}')
507        self.assertEqual(f'}}b', '}b')
508        self.assertEqual(f'a}}b', 'a}b')
509        self.assertEqual(f'{{}}', '{}')
510        self.assertEqual(f'a{{}}', 'a{}')
511        self.assertEqual(f'{{b}}', '{b}')
512        self.assertEqual(f'{{}}c', '{}c')
513        self.assertEqual(f'a{{b}}', 'a{b}')
514        self.assertEqual(f'a{{}}c', 'a{}c')
515        self.assertEqual(f'{{b}}c', '{b}c')
516        self.assertEqual(f'a{{b}}c', 'a{b}c')
517
518        self.assertEqual(f'{{{10}', '{10')
519        self.assertEqual(f'}}{10}', '}10')
520        self.assertEqual(f'}}{{{10}', '}{10')
521        self.assertEqual(f'}}a{{{10}', '}a{10')
522
523        self.assertEqual(f'{10}{{', '10{')
524        self.assertEqual(f'{10}}}', '10}')
525        self.assertEqual(f'{10}}}{{', '10}{')
526        self.assertEqual(f'{10}}}a{{' '}', '10}a{}')
527
528        # Inside of strings, don't interpret doubled brackets.
529        self.assertEqual(f'{"{{}}"}', '{{}}')
530
531        self.assertAllRaise(TypeError, 'unhashable type',
532                            ["f'{ {{}} }'", # dict in a set
533                             ])
534
535    def test_compile_time_concat(self):
536        x = 'def'
537        self.assertEqual('abc' f'## {x}ghi', 'abc## defghi')
538        self.assertEqual('abc' f'{x}' 'ghi', 'abcdefghi')
539        self.assertEqual('abc' f'{x}' 'gh' f'i{x:4}', 'abcdefghidef ')
540        self.assertEqual('{x}' f'{x}', '{x}def')
541        self.assertEqual('{x' f'{x}', '{xdef')
542        self.assertEqual('{x}' f'{x}', '{x}def')
543        self.assertEqual('{{x}}' f'{x}', '{{x}}def')
544        self.assertEqual('{{x' f'{x}', '{{xdef')
545        self.assertEqual('x}}' f'{x}', 'x}}def')
546        self.assertEqual(f'{x}' 'x}}', 'defx}}')
547        self.assertEqual(f'{x}' '', 'def')
548        self.assertEqual('' f'{x}' '', 'def')
549        self.assertEqual('' f'{x}', 'def')
550        self.assertEqual(f'{x}' '2', 'def2')
551        self.assertEqual('1' f'{x}' '2', '1def2')
552        self.assertEqual('1' f'{x}', '1def')
553        self.assertEqual(f'{x}' f'-{x}', 'def-def')
554        self.assertEqual('' f'', '')
555        self.assertEqual('' f'' '', '')
556        self.assertEqual('' f'' '' f'', '')
557        self.assertEqual(f'', '')
558        self.assertEqual(f'' '', '')
559        self.assertEqual(f'' '' f'', '')
560        self.assertEqual(f'' '' f'' '', '')
561
562        self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
563                            ["f'{3' f'}'",  # can't concat to get a valid f-string
564                             ])
565
566    def test_comments(self):
567        # These aren't comments, since they're in strings.
568        d = {'#': 'hash'}
569        self.assertEqual(f'{"#"}', '#')
570        self.assertEqual(f'{d["#"]}', 'hash')
571
572        self.assertAllRaise(SyntaxError, "f-string expression part cannot include '#'",
573                            ["f'{1#}'",   # error because the expression becomes "(1#)"
574                             "f'{3(#)}'",
575                             "f'{#}'",
576                             ])
577        self.assertAllRaise(SyntaxError, r"f-string: unmatched '\)'",
578                            ["f'{)#}'",   # When wrapped in parens, this becomes
579                                          #  '()#)'.  Make sure that doesn't compile.
580                             ])
581
582    def test_many_expressions(self):
583        # Create a string with many expressions in it. Note that
584        #  because we have a space in here as a literal, we're actually
585        #  going to use twice as many ast nodes: one for each literal
586        #  plus one for each expression.
587        def build_fstr(n, extra=''):
588            return "f'" + ('{x} ' * n) + extra + "'"
589
590        x = 'X'
591        width = 1
592
593        # Test around 256.
594        for i in range(250, 260):
595            self.assertEqual(eval(build_fstr(i)), (x+' ')*i)
596
597        # Test concatenating 2 largs fstrings.
598        self.assertEqual(eval(build_fstr(255)*256), (x+' ')*(255*256))
599
600        s = build_fstr(253, '{x:{width}} ')
601        self.assertEqual(eval(s), (x+' ')*254)
602
603        # Test lots of expressions and constants, concatenated.
604        s = "f'{1}' 'x' 'y'" * 1024
605        self.assertEqual(eval(s), '1xy' * 1024)
606
607    def test_format_specifier_expressions(self):
608        width = 10
609        precision = 4
610        value = decimal.Decimal('12.34567')
611        self.assertEqual(f'result: {value:{width}.{precision}}', 'result:      12.35')
612        self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result:      12.35')
613        self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result:      12.35')
614        self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result:      12.35')
615        self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result:      12.35')
616        self.assertEqual(f'{10:#{1}0x}', '       0xa')
617        self.assertEqual(f'{10:{"#"}1{0}{"x"}}', '       0xa')
618        self.assertEqual(f'{-10:-{"#"}1{0}x}', '      -0xa')
619        self.assertEqual(f'{-10:{"-"}#{1}0{"x"}}', '      -0xa')
620        self.assertEqual(f'{10:#{3 != {4:5} and width}x}', '       0xa')
621
622        self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
623                            ["""f'{"s"!r{":10"}}'""",
624
625                             # This looks like a nested format spec.
626                             ])
627
628        self.assertAllRaise(SyntaxError, "f-string: invalid syntax",
629                            [# Invalid syntax inside a nested spec.
630                             "f'{4:{/5}}'",
631                             ])
632
633        self.assertAllRaise(SyntaxError, "f-string: expressions nested too deeply",
634                            [# Can't nest format specifiers.
635                             "f'result: {value:{width:{0}}.{precision:1}}'",
636                             ])
637
638        self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character',
639                            [# No expansion inside conversion or for
640                             #  the : or ! itself.
641                             """f'{"s"!{"r"}}'""",
642                             ])
643
644    def test_side_effect_order(self):
645        class X:
646            def __init__(self):
647                self.i = 0
648            def __format__(self, spec):
649                self.i += 1
650                return str(self.i)
651
652        x = X()
653        self.assertEqual(f'{x} {x}', '1 2')
654
655    def test_missing_expression(self):
656        self.assertAllRaise(SyntaxError, 'f-string: empty expression not allowed',
657                            ["f'{}'",
658                             "f'{ }'"
659                             "f' {} '",
660                             "f'{10:{ }}'",
661                             "f' { } '",
662
663                             # The Python parser ignores also the following
664                             # whitespace characters in additional to a space.
665                             "f'''{\t\f\r\n}'''",
666                             ])
667
668        # Different error messeges are raised when a specfier ('!', ':' or '=') is used after an empty expression
669        self.assertAllRaise(SyntaxError, "f-string: expression required before '!'",
670                            ["f'{!r}'",
671                             "f'{ !r}'",
672                             "f'{!}'",
673                             "f'''{\t\f\r\n!a}'''",
674
675                             # Catch empty expression before the
676                             #  missing closing brace.
677                             "f'{!'",
678                             "f'{!s:'",
679
680                             # Catch empty expression before the
681                             #  invalid conversion.
682                             "f'{!x}'",
683                             "f'{ !xr}'",
684                             "f'{!x:}'",
685                             "f'{!x:a}'",
686                             "f'{ !xr:}'",
687                             "f'{ !xr:a}'",
688                             ])
689
690        self.assertAllRaise(SyntaxError, "f-string: expression required before ':'",
691                            ["f'{:}'",
692                             "f'{ :!}'",
693                             "f'{:2}'",
694                             "f'''{\t\f\r\n:a}'''",
695                             "f'{:'",
696                             ])
697
698        self.assertAllRaise(SyntaxError, "f-string: expression required before '='",
699                            ["f'{=}'",
700                             "f'{ =}'",
701                             "f'{ =:}'",
702                             "f'{   =!}'",
703                             "f'''{\t\f\r\n=}'''",
704                             "f'{='",
705                             ])
706
707        # Different error message is raised for other whitespace characters.
708        self.assertAllRaise(SyntaxError, r"invalid non-printable character U\+00A0",
709                            ["f'''{\xa0}'''",
710                             "\xa0",
711                             ])
712
713    def test_parens_in_expressions(self):
714        self.assertEqual(f'{3,}', '(3,)')
715
716        # Add these because when an expression is evaluated, parens
717        #  are added around it. But we shouldn't go from an invalid
718        #  expression to a valid one. The added parens are just
719        #  supposed to allow whitespace (including newlines).
720        self.assertAllRaise(SyntaxError, 'f-string: invalid syntax',
721                            ["f'{,}'",
722                             "f'{,}'",  # this is (,), which is an error
723                             ])
724
725        self.assertAllRaise(SyntaxError, r"f-string: unmatched '\)'",
726                            ["f'{3)+(4}'",
727                             ])
728
729        self.assertAllRaise(SyntaxError, 'unterminated string literal',
730                            ["f'{\n}'",
731                             ])
732    def test_newlines_before_syntax_error(self):
733        self.assertAllRaise(SyntaxError, "invalid syntax",
734                ["f'{.}'", "\nf'{.}'", "\n\nf'{.}'"])
735
736    def test_backslashes_in_string_part(self):
737        self.assertEqual(f'\t', '\t')
738        self.assertEqual(r'\t', '\\t')
739        self.assertEqual(rf'\t', '\\t')
740        self.assertEqual(f'{2}\t', '2\t')
741        self.assertEqual(f'{2}\t{3}', '2\t3')
742        self.assertEqual(f'\t{3}', '\t3')
743
744        self.assertEqual(f'\u0394', '\u0394')
745        self.assertEqual(r'\u0394', '\\u0394')
746        self.assertEqual(rf'\u0394', '\\u0394')
747        self.assertEqual(f'{2}\u0394', '2\u0394')
748        self.assertEqual(f'{2}\u0394{3}', '2\u03943')
749        self.assertEqual(f'\u0394{3}', '\u03943')
750
751        self.assertEqual(f'\U00000394', '\u0394')
752        self.assertEqual(r'\U00000394', '\\U00000394')
753        self.assertEqual(rf'\U00000394', '\\U00000394')
754        self.assertEqual(f'{2}\U00000394', '2\u0394')
755        self.assertEqual(f'{2}\U00000394{3}', '2\u03943')
756        self.assertEqual(f'\U00000394{3}', '\u03943')
757
758        self.assertEqual(f'\N{GREEK CAPITAL LETTER DELTA}', '\u0394')
759        self.assertEqual(f'{2}\N{GREEK CAPITAL LETTER DELTA}', '2\u0394')
760        self.assertEqual(f'{2}\N{GREEK CAPITAL LETTER DELTA}{3}', '2\u03943')
761        self.assertEqual(f'\N{GREEK CAPITAL LETTER DELTA}{3}', '\u03943')
762        self.assertEqual(f'2\N{GREEK CAPITAL LETTER DELTA}', '2\u0394')
763        self.assertEqual(f'2\N{GREEK CAPITAL LETTER DELTA}3', '2\u03943')
764        self.assertEqual(f'\N{GREEK CAPITAL LETTER DELTA}3', '\u03943')
765
766        self.assertEqual(f'\x20', ' ')
767        self.assertEqual(r'\x20', '\\x20')
768        self.assertEqual(rf'\x20', '\\x20')
769        self.assertEqual(f'{2}\x20', '2 ')
770        self.assertEqual(f'{2}\x20{3}', '2 3')
771        self.assertEqual(f'\x20{3}', ' 3')
772
773        self.assertEqual(f'2\x20', '2 ')
774        self.assertEqual(f'2\x203', '2 3')
775        self.assertEqual(f'\x203', ' 3')
776
777        with self.assertWarns(DeprecationWarning):  # invalid escape sequence
778            value = eval(r"f'\{6*7}'")
779        self.assertEqual(value, '\\42')
780        self.assertEqual(f'\\{6*7}', '\\42')
781        self.assertEqual(fr'\{6*7}', '\\42')
782
783        AMPERSAND = 'spam'
784        # Get the right unicode character (&), or pick up local variable
785        # depending on the number of backslashes.
786        self.assertEqual(f'\N{AMPERSAND}', '&')
787        self.assertEqual(f'\\N{AMPERSAND}', '\\Nspam')
788        self.assertEqual(fr'\N{AMPERSAND}', '\\Nspam')
789        self.assertEqual(f'\\\N{AMPERSAND}', '\\&')
790
791    def test_misformed_unicode_character_name(self):
792        # These test are needed because unicode names are parsed
793        # differently inside f-strings.
794        self.assertAllRaise(SyntaxError, r"\(unicode error\) 'unicodeescape' codec can't decode bytes in position .*: malformed \\N character escape",
795                            [r"f'\N'",
796                             r"f'\N '",
797                             r"f'\N  '",  # See bpo-46503.
798                             r"f'\N{'",
799                             r"f'\N{GREEK CAPITAL LETTER DELTA'",
800
801                             # Here are the non-f-string versions,
802                             #  which should give the same errors.
803                             r"'\N'",
804                             r"'\N '",
805                             r"'\N  '",
806                             r"'\N{'",
807                             r"'\N{GREEK CAPITAL LETTER DELTA'",
808                             ])
809
810    def test_no_backslashes_in_expression_part(self):
811        self.assertAllRaise(SyntaxError, 'f-string expression part cannot include a backslash',
812                            [r"f'{\'a\'}'",
813                             r"f'{\t3}'",
814                             r"f'{\}'",
815                             r"rf'{\'a\'}'",
816                             r"rf'{\t3}'",
817                             r"rf'{\}'",
818                             r"""rf'{"\N{LEFT CURLY BRACKET}"}'""",
819                             r"f'{\n}'",
820                             ])
821
822    def test_no_escapes_for_braces(self):
823        """
824        Only literal curly braces begin an expression.
825        """
826        # \x7b is '{'.
827        self.assertEqual(f'\x7b1+1}}', '{1+1}')
828        self.assertEqual(f'\x7b1+1', '{1+1')
829        self.assertEqual(f'\u007b1+1', '{1+1')
830        self.assertEqual(f'\N{LEFT CURLY BRACKET}1+1\N{RIGHT CURLY BRACKET}', '{1+1}')
831
832    def test_newlines_in_expressions(self):
833        self.assertEqual(f'{0}', '0')
834        self.assertEqual(rf'''{3+
8354}''', '7')
836
837    def test_lambda(self):
838        x = 5
839        self.assertEqual(f'{(lambda y:x*y)("8")!r}', "'88888'")
840        self.assertEqual(f'{(lambda y:x*y)("8")!r:10}', "'88888'   ")
841        self.assertEqual(f'{(lambda y:x*y)("8"):10}', "88888     ")
842
843        # lambda doesn't work without parens, because the colon
844        #  makes the parser think it's a format_spec
845        self.assertAllRaise(SyntaxError, 'f-string: invalid syntax',
846                            ["f'{lambda x:x}'",
847                             ])
848
849    def test_yield(self):
850        # Not terribly useful, but make sure the yield turns
851        #  a function into a generator
852        def fn(y):
853            f'y:{yield y*2}'
854            f'{yield}'
855
856        g = fn(4)
857        self.assertEqual(next(g), 8)
858        self.assertEqual(next(g), None)
859
860    def test_yield_send(self):
861        def fn(x):
862            yield f'x:{yield (lambda i: x * i)}'
863
864        g = fn(10)
865        the_lambda = next(g)
866        self.assertEqual(the_lambda(4), 40)
867        self.assertEqual(g.send('string'), 'x:string')
868
869    def test_expressions_with_triple_quoted_strings(self):
870        self.assertEqual(f"{'''x'''}", 'x')
871        self.assertEqual(f"{'''eric's'''}", "eric's")
872
873        # Test concatenation within an expression
874        self.assertEqual(f'{"x" """eric"s""" "y"}', 'xeric"sy')
875        self.assertEqual(f'{"x" """eric"s"""}', 'xeric"s')
876        self.assertEqual(f'{"""eric"s""" "y"}', 'eric"sy')
877        self.assertEqual(f'{"""x""" """eric"s""" "y"}', 'xeric"sy')
878        self.assertEqual(f'{"""x""" """eric"s""" """y"""}', 'xeric"sy')
879        self.assertEqual(f'{r"""x""" """eric"s""" """y"""}', 'xeric"sy')
880
881    def test_multiple_vars(self):
882        x = 98
883        y = 'abc'
884        self.assertEqual(f'{x}{y}', '98abc')
885
886        self.assertEqual(f'X{x}{y}', 'X98abc')
887        self.assertEqual(f'{x}X{y}', '98Xabc')
888        self.assertEqual(f'{x}{y}X', '98abcX')
889
890        self.assertEqual(f'X{x}Y{y}', 'X98Yabc')
891        self.assertEqual(f'X{x}{y}Y', 'X98abcY')
892        self.assertEqual(f'{x}X{y}Y', '98XabcY')
893
894        self.assertEqual(f'X{x}Y{y}Z', 'X98YabcZ')
895
896    def test_closure(self):
897        def outer(x):
898            def inner():
899                return f'x:{x}'
900            return inner
901
902        self.assertEqual(outer('987')(), 'x:987')
903        self.assertEqual(outer(7)(), 'x:7')
904
905    def test_arguments(self):
906        y = 2
907        def f(x, width):
908            return f'x={x*y:{width}}'
909
910        self.assertEqual(f('foo', 10), 'x=foofoo    ')
911        x = 'bar'
912        self.assertEqual(f(10, 10), 'x=        20')
913
914    def test_locals(self):
915        value = 123
916        self.assertEqual(f'v:{value}', 'v:123')
917
918    def test_missing_variable(self):
919        with self.assertRaises(NameError):
920            f'v:{value}'
921
922    def test_missing_format_spec(self):
923        class O:
924            def __format__(self, spec):
925                if not spec:
926                    return '*'
927                return spec
928
929        self.assertEqual(f'{O():x}', 'x')
930        self.assertEqual(f'{O()}', '*')
931        self.assertEqual(f'{O():}', '*')
932
933        self.assertEqual(f'{3:}', '3')
934        self.assertEqual(f'{3!s:}', '3')
935
936    def test_global(self):
937        self.assertEqual(f'g:{a_global}', 'g:global variable')
938        self.assertEqual(f'g:{a_global!r}', "g:'global variable'")
939
940        a_local = 'local variable'
941        self.assertEqual(f'g:{a_global} l:{a_local}',
942                         'g:global variable l:local variable')
943        self.assertEqual(f'g:{a_global!r}',
944                         "g:'global variable'")
945        self.assertEqual(f'g:{a_global} l:{a_local!r}',
946                         "g:global variable l:'local variable'")
947
948        self.assertIn("module 'unittest' from", f'{unittest}')
949
950    def test_shadowed_global(self):
951        a_global = 'really a local'
952        self.assertEqual(f'g:{a_global}', 'g:really a local')
953        self.assertEqual(f'g:{a_global!r}', "g:'really a local'")
954
955        a_local = 'local variable'
956        self.assertEqual(f'g:{a_global} l:{a_local}',
957                         'g:really a local l:local variable')
958        self.assertEqual(f'g:{a_global!r}',
959                         "g:'really a local'")
960        self.assertEqual(f'g:{a_global} l:{a_local!r}',
961                         "g:really a local l:'local variable'")
962
963    def test_call(self):
964        def foo(x):
965            return 'x=' + str(x)
966
967        self.assertEqual(f'{foo(10)}', 'x=10')
968
969    def test_nested_fstrings(self):
970        y = 5
971        self.assertEqual(f'{f"{0}"*3}', '000')
972        self.assertEqual(f'{f"{y}"*3}', '555')
973
974    def test_invalid_string_prefixes(self):
975        single_quote_cases = ["fu''",
976                             "uf''",
977                             "Fu''",
978                             "fU''",
979                             "Uf''",
980                             "uF''",
981                             "ufr''",
982                             "urf''",
983                             "fur''",
984                             "fru''",
985                             "rfu''",
986                             "ruf''",
987                             "FUR''",
988                             "Fur''",
989                             "fb''",
990                             "fB''",
991                             "Fb''",
992                             "FB''",
993                             "bf''",
994                             "bF''",
995                             "Bf''",
996                             "BF''",]
997        double_quote_cases = [case.replace("'", '"') for case in single_quote_cases]
998        self.assertAllRaise(SyntaxError, 'invalid syntax',
999                            single_quote_cases + double_quote_cases)
1000
1001    def test_leading_trailing_spaces(self):
1002        self.assertEqual(f'{ 3}', '3')
1003        self.assertEqual(f'{  3}', '3')
1004        self.assertEqual(f'{3 }', '3')
1005        self.assertEqual(f'{3  }', '3')
1006
1007        self.assertEqual(f'expr={ {x: y for x, y in [(1, 2), ]}}',
1008                         'expr={1: 2}')
1009        self.assertEqual(f'expr={ {x: y for x, y in [(1, 2), ]} }',
1010                         'expr={1: 2}')
1011
1012    def test_not_equal(self):
1013        # There's a special test for this because there's a special
1014        #  case in the f-string parser to look for != as not ending an
1015        #  expression. Normally it would, while looking for !s or !r.
1016
1017        self.assertEqual(f'{3!=4}', 'True')
1018        self.assertEqual(f'{3!=4:}', 'True')
1019        self.assertEqual(f'{3!=4!s}', 'True')
1020        self.assertEqual(f'{3!=4!s:.3}', 'Tru')
1021
1022    def test_equal_equal(self):
1023        # Because an expression ending in = has special meaning,
1024        # there's a special test for ==. Make sure it works.
1025
1026        self.assertEqual(f'{0==1}', 'False')
1027
1028    def test_conversions(self):
1029        self.assertEqual(f'{3.14:10.10}', '      3.14')
1030        self.assertEqual(f'{3.14!s:10.10}', '3.14      ')
1031        self.assertEqual(f'{3.14!r:10.10}', '3.14      ')
1032        self.assertEqual(f'{3.14!a:10.10}', '3.14      ')
1033
1034        self.assertEqual(f'{"a"}', 'a')
1035        self.assertEqual(f'{"a"!r}', "'a'")
1036        self.assertEqual(f'{"a"!a}', "'a'")
1037
1038        # Not a conversion.
1039        self.assertEqual(f'{"a!r"}', "a!r")
1040
1041        # Not a conversion, but show that ! is allowed in a format spec.
1042        self.assertEqual(f'{3.14:!<10.10}', '3.14!!!!!!')
1043
1044        self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character',
1045                            ["f'{3!g}'",
1046                             "f'{3!A}'",
1047                             "f'{3!3}'",
1048                             "f'{3!G}'",
1049                             "f'{3!!}'",
1050                             "f'{3!:}'",
1051                             "f'{3! s}'",  # no space before conversion char
1052                             ])
1053
1054        self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
1055                            ["f'{x!s{y}}'",
1056                             "f'{3!ss}'",
1057                             "f'{3!ss:}'",
1058                             "f'{3!ss:s}'",
1059                             ])
1060
1061    def test_assignment(self):
1062        self.assertAllRaise(SyntaxError, r'invalid syntax',
1063                            ["f'' = 3",
1064                             "f'{0}' = x",
1065                             "f'{x}' = x",
1066                             ])
1067
1068    def test_del(self):
1069        self.assertAllRaise(SyntaxError, 'invalid syntax',
1070                            ["del f''",
1071                             "del '' f''",
1072                             ])
1073
1074    def test_mismatched_braces(self):
1075        self.assertAllRaise(SyntaxError, "f-string: single '}' is not allowed",
1076                            ["f'{{}'",
1077                             "f'{{}}}'",
1078                             "f'}'",
1079                             "f'x}'",
1080                             "f'x}x'",
1081                             r"f'\u007b}'",
1082
1083                             # Can't have { or } in a format spec.
1084                             "f'{3:}>10}'",
1085                             "f'{3:}}>10}'",
1086                             ])
1087
1088        self.assertAllRaise(SyntaxError, "f-string: expecting '}'",
1089                            ["f'{3:{{>10}'",
1090                             "f'{3'",
1091                             "f'{3!'",
1092                             "f'{3:'",
1093                             "f'{3!s'",
1094                             "f'{3!s:'",
1095                             "f'{3!s:3'",
1096                             "f'x{'",
1097                             "f'x{x'",
1098                             "f'{x'",
1099                             "f'{3:s'",
1100                             "f'{{{'",
1101                             "f'{{}}{'",
1102                             "f'{'",
1103                             "f'x{<'",  # See bpo-46762.
1104                             "f'x{>'",
1105                             "f'{i='",  # See gh-93418.
1106                             ])
1107
1108        # But these are just normal strings.
1109        self.assertEqual(f'{"{"}', '{')
1110        self.assertEqual(f'{"}"}', '}')
1111        self.assertEqual(f'{3:{"}"}>10}', '}}}}}}}}}3')
1112        self.assertEqual(f'{2:{"{"}>10}', '{{{{{{{{{2')
1113
1114    def test_if_conditional(self):
1115        # There's special logic in compile.c to test if the
1116        #  conditional for an if (and while) are constants. Exercise
1117        #  that code.
1118
1119        def test_fstring(x, expected):
1120            flag = 0
1121            if f'{x}':
1122                flag = 1
1123            else:
1124                flag = 2
1125            self.assertEqual(flag, expected)
1126
1127        def test_concat_empty(x, expected):
1128            flag = 0
1129            if '' f'{x}':
1130                flag = 1
1131            else:
1132                flag = 2
1133            self.assertEqual(flag, expected)
1134
1135        def test_concat_non_empty(x, expected):
1136            flag = 0
1137            if ' ' f'{x}':
1138                flag = 1
1139            else:
1140                flag = 2
1141            self.assertEqual(flag, expected)
1142
1143        test_fstring('', 2)
1144        test_fstring(' ', 1)
1145
1146        test_concat_empty('', 2)
1147        test_concat_empty(' ', 1)
1148
1149        test_concat_non_empty('', 1)
1150        test_concat_non_empty(' ', 1)
1151
1152    def test_empty_format_specifier(self):
1153        x = 'test'
1154        self.assertEqual(f'{x}', 'test')
1155        self.assertEqual(f'{x:}', 'test')
1156        self.assertEqual(f'{x!s:}', 'test')
1157        self.assertEqual(f'{x!r:}', "'test'")
1158
1159    def test_str_format_differences(self):
1160        d = {'a': 'string',
1161             0: 'integer',
1162             }
1163        a = 0
1164        self.assertEqual(f'{d[0]}', 'integer')
1165        self.assertEqual(f'{d["a"]}', 'string')
1166        self.assertEqual(f'{d[a]}', 'integer')
1167        self.assertEqual('{d[a]}'.format(d=d), 'string')
1168        self.assertEqual('{d[0]}'.format(d=d), 'integer')
1169
1170    def test_errors(self):
1171        # see issue 26287
1172        self.assertAllRaise(TypeError, 'unsupported',
1173                            [r"f'{(lambda: 0):x}'",
1174                             r"f'{(0,):x}'",
1175                             ])
1176        self.assertAllRaise(ValueError, 'Unknown format code',
1177                            [r"f'{1000:j}'",
1178                             r"f'{1000:j}'",
1179                            ])
1180
1181    def test_filename_in_syntaxerror(self):
1182        # see issue 38964
1183        with temp_cwd() as cwd:
1184            file_path = os.path.join(cwd, 't.py')
1185            with open(file_path, 'w', encoding="utf-8") as f:
1186                f.write('f"{a b}"') # This generates a SyntaxError
1187            _, _, stderr = assert_python_failure(file_path,
1188                                                 PYTHONIOENCODING='ascii')
1189        self.assertIn(file_path.encode('ascii', 'backslashreplace'), stderr)
1190
1191    def test_loop(self):
1192        for i in range(1000):
1193            self.assertEqual(f'i:{i}', 'i:' + str(i))
1194
1195    def test_dict(self):
1196        d = {'"': 'dquote',
1197             "'": 'squote',
1198             'foo': 'bar',
1199             }
1200        self.assertEqual(f'''{d["'"]}''', 'squote')
1201        self.assertEqual(f"""{d['"']}""", 'dquote')
1202
1203        self.assertEqual(f'{d["foo"]}', 'bar')
1204        self.assertEqual(f"{d['foo']}", 'bar')
1205
1206    def test_backslash_char(self):
1207        # Check eval of a backslash followed by a control char.
1208        # See bpo-30682: this used to raise an assert in pydebug mode.
1209        self.assertEqual(eval('f"\\\n"'), '')
1210        self.assertEqual(eval('f"\\\r"'), '')
1211
1212    def test_debug_conversion(self):
1213        x = 'A string'
1214        self.assertEqual(f'{x=}', 'x=' + repr(x))
1215        self.assertEqual(f'{x =}', 'x =' + repr(x))
1216        self.assertEqual(f'{x=!s}', 'x=' + str(x))
1217        self.assertEqual(f'{x=!r}', 'x=' + repr(x))
1218        self.assertEqual(f'{x=!a}', 'x=' + ascii(x))
1219
1220        x = 2.71828
1221        self.assertEqual(f'{x=:.2f}', 'x=' + format(x, '.2f'))
1222        self.assertEqual(f'{x=:}', 'x=' + format(x, ''))
1223        self.assertEqual(f'{x=!r:^20}', 'x=' + format(repr(x), '^20'))
1224        self.assertEqual(f'{x=!s:^20}', 'x=' + format(str(x), '^20'))
1225        self.assertEqual(f'{x=!a:^20}', 'x=' + format(ascii(x), '^20'))
1226
1227        x = 9
1228        self.assertEqual(f'{3*x+15=}', '3*x+15=42')
1229
1230        # There is code in ast.c that deals with non-ascii expression values.  So,
1231        # use a unicode identifier to trigger that.
1232        tenπ = 31.4
1233        self.assertEqual(f'{tenπ=:.2f}', 'tenπ=31.40')
1234
1235        # Also test with Unicode in non-identifiers.
1236        self.assertEqual(f'{"Σ"=}', '"Σ"=\'Σ\'')
1237
1238        # Make sure nested fstrings still work.
1239        self.assertEqual(f'{f"{3.1415=:.1f}":*^20}', '*****3.1415=3.1*****')
1240
1241        # Make sure text before and after an expression with = works
1242        # correctly.
1243        pi = 'π'
1244        self.assertEqual(f'alpha α {pi=} ω omega', "alpha α pi='π' ω omega")
1245
1246        # Check multi-line expressions.
1247        self.assertEqual(f'''{
12483
1249=}''', '\n3\n=3')
1250
1251        # Since = is handled specially, make sure all existing uses of
1252        # it still work.
1253
1254        self.assertEqual(f'{0==1}', 'False')
1255        self.assertEqual(f'{0!=1}', 'True')
1256        self.assertEqual(f'{0<=1}', 'True')
1257        self.assertEqual(f'{0>=1}', 'False')
1258        self.assertEqual(f'{(x:="5")}', '5')
1259        self.assertEqual(x, '5')
1260        self.assertEqual(f'{(x:=5)}', '5')
1261        self.assertEqual(x, 5)
1262        self.assertEqual(f'{"="}', '=')
1263
1264        x = 20
1265        # This isn't an assignment expression, it's 'x', with a format
1266        # spec of '=10'.  See test_walrus: you need to use parens.
1267        self.assertEqual(f'{x:=10}', '        20')
1268
1269        # Test named function parameters, to make sure '=' parsing works
1270        # there.
1271        def f(a):
1272            nonlocal x
1273            oldx = x
1274            x = a
1275            return oldx
1276        x = 0
1277        self.assertEqual(f'{f(a="3=")}', '0')
1278        self.assertEqual(x, '3=')
1279        self.assertEqual(f'{f(a=4)}', '3=')
1280        self.assertEqual(x, 4)
1281
1282        # Make sure __format__ is being called.
1283        class C:
1284            def __format__(self, s):
1285                return f'FORMAT-{s}'
1286            def __repr__(self):
1287                return 'REPR'
1288
1289        self.assertEqual(f'{C()=}', 'C()=REPR')
1290        self.assertEqual(f'{C()=!r}', 'C()=REPR')
1291        self.assertEqual(f'{C()=:}', 'C()=FORMAT-')
1292        self.assertEqual(f'{C()=: }', 'C()=FORMAT- ')
1293        self.assertEqual(f'{C()=:x}', 'C()=FORMAT-x')
1294        self.assertEqual(f'{C()=!r:*^20}', 'C()=********REPR********')
1295
1296        self.assertRaises(SyntaxError, eval, "f'{C=]'")
1297
1298        # Make sure leading and following text works.
1299        x = 'foo'
1300        self.assertEqual(f'X{x=}Y', 'Xx='+repr(x)+'Y')
1301
1302        # Make sure whitespace around the = works.
1303        self.assertEqual(f'X{x  =}Y', 'Xx  ='+repr(x)+'Y')
1304        self.assertEqual(f'X{x=  }Y', 'Xx=  '+repr(x)+'Y')
1305        self.assertEqual(f'X{x  =  }Y', 'Xx  =  '+repr(x)+'Y')
1306
1307        # These next lines contains tabs.  Backslash escapes don't
1308        # work in f-strings.
1309        # patchcheck doesn't like these tabs.  So the only way to test
1310        # this will be to dynamically created and exec the f-strings.  But
1311        # that's such a hassle I'll save it for another day.  For now, convert
1312        # the tabs to spaces just to shut up patchcheck.
1313        #self.assertEqual(f'X{x =}Y', 'Xx\t='+repr(x)+'Y')
1314        #self.assertEqual(f'X{x =       }Y', 'Xx\t=\t'+repr(x)+'Y')
1315
1316    def test_walrus(self):
1317        x = 20
1318        # This isn't an assignment expression, it's 'x', with a format
1319        # spec of '=10'.
1320        self.assertEqual(f'{x:=10}', '        20')
1321
1322        # This is an assignment expression, which requires parens.
1323        self.assertEqual(f'{(x:=10)}', '10')
1324        self.assertEqual(x, 10)
1325
1326    def test_invalid_syntax_error_message(self):
1327        with self.assertRaisesRegex(SyntaxError, "f-string: invalid syntax"):
1328            compile("f'{a $ b}'", "?", "exec")
1329
1330    def test_with_two_commas_in_format_specifier(self):
1331        error_msg = re.escape("Cannot specify ',' with ','.")
1332        with self.assertRaisesRegex(ValueError, error_msg):
1333            f'{1:,,}'
1334
1335    def test_with_two_underscore_in_format_specifier(self):
1336        error_msg = re.escape("Cannot specify '_' with '_'.")
1337        with self.assertRaisesRegex(ValueError, error_msg):
1338            f'{1:__}'
1339
1340    def test_with_a_commas_and_an_underscore_in_format_specifier(self):
1341        error_msg = re.escape("Cannot specify both ',' and '_'.")
1342        with self.assertRaisesRegex(ValueError, error_msg):
1343            f'{1:,_}'
1344
1345    def test_with_an_underscore_and_a_comma_in_format_specifier(self):
1346        error_msg = re.escape("Cannot specify both ',' and '_'.")
1347        with self.assertRaisesRegex(ValueError, error_msg):
1348            f'{1:_,}'
1349
1350    def test_syntax_error_for_starred_expressions(self):
1351        error_msg = re.escape("cannot use starred expression here")
1352        with self.assertRaisesRegex(SyntaxError, error_msg):
1353            compile("f'{*a}'", "?", "exec")
1354
1355        error_msg = re.escape("cannot use double starred expression here")
1356        with self.assertRaisesRegex(SyntaxError, error_msg):
1357            compile("f'{**a}'", "?", "exec")
1358
1359if __name__ == '__main__':
1360    unittest.main()
1361