I also use the approach of @pf_moore
The original proposal works better with type checking though.
I’m not sure how is easily to extend the current Python grammar.
I know @guido and @pablogsal work on PEG parser, maybe it allows to implement the proposal much simpler.
Your suggested solution starts to remove the explicitness of the link between the function call and its arguments, as x= and y= are already 5 lines away from the function call. This can get out of hand for functions (that are out of my control) with many parameters, even getting off-screen. In my work, I encounter this problem almost daily, and the solution I employ is to create multiple different functions with smaller signatures which call the original function with different pre-filled arguments
My general pattern here is
kwargs = {}
if timeout: kwargs[‘timeout’] = timeout
if max_arg: args[‘max_age’] = max_age
foo(x=yada.yada.yada, z=yada.yada.yada, **kwargs)
that is - only the extra optional args get the special But you can also do:
foo(x=yada.yada.yada, z=yada.yada.yada,
timeout=timeout if timeout else None,
max_age=max_age if max_age else None)
(replace None with whatever sentinel value foo uses for not-supplied-parameters).
If foo really detects actually-passed vs passed-with-some-value, then thats perhaps a thing to change. Because using None as a sentinel allows that last example to collapse down to:
foo(x=yada.yada.yada, z=yada.yada.yada,
timeout=timeout,
max_age=max_age)
and still be semantically sensible.