# Test multiple format specs in same raw f-string
self.assertEqual(rf"{UnchangedFormat():\xFF} {UnchangedFormat():\n}", '\\xFF \\n')
+ def test_gh139516(self):
+ with temp_cwd():
+ script = 'script.py'
+ with open(script, 'wb') as f:
+ f.write('''def f(a): pass\nf"{f(a=lambda: 'à'\n)}"'''.encode())
+ assert_python_ok(script)
+
if __name__ == '__main__':
unittest.main()
FSTRING_END "\'\'\'" (3, 1) (3, 4)
""")
+ # gh-139516, the '\n' is explicit to ensure no trailing whitespace which would invalidate the test
+ self.check_tokenize('''f"{f(a=lambda: 'à'\n)}"''', """\
+ FSTRING_START \'f"\' (1, 0) (1, 2)
+ OP '{' (1, 2) (1, 3)
+ NAME 'f' (1, 3) (1, 4)
+ OP '(' (1, 4) (1, 5)
+ NAME 'a' (1, 5) (1, 6)
+ OP '=' (1, 6) (1, 7)
+ NAME 'lambda' (1, 7) (1, 13)
+ OP ':' (1, 13) (1, 14)
+ STRING "\'à\'" (1, 15) (1, 18)
+ NL '\\n' (1, 18) (1, 19)
+ OP ')' (2, 0) (2, 1)
+ OP '}' (2, 1) (2, 2)
+ FSTRING_END \'"\' (2, 2) (2, 3)
+ """)
+
class GenerateTokensTest(TokenizeTest):
def check_tokenize(self, s, expected):
# Format the tokens in s in a table format.
return MAKE_TOKEN(_PyTokenizer_syntaxerror(tok, "invalid non-printable character U+%04X", c));
}
- if( c == '=' && INSIDE_FSTRING_EXPR(current_tok)) {
+ if( c == '=' && INSIDE_FSTRING_EXPR_AT_TOP(current_tok)) {
current_tok->in_debug = 1;
}
#define INSIDE_FSTRING(tok) (tok->tok_mode_stack_index > 0)
#define INSIDE_FSTRING_EXPR(tok) (tok->curly_bracket_expr_start_depth >= 0)
+#define INSIDE_FSTRING_EXPR_AT_TOP(tok) \
+ (tok->curly_bracket_depth - tok->curly_bracket_expr_start_depth == 1)
enum decoding_state {
STATE_INIT,