From 1796a647affe4f6b060f320f34f3bac74049bd78 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 2 May 2023 00:01:16 +0100 Subject: [PATCH] gh-104016: Skip test for deeply neste f-strings on wasi --- Lib/test/test_fstring.py | 122 ++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/Lib/test/test_fstring.py b/Lib/test/test_fstring.py index 5c5176dc54a6d9e..744e4d1d0953fd6 100644 --- a/Lib/test/test_fstring.py +++ b/Lib/test/test_fstring.py @@ -26,6 +26,7 @@ # worthwhile tradeoff. When I switched to this method, I found many # examples where I wasn't testing what I thought I was. + class TestCase(unittest.TestCase): def assertAllRaise(self, exception_type, regex, error_strings): for str in error_strings: @@ -65,6 +66,7 @@ def test_ast(self): class X: def __init__(self): self.called = False + def __call__(self): self.called = True return 4 @@ -499,9 +501,10 @@ def test_docstring(self): def f(): f'''Not a docstring''' self.assertIsNone(f.__doc__) + def g(): '''Not a docstring''' \ - f'' + f'' self.assertIsNone(g.__doc__) def test_literal_eval(self): @@ -546,26 +549,27 @@ def test_mismatched_parens(self): self.assertAllRaise(SyntaxError, r"closing parenthesis '\)' " r"does not match opening parenthesis '\['", ["f'{a[4)}'", - ]) + ]) self.assertAllRaise(SyntaxError, r"closing parenthesis '\]' " r"does not match opening parenthesis '\('", ["f'{a(4]}'", - ]) + ]) self.assertAllRaise(SyntaxError, r"closing parenthesis '\}' " r"does not match opening parenthesis '\['", ["f'{a[4}'", - ]) + ]) self.assertAllRaise(SyntaxError, r"closing parenthesis '\}' " r"does not match opening parenthesis '\('", ["f'{a(4}'", - ]) + ]) self.assertRaises(SyntaxError, eval, "f'{" + "("*500 + "}'") + @unittest.skipIf(support.is_wasi, "exhausts limited stack on WASI") def test_fstring_nested_too_deeply(self): self.assertAllRaise(SyntaxError, "f-string: expressions nested too deeply", ['f"{1+2:{1+2:{1+1:{1}}}}"']) - + def create_nested_fstring(n): if n == 0: return "1+1" @@ -575,13 +579,13 @@ def create_nested_fstring(n): self.assertAllRaise(SyntaxError, "too many nested f-strings", [create_nested_fstring(160)]) - + def test_syntax_error_in_nested_fstring(self): # See gh-104016 for more information on this crash self.assertAllRaise(SyntaxError, "invalid syntax", ['f"{1 1:' + ('{f"1:' * 199)]) - + def test_double_braces(self): self.assertEqual(f'{{', '{') self.assertEqual(f'a{{', 'a{') @@ -614,7 +618,7 @@ def test_double_braces(self): self.assertEqual(f'{"{{}}"}', '{{}}') self.assertAllRaise(TypeError, 'unhashable type', - ["f'{ {{}} }'", # dict in a set + ["f'{ {{}} }'", # dict in a set ]) def test_compile_time_concat(self): @@ -699,11 +703,16 @@ def test_format_specifier_expressions(self): width = 10 precision = 4 value = decimal.Decimal('12.34567') - self.assertEqual(f'result: {value:{width}.{precision}}', 'result: 12.35') - self.assertEqual(f'result: {value:{width!r}.{precision}}', 'result: 12.35') - self.assertEqual(f'result: {value:{width:0}.{precision:1}}', 'result: 12.35') - self.assertEqual(f'result: {value:{1}{0:0}.{precision:1}}', 'result: 12.35') - self.assertEqual(f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result: 12.35') + self.assertEqual( + f'result: {value:{width}.{precision}}', 'result: 12.35') + self.assertEqual( + f'result: {value:{width!r}.{precision}}', 'result: 12.35') + self.assertEqual( + f'result: {value:{width:0}.{precision:1}}', 'result: 12.35') + self.assertEqual( + f'result: {value:{1}{0:0}.{precision:1}}', 'result: 12.35') + self.assertEqual( + f'result: {value:{ 1}{ 0:0}.{ precision:1}}', 'result: 12.35') self.assertEqual(f'{10:#{1}0x}', ' 0xa') self.assertEqual(f'{10:{"#"}1{0}{"x"}}', ' 0xa') self.assertEqual(f'{-10:-{"#"}1{0}x}', ' -0xa') @@ -718,20 +727,21 @@ def test_format_specifier_expressions(self): self.assertAllRaise(SyntaxError, "f-string: expecting a valid expression after '{'", - [# Invalid syntax inside a nested spec. - "f'{4:{/5}}'", - ]) + [ # Invalid syntax inside a nested spec. + "f'{4:{/5}}'", + ]) self.assertAllRaise(SyntaxError, 'f-string: invalid conversion character', - [# No expansion inside conversion or for - # the : or ! itself. - """f'{"s"!{"r"}}'""", - ]) + [ # No expansion inside conversion or for + # the : or ! itself. + """f'{"s"!{"r"}}'""", + ]) def test_side_effect_order(self): class X: def __init__(self): self.i = 0 + def __format__(self, spec): self.i += 1 return str(self.i) @@ -815,7 +825,7 @@ def test_parens_in_expressions(self): def test_newlines_before_syntax_error(self): self.assertAllRaise(SyntaxError, "f-string: expecting a valid expression after '{'", - ["f'{.}'", "\nf'{.}'", "\n\nf'{.}'"]) + ["f'{.}'", "\nf'{.}'", "\n\nf'{.}'"]) def test_backslashes_in_string_part(self): self.assertEqual(f'\t', '\t') @@ -893,8 +903,8 @@ def test_misformed_unicode_character_name(self): def test_backslashes_in_expression_part(self): self.assertEqual(f"{( - 1 + - 2 + 1 + + 2 )}", "3") self.assertEqual("\N{LEFT CURLY BRACKET}", '{') @@ -933,7 +943,8 @@ def test_no_escapes_for_braces(self): self.assertEqual(f'\x7b1+1}}', '{1+1}') self.assertEqual(f'\x7b1+1', '{1+1') self.assertEqual(f'\u007b1+1', '{1+1') - self.assertEqual(f'\N{LEFT CURLY BRACKET}1+1\N{RIGHT CURLY BRACKET}', '{1+1}') + self.assertEqual( + f'\N{LEFT CURLY BRACKET}1+1\N{RIGHT CURLY BRACKET}', '{1+1}') def test_newlines_in_expressions(self): self.assertEqual(f'{0}', '0') @@ -1006,7 +1017,8 @@ def test_fstring_backslash_prefix_raw(self): def test_fstring_format_spec_greedy_matching(self): self.assertEqual(f"{1:}}}", "1}") - self.assertEqual(f"{1:>3{5}}}}", " 1}") + self.assertEqual( + f"{1:>3{5}}}}", " 1}") def test_yield(self): # Not terribly useful, but make sure the yield turns @@ -1066,6 +1078,7 @@ def inner(): def test_arguments(self): y = 2 + def f(x, width): return f'x={x*y:{width}}' @@ -1135,28 +1148,29 @@ def test_nested_fstrings(self): def test_invalid_string_prefixes(self): single_quote_cases = ["fu''", - "uf''", - "Fu''", - "fU''", - "Uf''", - "uF''", - "ufr''", - "urf''", - "fur''", - "fru''", - "rfu''", - "ruf''", - "FUR''", - "Fur''", - "fb''", - "fB''", - "Fb''", - "FB''", - "bf''", - "bF''", - "Bf''", - "BF''",] - double_quote_cases = [case.replace("'", '"') for case in single_quote_cases] + "uf''", + "Fu''", + "fU''", + "Uf''", + "uF''", + "ufr''", + "urf''", + "fur''", + "fru''", + "rfu''", + "ruf''", + "FUR''", + "Fur''", + "fb''", + "fB''", + "Fb''", + "FB''", + "bf''", + "bF''", + "Bf''", + "BF''",] + double_quote_cases = [case.replace("'", '"') + for case in single_quote_cases] self.assertAllRaise(SyntaxError, 'invalid syntax', single_quote_cases + double_quote_cases) @@ -1365,14 +1379,14 @@ def test_errors(self): self.assertAllRaise(ValueError, 'Unknown format code', [r"f'{1000:j}'", r"f'{1000:j}'", - ]) + ]) def test_filename_in_syntaxerror(self): # see issue 38964 with temp_cwd() as cwd: file_path = os.path.join(cwd, 't.py') with open(file_path, 'w', encoding="utf-8") as f: - f.write('f"{a b}"') # This generates a SyntaxError + f.write('f"{a b}"') # This generates a SyntaxError _, _, stderr = assert_python_failure(file_path, PYTHONIOENCODING='ascii') self.assertIn(file_path.encode('ascii', 'backslashreplace'), stderr) @@ -1472,6 +1486,7 @@ def f(a): class C: def __format__(self, s): return f'FORMAT-{s}' + def __repr__(self): return 'REPR' @@ -1492,7 +1507,8 @@ def __repr__(self): self.assertEqual(f'X{x =}Y', 'Xx ='+repr(x)+'Y') self.assertEqual(f'X{x= }Y', 'Xx= '+repr(x)+'Y') self.assertEqual(f'X{x = }Y', 'Xx = '+repr(x)+'Y') - self.assertEqual(f"sadsd {1 + 1 = :{1 + 1:1d}f}", "sadsd 1 + 1 = 2.000000") + self.assertEqual( + f"sadsd {1 + 1 = :{1 + 1:1d}f}", "sadsd 1 + 1 = 2.000000") # These next lines contains tabs. Backslash escapes don't # work in f-strings. @@ -1547,7 +1563,8 @@ def test_syntax_error_for_starred_expressions(self): compile("f'{**a}'", "?", "exec") def test_not_closing_quotes(self): - self.assertAllRaise(SyntaxError, "unterminated f-string literal", ['f"', "f'"]) + self.assertAllRaise( + SyntaxError, "unterminated f-string literal", ['f"', "f'"]) self.assertAllRaise(SyntaxError, "unterminated triple-quoted f-string literal", ['f"""', "f'''"]) @@ -1565,5 +1582,6 @@ def test_syntax_error_after_debug(self): "f'{1=}{1;}'", ]) + if __name__ == '__main__': unittest.main()