Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 11c1dee

Browse files
committed
Issue #14697: Fix missing parser module support for set displays and set comprehensions.
1 parent cf360b9 commit 11c1dee

3 files changed

Lines changed: 105 additions & 21 deletions

File tree

Lib/test/test_parser.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,29 @@ def test_raise_statement(self):
305305
"except Exception as e:\n"
306306
" raise ValueError from e\n")
307307

308+
def test_set_displays(self):
309+
self.check_expr('{2}')
310+
self.check_expr('{2,}')
311+
self.check_expr('{2, 3}')
312+
self.check_expr('{2, 3,}')
313+
314+
def test_dict_displays(self):
315+
self.check_expr('{}')
316+
self.check_expr('{a:b}')
317+
self.check_expr('{a:b,}')
318+
self.check_expr('{a:b, c:d}')
319+
self.check_expr('{a:b, c:d,}')
320+
321+
def test_set_comprehensions(self):
322+
self.check_expr('{x for x in seq}')
323+
self.check_expr('{f(x) for x in seq}')
324+
self.check_expr('{f(x) for x in seq if condition(x)}')
325+
326+
def test_dict_comprehensions(self):
327+
self.check_expr('{x:x for x in seq}')
328+
self.check_expr('{x**2:x[3] for x in seq if condition(x)}')
329+
self.check_expr('{x:x for x in seq1 for y in seq2 if condition(x, y)}')
330+
308331

309332
#
310333
# Second, we take *invalid* trees and make sure we get ParserError

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ Core and Builtins
6161
Library
6262
-------
6363

64+
- Issue #14697: Fix missing support for set displays and set comprehensions in
65+
parser module.
66+
6467
- Issue #14701: Fix missing support for 'raise ... from' in parser module.
6568

6669
- Issue #13183: Fix pdb skipping frames after hitting a breakpoint and running

Modules/parsermodule.c

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2865,34 +2865,92 @@ validate_exprlist(node *tree)
28652865
validate_expr_or_star_expr, "exprlist"));
28662866
}
28672867

2868-
2868+
/*
2869+
* dictorsetmaker:
2870+
*
2871+
* (test ':' test (comp_for | (',' test ':' test)* [','])) |
2872+
* (test (comp_for | (',' test)* [',']))
2873+
*/
28692874
static int
28702875
validate_dictorsetmaker(node *tree)
28712876
{
28722877
int nch = NCH(tree);
2873-
int res = (validate_ntype(tree, dictorsetmaker)
2874-
&& (nch >= 3)
2875-
&& validate_test(CHILD(tree, 0))
2876-
&& validate_colon(CHILD(tree, 1))
2877-
&& validate_test(CHILD(tree, 2)));
2878+
int res;
2879+
int i = 0;
2880+
2881+
res = validate_ntype(tree, dictorsetmaker);
2882+
if (!res)
2883+
return 0;
28782884

2879-
if (res && ((nch % 4) == 0))
2880-
res = validate_comma(CHILD(tree, --nch));
2881-
else if (res)
2882-
res = ((nch % 4) == 3);
2883-
2884-
if (res && (nch > 3)) {
2885-
int pos = 3;
2886-
/* ( ',' test ':' test )* */
2887-
while (res && (pos < nch)) {
2888-
res = (validate_comma(CHILD(tree, pos))
2889-
&& validate_test(CHILD(tree, pos + 1))
2890-
&& validate_colon(CHILD(tree, pos + 2))
2891-
&& validate_test(CHILD(tree, pos + 3)));
2892-
pos += 4;
2885+
if (nch - i < 1) {
2886+
(void) validate_numnodes(tree, 1, "dictorsetmaker");
2887+
return 0;
2888+
}
2889+
2890+
res = validate_test(CHILD(tree, i++));
2891+
if (!res)
2892+
return 0;
2893+
2894+
if (nch - i >= 2 && TYPE(CHILD(tree, i)) == COLON) {
2895+
/* Dictionary display or dictionary comprehension. */
2896+
res = (validate_colon(CHILD(tree, i++))
2897+
&& validate_test(CHILD(tree, i++)));
2898+
if (!res)
2899+
return 0;
2900+
2901+
if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) {
2902+
/* Dictionary comprehension. */
2903+
res = validate_comp_for(CHILD(tree, i++));
2904+
if (!res)
2905+
return 0;
2906+
}
2907+
else {
2908+
/* Dictionary display. */
2909+
while (nch - i >= 4) {
2910+
res = (validate_comma(CHILD(tree, i++))
2911+
&& validate_test(CHILD(tree, i++))
2912+
&& validate_colon(CHILD(tree, i++))
2913+
&& validate_test(CHILD(tree, i++)));
2914+
if (!res)
2915+
return 0;
2916+
}
2917+
if (nch - i == 1) {
2918+
res = validate_comma(CHILD(tree, i++));
2919+
if (!res)
2920+
return 0;
2921+
}
28932922
}
28942923
}
2895-
return (res);
2924+
else {
2925+
/* Set display or set comprehension. */
2926+
if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) {
2927+
/* Set comprehension. */
2928+
res = validate_comp_for(CHILD(tree, i++));
2929+
if (!res)
2930+
return 0;
2931+
}
2932+
else {
2933+
/* Set display. */
2934+
while (nch - i >= 2) {
2935+
res = (validate_comma(CHILD(tree, i++))
2936+
&& validate_test(CHILD(tree, i++)));
2937+
if (!res)
2938+
return 0;
2939+
}
2940+
if (nch - i == 1) {
2941+
res = validate_comma(CHILD(tree, i++));
2942+
if (!res)
2943+
return 0;
2944+
}
2945+
}
2946+
}
2947+
2948+
if (nch - i > 0) {
2949+
err_string("Illegal trailing nodes for dictorsetmaker.");
2950+
return 0;
2951+
}
2952+
2953+
return 1;
28962954
}
28972955

28982956

0 commit comments

Comments
 (0)