@@ -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+ */
957964static int
958965validate_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 */
20992106static int
21002107validate_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