Skip to content

Commit 4790764

Browse files
authored
Merge pull request #63 from sunmy2019/fix-empty-string-concatenation
2 parents 270b661 + d8b12e2 commit 4790764

File tree

1 file changed

+69
-36
lines changed

1 file changed

+69
-36
lines changed

Parser/action_helpers.c

Lines changed: 69 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1373,9 +1373,16 @@ expr_ty _PyPegen_constant_from_string(Parser* p, Token* tok) {
13731373
_Pypegen_raise_decode_error(p);
13741374
return NULL;
13751375
}
1376+
if (_PyArena_AddPyObject(p->arena, s) < 0) {
1377+
Py_DECREF(s);
1378+
return NULL;
1379+
}
13761380
PyObject *kind = NULL;
13771381
if (the_str && the_str[0] == 'u') {
13781382
kind = _PyPegen_new_identifier(p, "u");
1383+
if (kind == NULL) {
1384+
return NULL;
1385+
}
13791386
}
13801387
return _PyAST_Constant(s, kind, tok->lineno, tok->col_offset, tok->end_lineno, tok->end_col_offset, p->arena);
13811388
}
@@ -1488,7 +1495,8 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
14881495
expr_ty elem = asdl_seq_GET(strings, i);
14891496
PyBytes_Concat(&res, elem->v.Constant.value);
14901497
}
1491-
if (_PyArena_AddPyObject(arena, res) < 0) {
1498+
if (!res || _PyArena_AddPyObject(arena, res) < 0) {
1499+
Py_XDECREF(res);
14921500
return NULL;
14931501
}
14941502
return _PyAST_Constant(res, kind, lineno, col_offset, end_lineno, end_col_offset, p->arena);
@@ -1511,7 +1519,7 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
15111519
if (elem->kind == Constant_kind) {
15121520
asdl_seq_SET(flattened, current_pos++, elem);
15131521
} else {
1514-
for (j=0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) {
1522+
for (j = 0; j < asdl_seq_LEN(elem->v.JoinedStr.values); j++) {
15151523
expr_ty subvalue = asdl_seq_GET(elem->v.JoinedStr.values, j);
15161524
if (subvalue == NULL) {
15171525
return NULL;
@@ -1526,6 +1534,15 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
15261534
int prev_is_constant = 0;
15271535
for (i = 0; i < n_flattened_elements; i++) {
15281536
expr_ty elem = asdl_seq_GET(flattened, i);
1537+
1538+
/* The concatenation of a FormattedValue and an empty Contant should
1539+
lead to the FormattedValue itself. Thus, we will not take any empty
1540+
constants into account, just as in `_PyPegen_joined_str` */
1541+
if (f_string_found && elem->kind == Constant_kind &&
1542+
PyUnicode_CheckExact(elem->v.Constant.value) &&
1543+
PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0)
1544+
continue;
1545+
15291546
if (!prev_is_constant || elem->kind != Constant_kind) {
15301547
n_elements++;
15311548
}
@@ -1545,44 +1562,59 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
15451562

15461563
/* if the current elem and the following are constants,
15471564
fold them and all consequent constants */
1548-
if (elem->kind == Constant_kind && i+1 < n_flattened_elements
1549-
&& asdl_seq_GET(flattened, i+1)->kind == Constant_kind) {
1550-
expr_ty first_elem = elem;
1551-
1552-
/* When a string is getting concatenated, the kind of the string
1553-
is determined by the first string in the concatenation sequence.
1554-
1555-
u"abc" "def" -> u"abcdef"
1556-
"abc" u"abc" -> "abcabc" */
1557-
PyObject *kind = elem->v.Constant.kind;
1558-
1559-
_PyUnicodeWriter_Init(&writer);
1560-
expr_ty last_elem = elem;
1561-
for (j = i; j < n_flattened_elements; j++) {
1562-
expr_ty current_elem = asdl_seq_GET(flattened, j);
1563-
if (current_elem->kind == Constant_kind) {
1564-
if (_PyUnicodeWriter_WriteStr(&writer, current_elem->v.Constant.value)) {
1565-
_PyUnicodeWriter_Dealloc(&writer);
1566-
return NULL;
1565+
if (elem->kind == Constant_kind) {
1566+
if (i + 1 < n_flattened_elements &&
1567+
asdl_seq_GET(flattened, i + 1)->kind == Constant_kind) {
1568+
expr_ty first_elem = elem;
1569+
1570+
/* When a string is getting concatenated, the kind of the string
1571+
is determined by the first string in the concatenation
1572+
sequence.
1573+
1574+
u"abc" "def" -> u"abcdef"
1575+
"abc" u"abc" -> "abcabc" */
1576+
PyObject *kind = elem->v.Constant.kind;
1577+
1578+
_PyUnicodeWriter_Init(&writer);
1579+
expr_ty last_elem = elem;
1580+
for (j = i; j < n_flattened_elements; j++) {
1581+
expr_ty current_elem = asdl_seq_GET(flattened, j);
1582+
if (current_elem->kind == Constant_kind) {
1583+
if (_PyUnicodeWriter_WriteStr(
1584+
&writer, current_elem->v.Constant.value)) {
1585+
_PyUnicodeWriter_Dealloc(&writer);
1586+
return NULL;
1587+
}
1588+
last_elem = current_elem;
1589+
} else {
1590+
break;
15671591
}
1568-
last_elem = current_elem;
1569-
} else {
1570-
break;
15711592
}
1572-
}
1573-
i = j-1;
1593+
i = j - 1;
15741594

1575-
PyObject *concat_str = _PyUnicodeWriter_Finish(&writer);
1576-
if (concat_str == NULL) {
1577-
_PyUnicodeWriter_Dealloc(&writer);
1578-
return NULL;
1595+
PyObject *concat_str = _PyUnicodeWriter_Finish(&writer);
1596+
if (concat_str == NULL) {
1597+
_PyUnicodeWriter_Dealloc(&writer);
1598+
return NULL;
1599+
}
1600+
if (_PyArena_AddPyObject(p->arena, concat_str) < 0) {
1601+
Py_DECREF(concat_str);
1602+
return NULL;
1603+
}
1604+
elem = _PyAST_Constant(concat_str, kind, first_elem->lineno,
1605+
first_elem->col_offset,
1606+
last_elem->end_lineno,
1607+
last_elem->end_col_offset, p->arena);
1608+
if (elem == NULL) {
1609+
return NULL;
1610+
}
15791611
}
15801612

1581-
elem = _PyAST_Constant(concat_str, kind, first_elem->lineno, first_elem->col_offset,
1582-
last_elem->end_lineno, last_elem->end_col_offset, p->arena);
1583-
if (elem == NULL) {
1584-
Py_DECREF(concat_str);
1585-
return NULL;
1613+
/* Drop all empty contanst strings */
1614+
if (f_string_found &&
1615+
PyUnicode_CheckExact(elem->v.Constant.value) &&
1616+
PyUnicode_GET_LENGTH(elem->v.Constant.value) == 0) {
1617+
continue;
15861618
}
15871619
}
15881620

@@ -1594,7 +1626,8 @@ _PyPegen_concatenate_strings(Parser *p, asdl_expr_seq *strings,
15941626
expr_ty elem = asdl_seq_GET(values, 0);
15951627
assert(elem->kind == Constant_kind);
15961628
return elem;
1597-
}
1629+
}
15981630

1631+
assert(current_pos == n_elements);
15991632
return _PyAST_JoinedStr(values, lineno, col_offset, end_lineno, end_col_offset, p->arena);
16001633
}

0 commit comments

Comments
 (0)