bpo-36961: Handle positional-only arguments in uparse.c (GH-13412)

This commit is contained in:
Pablo Galindo 2019-05-18 23:40:22 +01:00 committed by GitHub
parent fa19a25c23
commit da6129e821
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 6 deletions

View File

@ -183,6 +183,18 @@ class AnnotationsFutureTestCase(unittest.TestCase):
eq('lambda a, b, c=True: a') eq('lambda a, b, c=True: a')
eq("lambda a, b, c=True, *, d=1 << v2, e='str': a") eq("lambda a, b, c=True, *, d=1 << v2, e='str': a")
eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b") eq("lambda a, b, c=True, *vararg, d, e='str', **kwargs: a + b")
eq("lambda a, /, b, c=True, *vararg, d, e='str', **kwargs: a + b")
eq('lambda x, /: x')
eq('lambda x=1, /: x')
eq('lambda x, /, y: x + y')
eq('lambda x=1, /, y=2: x + y')
eq('lambda x, /, y=1: x + y')
eq('lambda x, /, y=1, *, z=3: x + y + z')
eq('lambda x=1, /, y=2, *, z=3: x + y + z')
eq('lambda x=1, /, y=2, *, z: x + y + z')
eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2: x + y + z + w + l + l2')
eq('lambda x=1, y=2, z=3, /, w=4, *, l, l2, **kwargs: x + y + z + w + l + l2')
eq('lambda x, /, y=1, *, z: x + y + z')
eq('lambda x: lambda y: x + y') eq('lambda x: lambda y: x + y')
eq('1 if True else 2') eq('1 if True else 2')
eq('str or None if int or True else str or bytes or None') eq('str or None if int or True else str or bytes or None')

View File

@ -193,22 +193,30 @@ static int
append_ast_args(_PyUnicodeWriter *writer, arguments_ty args) append_ast_args(_PyUnicodeWriter *writer, arguments_ty args)
{ {
bool first; bool first;
Py_ssize_t i, di, arg_count, default_count; Py_ssize_t i, di, arg_count, posonlyarg_count, default_count;
first = true; first = true;
/* positional arguments with defaults */ /* positional-only and positional arguments with defaults */
posonlyarg_count = asdl_seq_LEN(args->posonlyargs);
arg_count = asdl_seq_LEN(args->args); arg_count = asdl_seq_LEN(args->args);
default_count = asdl_seq_LEN(args->defaults); default_count = asdl_seq_LEN(args->defaults);
for (i = 0; i < arg_count; i++) { for (i = 0; i < posonlyarg_count + arg_count; i++) {
APPEND_STR_IF_NOT_FIRST(", "); APPEND_STR_IF_NOT_FIRST(", ");
APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i)); if (i < posonlyarg_count){
APPEND(arg, (arg_ty)asdl_seq_GET(args->posonlyargs, i));
} else {
APPEND(arg, (arg_ty)asdl_seq_GET(args->args, i-posonlyarg_count));
}
di = i - arg_count + default_count; di = i - posonlyarg_count - arg_count + default_count;
if (di >= 0) { if (di >= 0) {
APPEND_STR("="); APPEND_STR("=");
APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST); APPEND_EXPR((expr_ty)asdl_seq_GET(args->defaults, di), PR_TEST);
} }
if (posonlyarg_count && i + 1 == posonlyarg_count) {
APPEND_STR(", /");
}
} }
/* vararg, or bare '*' if no varargs but keyword-only arguments present */ /* vararg, or bare '*' if no varargs but keyword-only arguments present */
@ -251,7 +259,9 @@ static int
append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level) append_ast_lambda(_PyUnicodeWriter *writer, expr_ty e, int level)
{ {
APPEND_STR_IF(level > PR_TEST, "("); APPEND_STR_IF(level > PR_TEST, "(");
APPEND_STR(asdl_seq_LEN(e->v.Lambda.args->args) ? "lambda " : "lambda"); Py_ssize_t n_positional = (asdl_seq_LEN(e->v.Lambda.args->args) +
asdl_seq_LEN(e->v.Lambda.args->posonlyargs));
APPEND_STR(n_positional ? "lambda " : "lambda");
APPEND(args, e->v.Lambda.args); APPEND(args, e->v.Lambda.args);
APPEND_STR(": "); APPEND_STR(": ");
APPEND_EXPR(e->v.Lambda.body, PR_TEST); APPEND_EXPR(e->v.Lambda.body, PR_TEST);