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
This commit is contained in:
Pablo Galindo 2019-04-29 13:36:57 +01:00 committed by GitHub
parent 99fcc616d4
commit 8c77b8cb91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
38 changed files with 5771 additions and 4710 deletions

50
Python/Python-ast.c generated
View file

@ -469,6 +469,7 @@ static char *ExceptHandler_fields[]={
};
static PyTypeObject *arguments_type;
static PyObject* ast2obj_arguments(void*);
_Py_IDENTIFIER(posonlyargs);
_Py_IDENTIFIER(vararg);
_Py_IDENTIFIER(kwonlyargs);
_Py_IDENTIFIER(kw_defaults);
@ -476,6 +477,7 @@ _Py_IDENTIFIER(kwarg);
_Py_IDENTIFIER(defaults);
static char *arguments_fields[]={
"args",
"posonlyargs",
"vararg",
"kwonlyargs",
"kw_defaults",
@ -1141,7 +1143,7 @@ static int init_types(void)
ExceptHandler_type = make_type("ExceptHandler", excepthandler_type,
ExceptHandler_fields, 3);
if (!ExceptHandler_type) return 0;
arguments_type = make_type("arguments", &AST_type, arguments_fields, 6);
arguments_type = make_type("arguments", &AST_type, arguments_fields, 7);
if (!arguments_type) return 0;
if (!add_attributes(arguments_type, NULL, 0)) return 0;
arg_type = make_type("arg", &AST_type, arg_fields, 3);
@ -2569,14 +2571,16 @@ ExceptHandler(expr_ty type, identifier name, asdl_seq * body, int lineno, int
}
arguments_ty
arguments(asdl_seq * args, arg_ty vararg, asdl_seq * kwonlyargs, asdl_seq *
kw_defaults, arg_ty kwarg, asdl_seq * defaults, PyArena *arena)
arguments(asdl_seq * args, asdl_seq * posonlyargs, arg_ty vararg, asdl_seq *
kwonlyargs, asdl_seq * kw_defaults, arg_ty kwarg, asdl_seq *
defaults, PyArena *arena)
{
arguments_ty p;
p = (arguments_ty)PyArena_Malloc(arena, sizeof(*p));
if (!p)
return NULL;
p->args = args;
p->posonlyargs = posonlyargs;
p->vararg = vararg;
p->kwonlyargs = kwonlyargs;
p->kw_defaults = kw_defaults;
@ -3954,6 +3958,11 @@ ast2obj_arguments(void* _o)
if (_PyObject_SetAttrId(result, &PyId_args, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_list(o->posonlyargs, ast2obj_arg);
if (!value) goto failed;
if (_PyObject_SetAttrId(result, &PyId_posonlyargs, value) == -1)
goto failed;
Py_DECREF(value);
value = ast2obj_arg(o->vararg);
if (!value) goto failed;
if (_PyObject_SetAttrId(result, &PyId_vararg, value) == -1)
@ -8267,6 +8276,7 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena)
{
PyObject* tmp = NULL;
asdl_seq* args;
asdl_seq* posonlyargs;
arg_ty vararg;
asdl_seq* kwonlyargs;
asdl_seq* kw_defaults;
@ -8303,6 +8313,36 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena)
}
Py_CLEAR(tmp);
}
if (_PyObject_LookupAttrId(obj, &PyId_posonlyargs, &tmp) < 0) {
return 1;
}
if (tmp == NULL) {
PyErr_SetString(PyExc_TypeError, "required field \"posonlyargs\" missing from arguments");
return 1;
}
else {
int res;
Py_ssize_t len;
Py_ssize_t i;
if (!PyList_Check(tmp)) {
PyErr_Format(PyExc_TypeError, "arguments field \"posonlyargs\" must be a list, not a %.200s", tmp->ob_type->tp_name);
goto failed;
}
len = PyList_GET_SIZE(tmp);
posonlyargs = _Py_asdl_seq_new(len, arena);
if (posonlyargs == NULL) goto failed;
for (i = 0; i < len; i++) {
arg_ty val;
res = obj2ast_arg(PyList_GET_ITEM(tmp, i), &val, arena);
if (res != 0) goto failed;
if (len != PyList_GET_SIZE(tmp)) {
PyErr_SetString(PyExc_RuntimeError, "arguments field \"posonlyargs\" changed size during iteration");
goto failed;
}
asdl_seq_SET(posonlyargs, i, val);
}
Py_CLEAR(tmp);
}
if (_PyObject_LookupAttrId(obj, &PyId_vararg, &tmp) < 0) {
return 1;
}
@ -8419,8 +8459,8 @@ obj2ast_arguments(PyObject* obj, arguments_ty* out, PyArena* arena)
}
Py_CLEAR(tmp);
}
*out = arguments(args, vararg, kwonlyargs, kw_defaults, kwarg, defaults,
arena);
*out = arguments(args, posonlyargs, vararg, kwonlyargs, kw_defaults, kwarg,
defaults, arena);
return 0;
failed:
Py_XDECREF(tmp);

