Skip to content

Commit

Permalink
Fix behavior of tag'\N{BLAH}'
Browse files Browse the repository at this point in the history
This should treat `{BLAH}` as an interpolation.
To fix this we modify `_PyPegen_joined_str()` to take an `is_raw` flag.
  • Loading branch information
gvanrossum committed Apr 26, 2023
1 parent c1c75ea commit f93052d
Show file tree
Hide file tree
Showing 5 changed files with 19 additions and 6 deletions.
2 changes: 1 addition & 1 deletion Grammar/python.gram
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ fstring_format_spec[expr_ty]:
| t=FSTRING_MIDDLE { _PyPegen_constant_from_token(p, t) }
| fstring_replacement_field
fstring[expr_ty]:
| a=FSTRING_START b=fstring_middle* c=FSTRING_END { _PyPegen_joined_str(p, a, (asdl_expr_seq*)b, c) }
| a=FSTRING_START b=fstring_middle* c=FSTRING_END { _PyPegen_joined_str(p, 0, a, (asdl_expr_seq*)b, c) }
tagstring[expr_ty] (memo):
| a=TAGSTRING_START b=fstring_middle* c=FSTRING_END { _PyPegen_tag_str(p, a, (asdl_expr_seq*)b, c) }

Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_tag_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,19 @@ def tag(*args):
self.assertEqual(conv, "r")
self.assertEqual(spec, None)

def test_unicode_names(self):
def tag(*args):
return args
res = tag"\N{SPACE}"
self.assertEqual(len(res), 2)
self.assertEqual(res[0], r"\N")
func, string, conv, spec = res[1]
SPACE = 42
self.assertEqual(func(), 42)
self.assertEqual(string, "SPACE")
self.assertEqual(conv, None)
self.assertEqual(spec, None)


if __name__ == "__main__":
unittest.main()
6 changes: 3 additions & 3 deletions Parser/action_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1290,15 +1290,15 @@ unpack_top_level_joined_strs(Parser *p, asdl_expr_seq *raw_expressions)
}

expr_ty
_PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
_PyPegen_joined_str(Parser *p, int is_raw, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
asdl_expr_seq *expr = unpack_top_level_joined_strs(p, raw_expressions);
Py_ssize_t n_items = asdl_seq_LEN(expr);

const char* quote_str = PyBytes_AsString(a->bytes);
if (quote_str == NULL) {
return NULL;
}
int is_raw = strpbrk(quote_str, "rR") != NULL;
is_raw = is_raw || strpbrk(quote_str, "rR") != NULL;

asdl_expr_seq *seq = _Py_asdl_expr_seq_new(n_items, p->arena);
if (seq == NULL) {
Expand Down Expand Up @@ -1393,7 +1393,7 @@ _PyPegen_tag_str(Parser *p, Token* a, asdl_expr_seq* raw_expressions, Token*b) {
if (tag == NULL) {
return NULL;
}
expr_ty str = _PyPegen_joined_str(p, a, raw_expressions, b);
expr_ty str = _PyPegen_joined_str(p, 1, a, raw_expressions, b);
if (str == NULL) {
return NULL;
}
Expand Down
2 changes: 1 addition & 1 deletion Parser/parser.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Parser/pegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ mod_ty _PyPegen_run_parser_from_string(const char *, int, PyObject *, PyCompiler
asdl_stmt_seq *_PyPegen_interactive_exit(Parser *);

// TODO: move to the correct place in this file
expr_ty _PyPegen_joined_str(Parser *p, Token* a, asdl_expr_seq* expr, Token*b);
expr_ty _PyPegen_joined_str(Parser *p, int is_raw, Token* a, asdl_expr_seq* expr, Token*b);
expr_ty _PyPegen_tag_str(Parser *p, Token* a, asdl_expr_seq* expr, Token*b);

// Generated function in parse.c - function definition in python.gram
Expand Down

0 comments on commit f93052d

Please sign in to comment.