# PEP 736: Shorthand syntax for keyword arguments at invocation

**URL:** <https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432>\
**Category:** PEPs\
**Created:** [January 17, 2024, 2:11pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432 "2024-01-17T14:11:03Z")\
**Posts on this page:** 20\
**Page:** 6

<div class="post-metadata">

**Author:** ![pitrou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pitrou/32/28_2.png) [@pitrou](https://discuss.python.org/u/pitrou)\
**Post date:** [January 24, 2024, 9:38am UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/103 "2024-01-24T09:38:43Z")

</div>

> [@chepner](#):
>
> I don’t want to restart any debate on the proposed syntax, only note that the lone keyword-based syntax that appeared in the poll (`f(pass x)`) isn’t mentioned in the “Rejected Ideas” section.

If there are 10 named arguments to forward that way, you’d add 10 times the same lone keyword in the function invocation?

---

<div class="post-metadata">

**Author:** ![alexmojaki](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/alexmojaki/32/14755_2.png) [@alexmojaki](https://discuss.python.org/u/alexmojaki)\
**Post date:** [January 24, 2024, 10:12am UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/104 "2024-01-24T10:12:43Z")

</div>

Here’s an anecdote. Last night I was looking at this code from a library:

```python
def instrument_app(
    app: fastapi.FastAPI,
    server_request_hook: _ServerRequestHookT = None,
    client_request_hook: _ClientRequestHookT = None,
    client_response_hook: _ClientResponseHookT = None,
    tracer_provider=None,
    meter_provider=None,
    excluded_urls=None,
):
    ...
    if excluded_urls is None:
        excluded_urls = _excluded_urls_from_env
    else:
        excluded_urls = parse_excluded_urls(excluded_urls)
    meter = get_meter(
        __name__ ,
        __version__ ,
        meter_provider,
        schema_url='https://opentelemetry.io/schemas/1.11.0',
    )
    app.add_middleware(
        OpenTelemetryMiddleware,
        excluded_urls=excluded_urls,
        default_span_details=_get_default_span_details,
        server_request_hook=server_request_hook,
        client_request_hook=client_request_hook,
        client_response_hook=client_response_hook,
        tracer_provider=tracer_provider,
        meter=meter,
    )

```

You don’t have to understand it. Just know that as I was reading this I _thought_ that I was seeing basically all the code that I cared about. I didn’t care what exactly `parse_excluded_urls` or `get_meter` did. So I thought that this was doing little more than passing the arguments of `instrument_app` to `app.add_middleware`.

This was surprising to me, as I had reason to expect more. I pointed this out to coworkers, and one helpfully showed me what I was missing.

This morning I discovered this PEP. And I thought back to last night and realised that if the code was written with this shorthand, I would have immediately seen what was previously more like a needle in a haystack:

```python
    app.add_middleware(
        OpenTelemetryMiddleware,
        excluded_urls=,
        default_span_details=_get_default_span_details,
        server_request_hook=,
        client_request_hook=,
        client_response_hook=,
        tracer_provider=,
        meter=,
    )

```

`_get_default_span_details` contained the extra information that I was looking for.

More generally, I think this shorthand achieves what I consider a common benefit of keeping code DRY: when you remove duplication, important differences become more visible.

---

<div class="post-metadata">

**Author:** ![Jacob-Stevens-Haas](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jacob-stevens-haas/32/3998_2.png) [@Jacob-Stevens-Haas](https://discuss.python.org/u/Jacob-Stevens-Haas)\
**Post date:** [January 24, 2024, 11:46am UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/105 "2024-01-24T11:46:53Z")

</div>

That’s cool to see, and was the main takeaway I got from [the article](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/97) @boxed posted.

OTOH, one of the more convincing (to me) counterarguments is that it “discourages context-appropriate variable names”, as @pf_moore mentioned above. To see how that would apply to OpenTelemetry’s API I would have to understand it better, but for starters the name `_get_default_span_details` suggests a callable, and `default_span_details` suggests a container of some sort. If instead the line were:

```python
default_span_details=_get_default_span_details()

```

it seems probable that you would have spotted it’s uniqueness without the PEP 736 syntax. If, on the other hand, OpenTelemetry called the variable `default_span_details`, the needle would remain buried, as the PEP736 syntax would elide it just like the other variables.

---

<div class="post-metadata">

**Author:** ![elis.byberi](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/elis.byberi/32/35937_2.png) [@elis.byberi](https://discuss.python.org/u/elis.byberi)\
**Post date:** [January 24, 2024, 11:56am UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/106 "2024-01-24T11:56:44Z")

</div>

> [@Jacob-Stevens-Haas](#):
>
> If, on the other hand, OpenTelemetry called the variable `default_span_details`

That is pretty expected after the acceptance of PEP 736. They will rename it.

---

<div class="post-metadata">

**Author:** ![boxed](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/boxed/32/5966_2.png) [@boxed](https://discuss.python.org/u/boxed)\
**Post date:** [January 24, 2024, 12:03pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/107 "2024-01-24T12:03:42Z")

</div>

> If instead the line were:  
> `default_span_details=_get_default_span_details()`  
> it seems probable that you would have spotted it’s uniqueness without the PEP 736 syntax

I don’t see how this would make much difference:

```py
app.add_middleware(
        OpenTelemetryMiddleware,
        excluded_urls=excluded_urls,
        default_span_details=_get_default_span_details(),
        server_request_hook=server_request_hook,
        client_request_hook=client_request_hook,
        client_response_hook=client_response_hook,
        tracer_provider=tracer_provider,
        meter=meter,
    )

```

This seems just as easy to overlook as before to me. Maybe it’s better if your syntax highlighting makes `()` have very different colors, but that seems very specific to this case anyway.

---

<div class="post-metadata">

**Author:** ![ajoino](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ajoino/32/6907_2.png) [@ajoino](https://discuss.python.org/u/ajoino)\
**Post date:** [January 24, 2024, 12:49pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/108 "2024-01-24T12:49:37Z")

</div>

Assuming that PEP 736 would capture variables in all scopes, both the old style and new style would be completely equivalent (unless there’s something I’ve completely missed.)

```python
func(
    foo=foo,
    bar=bar,
)
# Equivalent to
func(
    foo=,
    bar=,
)

```

Now we have two ways to create the same thing, and it’s seemingly a stylistic\[1\] choice whether one is better than the other. That means there’s another thing for developers to argue about. While that in and of itself is not an argument against the PEP, I think the PEP should also include a change to PEP 8 to make one of these choices the preferred style. That would reduce the amount of argument, both IRL and in various projects’ issue trackers.

* * *

1. For a quick and dirty script it might not just be a stylistic but an ergonomic choice as well.

---

<div class="post-metadata">

**Author:** ![effigies](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/effigies/32/35835_2.png) [@effigies](https://discuss.python.org/u/effigies)\
**Post date:** [January 24, 2024, 1:40pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/109 "2024-01-24T13:40:44Z")

</div>

> [@ajoino](#):
>
> I think the PEP should also include a change to PEP 8 to make one of these choices the preferred style

I disagree. I suspect I would use the style once my minimum Python hit a supporting version, but I would really rather not add the weight of PEP8 (which is frequently misapplied) behind it. I’m sure there’ll be a flake8 plugin and ruff support, which should be enough. If projects want to consistently use/avoid it, they can set that policy in their linter/formatter config.

---

<div class="post-metadata">

**Author:** ![Jacob-Stevens-Haas](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jacob-stevens-haas/32/3998_2.png) [@Jacob-Stevens-Haas](https://discuss.python.org/u/Jacob-Stevens-Haas)\
**Post date:** [January 24, 2024, 2:28pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/110 "2024-01-24T14:28:39Z")

</div>

That’s fair. My point is that examples like this show when eliding a kwarg illuminates an important name. We should also consider whether the API could’ve used more context-appropriate names in the first place, and how PEP-736 would look with those names.

In this case, it seems like the function does have more context on `meter` and `excluded_urls` (and maybe more, depending upon what’s in the …), which could use a more context-appropriate name. This is a case where the poster’s missing context was only missed because it came from the global scope, and only stood out so much in PEP 736 because the `add_instrument` didn’t use a more context-appropriate name for `meter` and `excluded_urls`. Maybe this is the appropriate comparison?

```python
app.add_middleware(
        OpenTelemetryMiddleware,
        excluded_urls=parsed_exclusions,
        default_span_details=_get_default_span_details,
        server_request_hook=,
        client_request_hook=,
        client_response_hook=,
        tracer_provider=,
        meter=instrument_meter,
    )

```

…which still stands out. So the more I think about this example, the more I agree with it’s author. Wrappers and factories like `instrument_app()` will usually only have more context for some subset of the arguments they pass along, which are exactly the arguments that would stand out if the others are elided.

So to paraphrase the author, the PEP makes important differences become more visible _so long as the important differences are given different names_.

---

<div class="post-metadata">

**Author:** ![chepner](https://avatars.discourse-cdn.com/v4/letter/c/22d042/32.png) [@chepner](https://discuss.python.org/u/chepner)\
**Post date:** [January 24, 2024, 2:39pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/111 "2024-01-24T14:39:43Z")

</div>

No, but it was mentioned in the discussion thread, and I think it should be mentioned along with the other rejected forms in the PEP. (Plus, I did mention that Nix allows `{inherit x y; ...}` instead of `{inherit x; inherit y; ...}`, and I would recommend the same in Python if I were advocating for it.)

---

<div class="post-metadata">

**Author:** ![sirosen](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/sirosen/32/8478_2.png) [@sirosen](https://discuss.python.org/u/sirosen)\
**Post date:** [January 24, 2024, 2:47pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/112 "2024-01-24T14:47:23Z")

</div>

I posted more extensively about this in the other thread, but I really hope linters don’t pick this up and start pushing it. There are reasons to avoid configuring linting tools to have non-default behavior, in that it helps you keep disparate codebases uniform.

Rubocop enforces this style for Ruby, which results in this being applied in lots of trivial cases which you could argue are not harmed but are certainly not helped by the change. A lot of

```ruby
foo(x: bar, y:)

```

To me, the end result is non-uniformity of style within a codebase, and sometimes within a single call site, for no beneficial purpose in many cases. (To clarify, I’m not saying that supporting this feature has no benefit, but rather that linter enforcement is not providing any benefit in many cases.)

So Rubocop “forces” me to write in this way, even though I’d rather not. I hope not to have the same experience with Python linters.

* * *

Regarding the above example of this revealing the intent of an otherwise obscure parameter in a long list of passthroughs, I have two thoughts.

One is that the syntax itself helps highlight the difference, as noted.

The other is that this seems like a case in which a judiciously placed comment could also have helped.

---

<div class="post-metadata">

**Author:** ![jamestwebber](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jamestwebber/32/12799_2.png) [@jamestwebber](https://discuss.python.org/u/jamestwebber)\
**Post date:** [January 24, 2024, 2:57pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/113 "2024-01-24T14:57:23Z")

</div>

> [@alexmojaki](#):
>
> `_get_default_span_details` contained the extra information that I was looking for.

It seems like the more important detail in this code is `meter`, which is _de-emphasized_ in the new version. That’s the non-default argument that’s being added by this function, right?

Maybe that wasn’t relevant to you in the specific case you were debugging, but I would think it’s the primary reason for this method.

---

<div class="post-metadata">

**Author:** ![ajoino](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ajoino/32/6907_2.png) [@ajoino](https://discuss.python.org/u/ajoino)\
**Post date:** [January 24, 2024, 2:58pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/114 "2024-01-24T14:58:44Z")

</div>

I think the end result is going to be that linters and autoformatters pick this up eventually, which is why I think it’s better to add it to PEP 8 immediately to reduce the amount of discussion around this topic. But I see that many disagree.

To me, the PEP is about adding an additional style of function call, and I think it’s not great to add a new style unless it’s not the one being pushed as correct style.

---

<div class="post-metadata">

**Author:** ![jamestwebber](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jamestwebber/32/12799_2.png) [@jamestwebber](https://discuss.python.org/u/jamestwebber)\
**Post date:** [January 24, 2024, 3:08pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/115 "2024-01-24T15:08:58Z")

</div>

> [@ajoino](#):
>
> I think the end result is going to be that linters and autoformatters pick this up eventually, which is why I think it’s better to add it to PEP 8 immediately to reduce the amount of discussion around this topic. But I see that many disagree.

But PEP 8 is not a general style guide, it’s a style guide for the stdlib itself. Popular formatting tools do not follow PEP 8.

It only makes sense to add it there if the core developers want to adopt this style in future code.

---

<div class="post-metadata">

**Author:** ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)\
**Post date:** [January 24, 2024, 3:47pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/116 "2024-01-24T15:47:30Z")

</div>

> [@jamestwebber](#):
>
> But PEP 8 is not a general style guide, it’s a style guide for the stdlib itself. Popular formatting tools do not follow PEP 8.

Precisely. We’ll add it into our style guide when we need it (and more likely than not, it’ll start off with “don’t change existing uses to use the new style”, which is probably not what you want to be suggesting in the PEP proposing the feature).

It’s fine to have a section of recommendations for linters/formatters though. PEP 8 isn’t that, but PEP 736 can be for this feature.

---

<div class="post-metadata">

**Author:** ![ajoino](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ajoino/32/6907_2.png) [@ajoino](https://discuss.python.org/u/ajoino)\
**Post date:** [January 24, 2024, 3:50pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/117 "2024-01-24T15:50:42Z")

</div>

A recommendation in the PEP would satisfy me.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [January 24, 2024, 4:23pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/118 "2024-01-24T16:23:52Z")

</div>

A recommendation in the PEP that linters explicitly _don’t_ enforce this style over the traditional form would satisfy me.

(To make the point in a more balanced way, I think there are opinions on both sides, and the PEP should either take no stance on linters, or should explicitly note that there is no consensus and therefore linters should not prefer one form over the other).

---

<div class="post-metadata">

**Author:** ![effigies](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/effigies/32/35835_2.png) [@effigies](https://discuss.python.org/u/effigies)\
**Post date:** [January 24, 2024, 4:34pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/119 "2024-01-24T16:34:41Z")

</div>

I would be curious to hear from a black maintainer about how they would view this PEP as written. Would it be ignored, so long as it is possible to preserve whether the value was present, or would it be in the spirit of black to pick one and just enforce it? Would the inclusion of recommendations for linters/formatters in the PEP text have any effect on that decision?

---

<div class="post-metadata">

**Author:** ![Jelle](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/jelle/32/1049_2.png) [@Jelle](https://discuss.python.org/u/Jelle)\
**Post date:** [January 24, 2024, 4:37pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/120 "2024-01-24T16:37:24Z")

</div>

I am a maintainer of Black. I would want Black to enforce PEP 736 style where possible.

That means I disagree with @pf_moore just above. If we don’t think that linters should recommend PEP 736 style, then I don’t see why we’d add the feature to the language.

---

<div class="post-metadata">

**Author:** ![steve.dower](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/steve.dower/32/56_2.png) [@steve.dower](https://discuss.python.org/u/steve.dower)\
**Post date:** [January 24, 2024, 4:46pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/121 "2024-01-24T16:46:37Z")

</div>

To be clear, “recommend PEP 736 style” means “we will delete code that the user wrote”?

I read Paul’s preference as “correctly format both `x=x` and `x=`, but don’t change one to the other”, which seems reasonable to me.

Until refactoring tools are able to correctly handle a `x=` in the case where you either rename the `x` parameter or the `x` local (which obviously doesn’t rename both simultaneously), automatically deleting the variable in `x=x` feels likely to be more inconvenient than anything else.

---

<div class="post-metadata">

**Author:** ![pf\_moore](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/pf_moore/32/35_2.png) [@pf\_moore](https://discuss.python.org/u/pf_moore)\
**Post date:** [January 24, 2024, 5:30pm UTC](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432/122 "2024-01-24T17:30:57Z")

</div>

> [@steve.dower](#):
>
> I read Paul’s preference as “correctly format both `x=x` and `x=`, but don’t change one to the other”, which seems reasonable to me.

Precisely. If black (or any other formatter) rewrote `x=x` as `x=`, I would do one of the following on any project I maintain:

1. Stop using that formatter.
2. Disable that rewrite rule, if the formatter gives me a way of doing so.
3. Put `# fmt: off` around all function calls that might be affected.
4. Make it a requirement that when passing a variable to a keyword argument, the variable _must_ always have a different name than the keyword, to prevent this behaviour.

Of these, only (1) and (2) seem like they would be feasible in practice.

[Previous page](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432.md?page=5)

[Next page](https://discuss.python.org/t/pep-736-shorthand-syntax-for-keyword-arguments-at-invocation/43432.md?page=7)