View file

@ -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));

View file

@ -3694,10 +3694,10 @@ missing_arguments(PyCodeObject *co, Py_ssize_t missing, Py_ssize_t defcount,
return;
if (positional) {
start = 0;
end = co->co_argcount - defcount;
end = co->co_posonlyargcount + co->co_argcount - defcount;
}
else {
start = co->co_argcount;
start = co->co_posonlyargcount + co->co_argcount;
end = start + co->co_kwonlyargcount;
}
for (i = start; i < end; i++) {
@ -3724,23 +3724,25 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount,
Py_ssize_t kwonly_given = 0;
Py_ssize_t i;
PyObject *sig, *kwonly_sig;
Py_ssize_t co_posonlyargcount = co->co_posonlyargcount;
Py_ssize_t co_argcount = co->co_argcount;
Py_ssize_t total_positional = co_argcount + co_posonlyargcount;
assert((co->co_flags & CO_VARARGS) == 0);
/* Count missing keyword-only args. */
for (i = co_argcount; i < co_argcount + co->co_kwonlyargcount; i++) {
for (i = total_positional; i < total_positional + co->co_kwonlyargcount; i++) {
if (GETLOCAL(i) != NULL) {
kwonly_given++;
}
}
if (defcount) {
Py_ssize_t atleast = co_argcount - defcount;
Py_ssize_t atleast = total_positional - defcount;
plural = 1;
sig = PyUnicode_FromFormat("from %zd to %zd", atleast, co_argcount);
sig = PyUnicode_FromFormat("from %zd to %zd", atleast, total_positional);
}
else {
plural = (co_argcount != 1);
sig = PyUnicode_FromFormat("%zd", co_argcount);
plural = (total_positional != 1);
sig = PyUnicode_FromFormat("%zd", total_positional);
}
if (sig == NULL)
return;
@ -3772,6 +3774,67 @@ too_many_positional(PyCodeObject *co, Py_ssize_t given, Py_ssize_t defcount,
Py_DECREF(kwonly_sig);
}
static int
positional_only_passed_as_keyword(PyCodeObject *co, Py_ssize_t kwcount,
PyObject* const* kwnames)
{
int posonly_conflicts = 0;
PyObject* posonly_names = PyList_New(0);
for(int k=0; k < co->co_posonlyargcount; k++){
PyObject* posonly_name = PyTuple_GET_ITEM(co->co_varnames, k);
for (int k2=0; k2<kwcount; k2++){
/* Compare the pointers first and fallback to PyObject_RichCompareBool*/
PyObject* kwname = kwnames[k2];
if (kwname == posonly_name){
if(PyList_Append(posonly_names, kwname) != 0) {
goto fail;
}
posonly_conflicts++;
continue;
}
int cmp = PyObject_RichCompareBool(posonly_name, kwname, Py_EQ);
if ( cmp > 0) {
if(PyList_Append(posonly_names, kwname) != 0) {
goto fail;
}
posonly_conflicts++;
} else if (cmp < 0) {
goto fail;
}
}
}
if (posonly_conflicts) {
PyObject* comma = PyUnicode_FromString(", ");
if (comma == NULL) {
goto fail;
}
PyObject* error_names = PyUnicode_Join(comma, posonly_names);
Py_DECREF(comma);
if (error_names == NULL) {
goto fail;
}
PyErr_Format(PyExc_TypeError,
"%U() got some positional-only arguments passed"
" as keyword arguments: '%U'",
co->co_name, error_names);
Py_DECREF(error_names);
goto fail;
}
Py_DECREF(posonly_names);
return 0;
fail:
Py_XDECREF(posonly_names);
return 1;
}
/* This is gonna seem *real weird*, but if you put some other code between
PyEval_EvalFrame() and _PyEval_EvalFrameDefault() you will need to adjust
the test in the if statements in Misc/gdbinit (pystack and pystackv). */
@ -3791,8 +3854,8 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
PyObject **fastlocals, **freevars;
PyThreadState *tstate;
PyObject *x, *u;
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
Py_ssize_t i, n;
const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount + co->co_posonlyargcount;
Py_ssize_t i, j, n;
PyObject *kwdict;
if (globals == NULL) {
@ -3826,14 +3889,28 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
kwdict = NULL;
}
/* Copy positional arguments into local variables */
if (argcount > co->co_argcount) {
n = co->co_argcount;
/* Copy positional only arguments into local variables */
if (argcount > co->co_argcount + co->co_posonlyargcount) {
n = co->co_posonlyargcount;
}
else {
n = argcount;
}
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
x = args[j];
Py_INCREF(x);
SETLOCAL(j, x);
}
/* Copy positional arguments into local variables */
if (argcount > co->co_argcount + co->co_posonlyargcount) {
n += co->co_argcount;
}
else {
n = argcount;
}
for (i = j; i < n; i++) {
x = args[i];
Py_INCREF(x);
SETLOCAL(i, x);
@ -3866,7 +3943,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
/* Speed hack: do raw pointer compares. As names are
normally interned this should almost always hit. */
co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
for (j = 0; j < total_args; j++) {
for (j = co->co_posonlyargcount; j < total_args; j++) {
PyObject *name = co_varnames[j];
if (name == keyword) {
goto kw_found;
@ -3874,7 +3951,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
}
/* Slow fallback, just in case */
for (j = 0; j < total_args; j++) {
for (j = co->co_posonlyargcount; j < total_args; j++) {
PyObject *name = co_varnames[j];
int cmp = PyObject_RichCompareBool( keyword, name, Py_EQ);
if (cmp > 0) {
@ -3887,6 +3964,11 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
assert(j >= total_args);
if (kwdict == NULL) {
if (co->co_posonlyargcount && positional_only_passed_as_keyword(co, kwcount, kwnames)) {
goto fail;
}
PyErr_Format(PyExc_TypeError,
"%U() got an unexpected keyword argument '%S'",
co->co_name, keyword);
@ -3910,14 +3992,14 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
}
/* Check the number of positional arguments */
if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
if ((argcount > co->co_argcount + co->co_posonlyargcount) && !(co->co_flags & CO_VARARGS)) {
too_many_positional(co, argcount, defcount, fastlocals);
goto fail;
}
/* Add missing positional arguments (copy default values from defs) */
if (argcount < co->co_argcount) {
Py_ssize_t m = co->co_argcount - defcount;
if (argcount < co->co_posonlyargcount + co->co_argcount) {
Py_ssize_t m = co->co_posonlyargcount + co->co_argcount - defcount;
Py_ssize_t missing = 0;
for (i = argcount; i < m; i++) {
if (GETLOCAL(i) == NULL) {
@ -3944,7 +4026,7 @@ _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
/* Add missing keyword arguments (copy default values from kwdefs) */
if (co->co_kwonlyargcount > 0) {
Py_ssize_t missing = 0;
for (i = co->co_argcount; i < total_args; i++) {
for (i = co->co_posonlyargcount + co->co_argcount; i < total_args; i++) {
PyObject *name;
if (GETLOCAL(i) != NULL)
continue;

View file

@ -122,6 +122,7 @@ struct compiler_unit {
PyObject *u_private; /* for private name mangling */
Py_ssize_t u_argcount; /* number of arguments for block */
Py_ssize_t u_posonlyargcount; /* number of positional only arguments for block */
Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */
/* Pointer to the most recently allocated block. By following b_list
members, you can reach all early allocated blocks. */
@ -552,6 +553,7 @@ compiler_enter_scope(struct compiler *c, identifier name,
memset(u, 0, sizeof(struct compiler_unit));
u->u_scope_type = scope_type;
u->u_argcount = 0;
u->u_posonlyargcount = 0;
u->u_kwonlyargcount = 0;
u->u_ste = PySymtable_Lookup(c->c_st, key);
if (!u->u_ste) {
@ -2127,6 +2129,7 @@ compiler_function(struct compiler *c, stmt_ty s, int is_async)
}
c->u->u_argcount = asdl_seq_LEN(args->args);
c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
VISIT_SEQ_IN_SCOPE(c, stmt, body);
co = assemble(c, 1);
@ -2507,6 +2510,7 @@ compiler_lambda(struct compiler *c, expr_ty e)
return 0;
c->u->u_argcount = asdl_seq_LEN(args->args);
c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
if (c->u->u_ste->ste_generator) {
@ -5742,7 +5746,7 @@ makecode(struct compiler *c, struct assembler *a)
Py_ssize_t nlocals;
int nlocals_int;
int flags;
int argcount, kwonlyargcount, maxdepth;
int argcount, posonlyargcount, kwonlyargcount, maxdepth;
consts = consts_dict_keys_inorder(c->u->u_consts);
names = dict_keys_inorder(c->u->u_names, 0);
@ -5787,12 +5791,13 @@ makecode(struct compiler *c, struct assembler *a)
}
argcount = Py_SAFE_DOWNCAST(c->u->u_argcount, Py_ssize_t, int);
posonlyargcount = Py_SAFE_DOWNCAST(c->u->u_posonlyargcount, Py_ssize_t, int);
kwonlyargcount = Py_SAFE_DOWNCAST(c->u->u_kwonlyargcount, Py_ssize_t, int);
maxdepth = stackdepth(c);
if (maxdepth < 0) {
goto error;
}
co = PyCode_New(argcount, kwonlyargcount,
co = PyCode_New(argcount, posonlyargcount, kwonlyargcount,
nlocals_int, maxdepth, flags,
bytecode, consts, names, varnames,
freevars, cellvars,

View file

@ -15,15 +15,15 @@
the appropriate bytes from M___main__.c. */
static unsigned char M___hello__[] = {
227,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,
0,64,0,0,0,115,16,0,0,0,100,0,90,0,101,1,
100,1,131,1,1,0,100,2,83,0,41,3,84,122,12,72,
101,108,108,111,32,119,111,114,108,100,33,78,41,2,218,11,
105,110,105,116,105,97,108,105,122,101,100,218,5,112,114,105,
110,116,169,0,114,3,0,0,0,114,3,0,0,0,250,22,
46,47,84,111,111,108,115,47,102,114,101,101,122,101,47,102,
108,97,103,46,112,121,218,8,60,109,111,100,117,108,101,62,
1,0,0,0,115,2,0,0,0,4,1,
227,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,2,0,0,0,64,0,0,0,115,16,0,0,0,100,0,
90,0,101,1,100,1,131,1,1,0,100,2,83,0,41,3,
84,122,12,72,101,108,108,111,32,119,111,114,108,100,33,78,
41,2,218,11,105,110,105,116,105,97,108,105,122,101,100,218,
5,112,114,105,110,116,169,0,114,3,0,0,0,114,3,0,
0,0,250,20,84,111,111,108,115,47,102,114,101,101,122,101,
47,102,108,97,103,46,112,121,218,8,60,109,111,100,117,108,
101,62,1,0,0,0,115,2,0,0,0,4,1,
};
#define SIZE (int)sizeof(M___hello__)

File diff suppressed because it is too large Load diff

2781
Python/importlib.h generated

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -530,6 +530,7 @@ w_complex_object(PyObject *v, char flag, WFILE *p)
PyCodeObject *co = (PyCodeObject *)v;
W_TYPE(TYPE_CODE, p);
w_long(co->co_argcount, p);
w_long(co->co_posonlyargcount, p);
w_long(co->co_kwonlyargcount, p);
w_long(co->co_nlocals, p);
w_long(co->co_stacksize, p);
@ -1322,6 +1323,7 @@ r_object(RFILE *p)
case TYPE_CODE:
{
int argcount;
int posonlyargcount;
int kwonlyargcount;
int nlocals;
int stacksize;
@ -1347,6 +1349,10 @@ r_object(RFILE *p)
argcount = (int)r_long(p);
if (PyErr_Occurred())
goto code_error;
posonlyargcount = (int)r_long(p);
if (PyErr_Occurred()) {
goto code_error;
}
kwonlyargcount = (int)r_long(p);
if (PyErr_Occurred())
goto code_error;
@ -1391,7 +1397,7 @@ r_object(RFILE *p)
goto code_error;
v = (PyObject *) PyCode_New(
argcount, kwonlyargcount,
argcount, posonlyargcount, kwonlyargcount,
nlocals, stacksize, flags,
code, consts, names, varnames,
freevars, cellvars, filename, name,

View file

@ -1653,6 +1653,8 @@ symtable_visit_arguments(struct symtable *st, arguments_ty a)
/* skip default arguments inside function block
XXX should ast be different?
*/
if (a->posonlyargs && !symtable_visit_params(st, a->posonlyargs))
return 0;
if (a->args && !symtable_visit_params(st, a->args))
return 0;
if (a->kwonlyargs && !symtable_visit_params(st, a->kwonlyargs))