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

Skip to content

Commit e7ab64e

Browse files
committed
validate_arglist(): Re-written to reflect extended call syntax.
validate_numnodes(): Added comment to explain the sometimes idiomatic usage pattern.
1 parent c35a20e commit e7ab64e

1 file changed

Lines changed: 80 additions & 3 deletions

File tree

Modules/parsermodule.c

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,13 @@ validate_ntype(node *n, int t)
954954
}
955955

956956

957+
/* Verifies that the number of child nodes is exactly 'num', raising
958+
* an exception if it isn't. The exception message does not indicate
959+
* the exact number of nodes, allowing this to be used to raise the
960+
* "right" exception when the wrong number of nodes is present in a
961+
* specific variant of a statement's syntax. This is commonly used
962+
* in that fashion.
963+
*/
957964
static int
958965
validate_numnodes(node *n, int num, const char *const name)
959966
{
@@ -2094,13 +2101,83 @@ validate_lambdef(node *tree)
20942101

20952102
/* arglist:
20962103
*
2097-
* argument (',' argument)* [',']
2104+
* (argument ',')* (argument* [','] | '*' test [',' '**' test] | '**' test)
20982105
*/
20992106
static int
21002107
validate_arglist(node *tree)
21012108
{
2102-
return (validate_repeating_list(tree, arglist,
2103-
validate_argument, "arglist"));
2109+
int nch = NCH(tree);
2110+
int i, ok;
2111+
node *last;
2112+
2113+
if (nch <= 0)
2114+
/* raise the right error from having an invalid number of children */
2115+
return validate_numnodes(tree, nch + 1, "arglist");
2116+
2117+
last = CHILD(tree, nch - 1);
2118+
if (TYPE(last) == test) {
2119+
/* Extended call syntax introduced in Python 1.6 has been used;
2120+
* validate and strip that off and continue;
2121+
* adjust nch to perform the cut, and ensure resulting nch is even
2122+
* (validation of the first part doesn't require that).
2123+
*/
2124+
if (nch < 2) {
2125+
validate_numnodes(tree, nch + 1, "arglist");
2126+
return 0;
2127+
}
2128+
ok = validate_test(last);
2129+
if (ok) {
2130+
node *prev = CHILD(tree, nch - 2);
2131+
/* next must be '*' or '**' */
2132+
if (validate_doublestar(prev)) {
2133+
nch -= 2;
2134+
if (nch >= 3) {
2135+
/* may include: '*' test ',' */
2136+
last = CHILD(tree, nch - 1);
2137+
prev = CHILD(tree, nch - 2);
2138+
if (TYPE(prev) == test) {
2139+
ok = validate_comma(last)
2140+
&& validate_test(prev)
2141+
&& validate_star(CHILD(tree, nch - 3));
2142+
if (ok)
2143+
nch -= 3;
2144+
}
2145+
/* otherwise, nothing special */
2146+
}
2147+
}
2148+
else {
2149+
/* must be only: '*' test */
2150+
PyErr_Clear();
2151+
ok = validate_star(prev);
2152+
nch -= 2;
2153+
}
2154+
if (ok && is_odd(nch)) {
2155+
/* Illegal number of nodes before extended call syntax;
2156+
* validation of the "normal" arguments does not require
2157+
* a trailing comma, but requiring an even number of
2158+
* children will effect the same requirement.
2159+
*/
2160+
return validate_numnodes(tree, nch + 1, "arglist");
2161+
}
2162+
}
2163+
}
2164+
/* what remains must be: (argument ",")* [argument [","]] */
2165+
i = 0;
2166+
while (ok && nch - i >= 2) {
2167+
ok = validate_argument(CHILD(tree, i))
2168+
&& validate_comma(CHILD(tree, i + 1));
2169+
i += 2;
2170+
}
2171+
if (ok && i < nch) {
2172+
ok = validate_comma(CHILD(tree, i));
2173+
++i;
2174+
}
2175+
if (i != nch) {
2176+
/* internal error! */
2177+
ok = 0;
2178+
err_string("arglist: internal error; nch != i");
2179+
}
2180+
return (ok);
21042181
}
21052182

21062183

0 commit comments

Comments
 (0)