Skip to content

Commit 72f6095

Browse files
committed
Issue #14697: Merge fix from 3.2.
2 parents 0576f9b + 11c1dee commit 72f6095

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
@@ -309,6 +309,29 @@ def test_raise_statement(self):
309309
"except Exception as e:\n"
310310
" raise ValueError from e\n")
311311

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

313336
#
314337
# 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
@@ -20,6 +20,9 @@ Core and Builtins
2020
Library
2121
-------
2222

23+
- Issue #14697: Fix missing support for set displays and set comprehensions in
24+
parser module.
25+
2326
- Issue #14701: Fix missing support for 'raise ... from' in parser module.
2427

2528
- Add support for timeouts to the acquire() methods of

Modules/parsermodule.c

Lines changed: 79 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2895,34 +2895,92 @@ validate_exprlist(node *tree)
28952895
validate_expr_or_star_expr, "exprlist"));
28962896
}
28972897

2898-
2898+
/*
2899+
* dictorsetmaker:
2900+
*
2901+
* (test ':' test (comp_for | (',' test ':' test)* [','])) |
2902+
* (test (comp_for | (',' test)* [',']))
2903+
*/
28992904
static int
29002905
validate_dictorsetmaker(node *tree)
29012906
{
29022907
int nch = NCH(tree);
2903-
int res = (validate_ntype(tree, dictorsetmaker)
2904-
&& (nch >= 3)
2905-
&& validate_test(CHILD(tree, 0))
2906-
&& validate_colon(CHILD(tree, 1))
2907-
&& validate_test(CHILD(tree, 2)));
2908+
int res;
2909+
int i = 0;
2910+
2911+
res = validate_ntype(tree, dictorsetmaker);
2912+
if (!res)
2913+
return 0;
29082914

2909-
if (res && ((nch % 4) == 0))
2910-
res = validate_comma(CHILD(tree, --nch));
2911-
else if (res)
2912-
res = ((nch % 4) == 3);
2913-
2914-
if (res && (nch > 3)) {
2915-
int pos = 3;
2916-
/* ( ',' test ':' test )* */
2917-
while (res && (pos < nch)) {
2918-
res = (validate_comma(CHILD(tree, pos))
2919-
&& validate_test(CHILD(tree, pos + 1))
2920-
&& validate_colon(CHILD(tree, pos + 2))
2921-
&& validate_test(CHILD(tree, pos + 3)));
2922-
pos += 4;
2915+
if (nch - i < 1) {
2916+
(void) validate_numnodes(tree, 1, "dictorsetmaker");
2917+
return 0;
2918+
}
2919+
2920+
res = validate_test(CHILD(tree, i++));
2921+
if (!res)
2922+
return 0;
2923+
2924+
if (nch - i >= 2 && TYPE(CHILD(tree, i)) == COLON) {
2925+
/* Dictionary display or dictionary comprehension. */
2926+
res = (validate_colon(CHILD(tree, i++))
2927+
&& validate_test(CHILD(tree, i++)));
2928+
if (!res)
2929+
return 0;
2930+
2931+
if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) {
2932+
/* Dictionary comprehension. */
2933+
res = validate_comp_for(CHILD(tree, i++));
2934+
if (!res)
2935+
return 0;
2936+
}
2937+
else {
2938+
/* Dictionary display. */
2939+
while (nch - i >= 4) {
2940+
res = (validate_comma(CHILD(tree, i++))
2941+
&& validate_test(CHILD(tree, i++))
2942+
&& validate_colon(CHILD(tree, i++))
2943+
&& validate_test(CHILD(tree, i++)));
2944+
if (!res)
2945+
return 0;
2946+
}
2947+
if (nch - i == 1) {
2948+
res = validate_comma(CHILD(tree, i++));
2949+
if (!res)
2950+
return 0;
2951+
}
29232952
}
29242953
}
2925-
return (res);
2954+
else {
2955+
/* Set display or set comprehension. */
2956+
if (nch - i >= 1 && TYPE(CHILD(tree, i)) == comp_for) {
2957+
/* Set comprehension. */
2958+
res = validate_comp_for(CHILD(tree, i++));
2959+
if (!res)
2960+
return 0;
2961+
}
2962+
else {
2963+
/* Set display. */
2964+
while (nch - i >= 2) {
2965+
res = (validate_comma(CHILD(tree, i++))
2966+
&& validate_test(CHILD(tree, i++)));
2967+
if (!res)
2968+
return 0;
2969+
}
2970+
if (nch - i == 1) {
2971+
res = validate_comma(CHILD(tree, i++));
2972+
if (!res)
2973+
return 0;
2974+
}
2975+
}
2976+
}
2977+
2978+
if (nch - i > 0) {
2979+
err_string("Illegal trailing nodes for dictorsetmaker.");
2980+
return 0;
2981+
}
2982+
2983+
return 1;
29262984
}
29272985

29282986

0 commit comments

Comments
 (0)