summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
authorPablo Galindo <Pablogsal@gmail.com>2019-04-29 12:36:57 (GMT)
committerGitHub <noreply@github.com>2019-04-29 12:36:57 (GMT)
commit8c77b8cb9188165a123f2512026e3629bf03dc9b (patch)
tree863ea19f5f2c8ec179c32b3d06dc8366859ae26e /Python/ast.c
parent99fcc616d400cd31af0733c3f8cc93bcc1d32a44 (diff)
downloadcpython-8c77b8cb9188165a123f2512026e3629bf03dc9b.zip
cpython-8c77b8cb9188165a123f2512026e3629bf03dc9b.tar.gz
cpython-8c77b8cb9188165a123f2512026e3629bf03dc9b.tar.bz2
bpo-36540: PEP 570 -- Implementation (GH-12701)
This commit contains the implementation of PEP570: Python positional-only parameters. * Update Grammar/Grammar with new typedarglist and varargslist * Regenerate grammar files * Update and regenerate AST related files * Update code object * Update marshal.c * Update compiler and symtable * Regenerate importlib files * Update callable objects * Implement positional-only args logic in ceval.c * Regenerate frozen data * Update standard library to account for positional-only args * Add test file for positional-only args * Update other test files to account for positional-only args * Add News entry * Update inspect module and related tests
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c100
1 files changed, 82 insertions, 18 deletions
diff --git a/Python/ast.c b/Python/ast.c
index 913e53a..4687f81 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -110,8 +110,9 @@ expr_context_name(expr_context_ty ctx)
static int
validate_arguments(arguments_ty args)
{
- if (!validate_args(args->args))
+ if (!validate_args(args->posonlyargs) || !validate_args(args->args)) {
return 0;
+ }
if (args->vararg && args->vararg->annotation
&& !validate_expr(args->vararg->annotation, Load)) {
return 0;
@@ -1431,31 +1432,73 @@ ast_for_arguments(struct compiling *c, const node *n)
and varargslist (lambda definition).
parameters: '(' [typedargslist] ')'
- typedargslist: (tfpdef ['=' test] (',' tfpdef ['=' test])* [',' [
- '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
- | '**' tfpdef [',']]]
- | '*' [tfpdef] (',' tfpdef ['=' test])* [',' ['**' tfpdef [',']]]
- | '**' tfpdef [','])
+
+ The following definition for typedarglist is equivalent to this set of rules:
+
+ arguments = argument (',' [TYPE_COMMENT] argument)*
+ argument = tfpdef ['=' test]
+ kwargs = '**' tfpdef [','] [TYPE_COMMENT]
+ args = '*' [tfpdef]
+ kwonly_kwargs = (',' [TYPE_COMMENT] argument)* (TYPE_COMMENT | [','
+ [TYPE_COMMENT] [kwargs]])
+ args_kwonly_kwargs = args kwonly_kwargs | kwargs
+ poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [','
+ [TYPE_COMMENT] [args_kwonly_kwargs]])
+ typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+ typedarglist = (arguments ',' [TYPE_COMMENT] '/' [',' [[TYPE_COMMENT]
+ typedargslist_no_posonly]])|(typedargslist_no_posonly)"
+
+ typedargslist: ( (tfpdef ['=' test] (',' [TYPE_COMMENT] tfpdef ['=' test])*
+ ',' [TYPE_COMMENT] '/' [',' [ [TYPE_COMMENT] tfpdef ['=' test] ( ','
+ [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*'
+ [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [','
+ [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [',']
+ [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])*
+ (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) |
+ '**' tfpdef [','] [TYPE_COMMENT]]] ) | (tfpdef ['=' test] (','
+ [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [',' [TYPE_COMMENT] [ '*'
+ [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])* (TYPE_COMMENT | [','
+ [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) | '**' tfpdef [',']
+ [TYPE_COMMENT]]]) | '*' [tfpdef] (',' [TYPE_COMMENT] tfpdef ['=' test])*
+ (TYPE_COMMENT | [',' [TYPE_COMMENT] ['**' tfpdef [','] [TYPE_COMMENT]]]) |
+ '**' tfpdef [','] [TYPE_COMMENT]))
+
tfpdef: NAME [':' test]
- varargslist: (vfpdef ['=' test] (',' vfpdef ['=' test])* [',' [
- '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
- | '**' vfpdef [',']]]
- | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
- | '**' vfpdef [',']
- )
+
+ The following definition for varargslist is equivalent to this set of rules:
+
+ arguments = argument (',' argument )*
+ argument = vfpdef ['=' test]
+ kwargs = '**' vfpdef [',']
+ args = '*' [vfpdef]
+ kwonly_kwargs = (',' argument )* [',' [kwargs]]
+ args_kwonly_kwargs = args kwonly_kwargs | kwargs
+ poskeyword_args_kwonly_kwargs = arguments [',' [args_kwonly_kwargs]]
+ vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs
+ varargslist = arguments ',' '/' [','[(vararglist_no_posonly)]] |
+ (vararglist_no_posonly)
+
+ varargslist: vfpdef ['=' test ](',' vfpdef ['=' test])* ',' '/' [',' [ (vfpdef ['='
+ test] (',' vfpdef ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [','
+ ['**' vfpdef [',']]] | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])*
+ [',' ['**' vfpdef [',']]] | '**' vfpdef [',']) ]] | (vfpdef ['=' test] (',' vfpdef
+ ['=' test])* [',' [ '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef [',']]]
+ | '**' vfpdef [',']]] | '*' [vfpdef] (',' vfpdef ['=' test])* [',' ['**' vfpdef
+ [',']]] | '**' vfpdef [','])
+
vfpdef: NAME
*/
- int i, j, k, nposargs = 0, nkwonlyargs = 0;
+ int i, j, k, l, nposonlyargs=0, nposargs = 0, nkwonlyargs = 0;
int nposdefaults = 0, found_default = 0;
- asdl_seq *posargs, *posdefaults, *kwonlyargs, *kwdefaults;
+ asdl_seq *posonlyargs, *posargs, *posdefaults, *kwonlyargs, *kwdefaults;
arg_ty vararg = NULL, kwarg = NULL;
arg_ty arg = NULL;
node *ch;
if (TYPE(n) == parameters) {
if (NCH(n) == 2) /* () as argument list */
- return arguments(NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena);
+ return arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena);
n = CHILD(n, 1);
}
assert(TYPE(n) == typedargslist || TYPE(n) == varargslist);
@@ -1479,6 +1522,10 @@ ast_for_arguments(struct compiling *c, const node *n)
if (TYPE(ch) == DOUBLESTAR) break;
if (TYPE(ch) == vfpdef || TYPE(ch) == tfpdef) nposargs++;
if (TYPE(ch) == EQUAL) nposdefaults++;
+ if (TYPE(ch) == SLASH ) {
+ nposonlyargs = nposargs;
+ nposargs = 0;
+ }
}
/* count the number of keyword only args &
defaults for keyword only args */
@@ -1487,6 +1534,10 @@ ast_for_arguments(struct compiling *c, const node *n)
if (TYPE(ch) == DOUBLESTAR) break;
if (TYPE(ch) == tfpdef || TYPE(ch) == vfpdef) nkwonlyargs++;
}
+ posonlyargs = (nposonlyargs ? _Py_asdl_seq_new(nposonlyargs, c->c_arena) : NULL);
+ if (!posonlyargs && nposonlyargs) {
+ return NULL;
+ }
posargs = (nposargs ? _Py_asdl_seq_new(nposargs, c->c_arena) : NULL);
if (!posargs && nposargs)
return NULL;
@@ -1512,6 +1563,7 @@ ast_for_arguments(struct compiling *c, const node *n)
i = 0;
j = 0; /* index for defaults */
k = 0; /* index for args */
+ l = 0; /* index for posonlyargs */
while (i < NCH(n)) {
ch = CHILD(n, i);
switch (TYPE(ch)) {
@@ -1537,11 +1589,23 @@ ast_for_arguments(struct compiling *c, const node *n)
arg = ast_for_arg(c, ch);
if (!arg)
return NULL;
- asdl_seq_SET(posargs, k++, arg);
+ if (l < nposonlyargs) {
+ asdl_seq_SET(posonlyargs, l++, arg);
+ } else {
+ asdl_seq_SET(posargs, k++, arg);
+ }
i += 1; /* the name */
if (i < NCH(n) && TYPE(CHILD(n, i)) == COMMA)
i += 1; /* the comma, if present */
break;
+ case SLASH:
+ /* Advance the slash and the comma. If there are more names
+ * after the slash there will be a comma so we are advancing
+ * the correct number of nodes. If the slash is the last item,
+ * we will be advancing an extra token but then * i > NCH(n)
+ * and the enclosing while will finish correctly. */
+ i += 2;
+ break;
case STAR:
if (i+1 >= NCH(n) ||
(i+2 == NCH(n) && (TYPE(CHILD(n, i+1)) == COMMA
@@ -1621,7 +1685,7 @@ ast_for_arguments(struct compiling *c, const node *n)
return NULL;
}
}
- return arguments(posargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena);
+ return arguments(posargs, posonlyargs, vararg, kwonlyargs, kwdefaults, kwarg, posdefaults, c->c_arena);
}
static expr_ty
@@ -1909,7 +1973,7 @@ ast_for_lambdef(struct compiling *c, const node *n)
expr_ty expression;
if (NCH(n) == 3) {
- args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena);
+ args = arguments(NULL, NULL, NULL, NULL, NULL, NULL, NULL, c->c_arena);
if (!args)
return NULL;
expression = ast_for_expr(c, CHILD(n, 2));