Author Benjamin.S.Wolf
Recipients Benjamin.S.Wolf
Date 2019-07-14.18:55:36
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <>
Positional-only arguments come before position-or-keyword arguments.

    def f(pos1, pos2, /, pos_or_kwd, *, kwd1, kwd2):

However, the posonlyargs are defined to come after args in the AST:

    arguments = (arg* args, arg* posonlyargs, arg? vararg, arg* kwonlyargs,
                 expr* kw_defaults, arg? kwarg, expr* defaults)

which results in confusing ast.dump output because they share defaults:

>>> r = ast.parse('lambda a=1,/,b=2:a+b', mode='eval')
>>> ast.dump(r.body.args)
    args=[arg(arg='b', annotation=None, type_comment=None)],
    posonlyargs=[arg(arg='a', annotation=None, type_comment=None)],
    vararg=None, kwonlyargs=[], kw_defaults=[], kwarg=None,
    defaults=[Constant(value=1, kind=None), Constant(value=2, kind=None)])"
[manually prettified]

Note how the ordering is 'args b', then 'posonlyargs a', but the defaults are still 1 then 2. This can be confusing to someone building an ast.arguments using keywords because the elements in 'defaults' have to be supplied in a specific order, but the keyword args 'args' and 'posonlyargs' do not, or to someone building an ast.arguments using positional arguments (because, maybe ironically, they're not keyword-only arguments) because 'posonlyargs' and 'args' must be supplied in a different order than the ordering of elements in 'defaults' would imply.

Potential solutions:
 1. Swap posonlyargs and args.
 2. Add a separate pos_defaults list.
Date User Action Args
2019-07-14 18:55:37Benjamin.S.Wolfsetrecipients: + Benjamin.S.Wolf
2019-07-14 18:55:37Benjamin.S.Wolfsetmessageid: <>
2019-07-14 18:55:37Benjamin.S.Wolflinkissue37593 messages
2019-07-14 18:55:36Benjamin.S.Wolfcreate