classification
Title: ast.arguments has confusing args/posonlyargs ordering
Type: behavior Stage: resolved
Components: Versions: Python 3.8
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Benjamin.S.Wolf, levkivskyi, mdulaney, miss-islington, pablogsal, serhiy.storchaka
Priority: normal Keywords: patch

Created on 2019-07-14 18:55 by Benjamin.S.Wolf, last changed 2019-08-16 19:56 by mdulaney. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 14778 merged pablogsal, 2019-07-14 23:00
PR 14779 merged miss-islington, 2019-07-14 23:32
Messages (5)
msg347932 - (view) Author: Benjamin S Wolf (Benjamin.S.Wolf) Date: 2019-07-14 18:55
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)
"arguments(
    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.
msg347945 - (view) Author: miss-islington (miss-islington) Date: 2019-07-14 23:32
New changeset cd6e83b4810549c308ab2d7315dbab526e35ccf6 by Miss Islington (bot) (Pablo Galindo) in branch 'master':
bpo-37593: Swap the positions of posonlyargs and args in the constructor of ast.parameters nodes (GH-14778)
https://github.com/python/cpython/commit/cd6e83b4810549c308ab2d7315dbab526e35ccf6
msg347946 - (view) Author: miss-islington (miss-islington) Date: 2019-07-14 23:49
New changeset cf9a63c6c7e19f3d27cf3b5731d02cc216ef3dd1 by Miss Islington (bot) in branch '3.8':
bpo-37593: Swap the positions of posonlyargs and args in the constructor of ast.parameters nodes (GH-14778)
https://github.com/python/cpython/commit/cf9a63c6c7e19f3d27cf3b5731d02cc216ef3dd1
msg347947 - (view) Author: Pablo Galindo Salgado (pablogsal) * (Python committer) Date: 2019-07-15 00:08
Thanks for the report, Benjamin!
msg349883 - (view) Author: Mairi Dulaney (mdulaney) Date: 2019-08-16 19:56
The patch that was merged to fix this may have caused a regresion in xonsh.  Am working on a reproducer.
History
Date User Action Args
2019-08-16 19:56:37mdulaneysetnosy: + mdulaney
messages: + msg349883
2019-07-15 00:08:34pablogsalsetstatus: open -> closed
resolution: fixed
messages: + msg347947

stage: patch review -> resolved
2019-07-14 23:49:55miss-islingtonsetmessages: + msg347946
2019-07-14 23:32:34miss-islingtonsetpull_requests: + pull_request14575
2019-07-14 23:32:21miss-islingtonsetnosy: + miss-islington
messages: + msg347945
2019-07-14 23:00:47pablogsalsetkeywords: + patch
stage: patch review
pull_requests: + pull_request14574
2019-07-14 20:25:43xtreaksetnosy: + serhiy.storchaka, levkivskyi, pablogsal
2019-07-14 18:55:37Benjamin.S.Wolfcreate