compiler_visit_kwonlydefaults(struct compiler *c, asdl_seq *kwonlyargs,
asdl_seq *kw_defaults)
{
- /* Return the number of defaults + 1.
- Returns 0 on error.
- */
- int i, default_count = 0;
++ /* Push a dict of keyword-only default values.
++
++ Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
++ */
+ int i;
+ PyObject *keys = NULL;
+
for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
arg_ty arg = asdl_seq_GET(kwonlyargs, i);
expr_ty default_ = asdl_seq_GET(kw_defaults, i);
if (default_) {
PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
- if (!mangled)
- return 0;
- ADDOP_O(c, LOAD_CONST, mangled, consts);
- Py_DECREF(mangled);
+ if (!mangled) {
+ goto error;
+ }
+ if (keys == NULL) {
+ keys = PyList_New(1);
+ if (keys == NULL) {
+ Py_DECREF(mangled);
- return -1;
++ return 0;
+ }
+ PyList_SET_ITEM(keys, 0, mangled);
+ }
+ else {
+ int res = PyList_Append(keys, mangled);
+ Py_DECREF(mangled);
+ if (res == -1) {
+ goto error;
+ }
+ }
if (!compiler_visit_expr(c, default_)) {
- return 0;
+ goto error;
}
- default_count++;
}
}
- return default_count + 1;
+ if (keys != NULL) {
+ Py_ssize_t default_count = PyList_GET_SIZE(keys);
+ PyObject *keys_tuple = PyList_AsTuple(keys);
+ Py_DECREF(keys);
+ if (keys_tuple == NULL) {
- return -1;
++ return 0;
+ }
+ ADDOP_N(c, LOAD_CONST, keys_tuple, consts);
+ ADDOP_I(c, BUILD_CONST_KEY_MAP, default_count);
- return default_count;
++ assert(default_count > 0);
++ return 1;
+ }
+ else {
- return 0;
++ return -1;
+ }
+
+error:
+ Py_XDECREF(keys);
- return -1;
++ return 0;
}
static int
compiler_visit_annotations(struct compiler *c, arguments_ty args,
expr_ty returns)
{
- /* Push arg annotation dict. Return # of items pushed.
- /* Push arg annotations and a list of the argument names. Return the #
- of items pushed + 1. The expressions are evaluated out-of-order wrt the
- source code.
++ /* Push arg annotation dict.
+ The expressions are evaluated out-of-order wrt the source code.
- Returns -1 on error.
- More than 2^16-1 annotations is a SyntaxError. Returns 0 on error.
++ Return 0 on error, -1 if no dict pushed, 1 if a dict is pushed.
*/
static identifier return_str;
PyObject *names;
}
len = PyList_GET_SIZE(names);
- if (len > 65534) {
- /* len must fit in 16 bits, and len is incremented below */
- PyErr_SetString(PyExc_SyntaxError,
- "too many annotations");
- goto error;
- }
if (len) {
- /* convert names to a tuple and place on stack */
- PyObject *elt;
- Py_ssize_t i;
- PyObject *s = PyTuple_New(len);
- if (!s)
- goto error;
- for (i = 0; i < len; i++) {
- elt = PyList_GET_ITEM(names, i);
- Py_INCREF(elt);
- PyTuple_SET_ITEM(s, i, elt);
+ PyObject *keytuple = PyList_AsTuple(names);
+ Py_DECREF(names);
+ if (keytuple == NULL) {
- return -1;
++ return 0;
}
- ADDOP_O(c, LOAD_CONST, s, consts);
- Py_DECREF(s);
- len++; /* include the just-pushed tuple */
+ ADDOP_N(c, LOAD_CONST, keytuple, consts);
+ ADDOP_I(c, BUILD_CONST_KEY_MAP, len);
++ return 1;
+ }
+ else {
+ Py_DECREF(names);
++ return -1;
}
- return len;
- Py_DECREF(names);
-
- /* We just checked that len <= 65535, see above */
- return Py_SAFE_DOWNCAST(len + 1, Py_ssize_t, int);
error:
Py_DECREF(names);
- return -1;
+ return 0;
+ }
+
++static int
++compiler_visit_defaults(struct compiler *c, arguments_ty args)
++{
++ VISIT_SEQ(c, expr, args->defaults);
++ ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
++ return 1;
+}
+
+static Py_ssize_t
+compiler_default_arguments(struct compiler *c, arguments_ty args)
+{
+ Py_ssize_t funcflags = 0;
+ if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
- VISIT_SEQ(c, expr, args->defaults);
- ADDOP_I(c, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
++ if (!compiler_visit_defaults(c, args))
++ return -1;
+ funcflags |= 0x01;
+ }
+ if (args->kwonlyargs) {
- Py_ssize_t res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
++ int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
+ args->kw_defaults);
- if (res < 0) {
++ if (res == 0) {
+ return -1;
+ }
+ else if (res > 0) {
+ funcflags |= 0x02;
+ }
+ }
+ return funcflags;
+}
+
static int
compiler_function(struct compiler *c, stmt_ty s, int is_async)
{
asdl_seq* decos;
asdl_seq *body;
stmt_ty st;
- Py_ssize_t i, n, arglength;
- int docstring, kw_default_count = 0;
- int num_annotations;
+ Py_ssize_t i, n, funcflags;
+ int docstring;
- int num_annotations;
++ int annotations;
int scope_type;
-
if (is_async) {
assert(s->kind == AsyncFunctionDef_kind);
if (!compiler_decorators(c, decos))
return 0;
- if (args->defaults)
- VISIT_SEQ(c, expr, args->defaults);
- if (args->kwonlyargs) {
- int res = compiler_visit_kwonlydefaults(c, args->kwonlyargs,
- args->kw_defaults);
- if (res == 0)
- return 0;
- kw_default_count = res - 1;
+
+ funcflags = compiler_default_arguments(c, args);
+ if (funcflags == -1) {
+ return 0;
}
- num_annotations = compiler_visit_annotations(c, args, returns);
- if (num_annotations == 0)
+
- num_annotations = compiler_visit_annotations(c, args, returns);
- if (num_annotations < 0) {
++ annotations = compiler_visit_annotations(c, args, returns);
++ if (annotations == 0) {
return 0;
- num_annotations--;
- assert((num_annotations & 0xFFFF) == num_annotations);
+ }
- else if (num_annotations > 0) {
++ else if (annotations > 0) {
+ funcflags |= 0x04;
+ }
- if (!compiler_enter_scope(c, name,
- scope_type, (void *)s,
- s->lineno))
+ if (!compiler_enter_scope(c, name, scope_type, (void *)s, s->lineno)) {
return 0;
+ }
st = (stmt_ty)asdl_seq_GET(body, 0);
docstring = compiler_isdocstring(st);