Should we define terms like `dunder` or `**kwargs` in the docs?

I’m reviewing PEP 692, which uses **kwargs quite liberally, and I realized there’s no place that says what a kwargs is. Or a dunder, for that matter.
It seems that the status quo is that we don’t put slang/jargon in the Glossary (see e.g. #84226). But if a terms gets used in PEPs without anyone batting an eye, I think we ought to define it somewhere, regardless of whether we consider it informal.

9 Likes

If we do, we should also add “walrus”.

8 Likes

Looking through the glossary (and the definition of “jargon”), “don’t include jargon in the glossary” seems like an indefensible position. Considering how widely used these terms are and that they are unambiguously defined, I see no reason not to include them in the glossary. I would also suggest *args to go along with **kwargs.

7 Likes

+1. Defining language-specific (but not obvious) terms would make discussion more accessible to those new to Python.

6 Likes
3 Likes

“dunder” for sure should be defined (I didn’t like the term originally, but there’s no denying its convenience and ubiquity).

“kwargs” I’m less certain of. Isn’t there more variability here? **kwargs isn’t a required spelling, and I’ve see **kw and probably others in use.

I tend to use **kwds but I seem to be unique in this spelling (which I like because it’s the same number of letters as in *args). I think kwargs has emerged as the common spelling, so it might as well be canonized. And it’s nicely pronounceable.

2 Likes

It’s true that we see and use many spellings for the variable name, from kwargs to kw to params to extra, but I think there’s an unofficial name for the concept of keyword arguments packed into / unpacked from a dict, aka varkwargs (similar to varargs).

Looking for a precedent, I found keywords and varkw in inspect: inspect — Inspect live objects — Python 3.10.7 documentation (varkw in the method following that one linked here)

I use that too. I’m sure I picked it up from you ages ago.

In my head, I know them as variadic keyword arguments, shortened to kwargs for speech and spelling. I noticed variadic arguments aren’t in the glossary at all, I guess because they’re really only important in the documentation for the syntax and inspect.signature.

2 Likes

The definition (or whatever other docs it links to) should definitely be clear that kwargs is not a required name, just a colloquial name for the concept.

2 Likes

I see no problem with including **kwargs as “the common placeholder” keyword arguments etc, with the clarification that it is absolutely not required, even if it is often use as a convention, and that it is not an Official Python Convention etc.

This is one of those situations where it would be helpful to include what might be called very commonly used terms, even while being careful to say they’re not universal or official in any way.

Does **args1, 1**kwargs or dunder ever appear in a PEP, or draft PEP? If so it seems fair to include them, with appropriate provisos and disclaimers.

Indeed, treating *args and **kwargs roughly the same way as self would easiest. Python doesn’t care, but people asking “What does **kwargs mean?” do.
Of course, there are more opportunities for better names (*initial_items, **plot_settings) here than with self (which gets different names in metaclasses or descriptors, but that’s about it).

I don’t think there are common alternatives to *args*varargs seems most common, but feels outdated.

Yeah, but things added in 3.3+ (Signature/Parameter/BoundArguments) use kwargs exclusively (mainly just in the docs text, only BoundArguments.kwargs is actual API.)
So it still sounds reasonable to say that the collective brainstorming is over, and **kwargs won.

3 Likes

ParamSpec.kwargs too typing — Support for type hints — Python 3.12.1 documentation

1 Like

Yes, searching the PEPs repo (e.g. git grep "\*args" pep-* | wc -l):

grep pattern matching lines
\*args 364
\*\*kwargs 265
\bargs\b 588
\bkwargs\b 386
\bdunder\b 42
2 Likes

Perhaps of interest to note that the documentation of the Data model uses the more explicit terms *arguments and **keywords at least here:

https://docs/python.org/3/reference/datamodel.html#the-standard-type-heirarchy under Internal types / Code objects

(I ran across this just now in a search entirely unrelated to the question here)

Docs: Internal types - Code objects https://docs.python.org/3/reference/datamodel.html#the-standard-type-heirarchy

Oh no, there’s a typo in the label. :frowning:

(Sadly or confusingly) It’s not the kwargs (args, kw, kwds) which is important, but the ** (or *) prefix to the chosen identifier.
Similar to many assuming (“tuple”) where it is in-fact a trailing comma or comma-separated list of identifiers which is the relevant construction.
In some ways, it is a shame that we can’t use * and ** “bare” (as it says in the exception-message), in the same manner as _ for ‘identifier which am too tired to name’ - sorry, the facility formally-known as “wildcard”.
Yes, overload-itis, but am wondering if the ‘new’ parser might better cope with such?
Regards =dn

In python/cpython#87780 where this was discussed (particularly in the context of users searching for these terms), it was mentioned that we already have index entries for the terms var-positional and var-keyword, so it would be ideal if searches for args and kwargs brought up those entries. Until then, Sphinx didn’t actually use index entries in search results at all, but in response to our discussion and request, @AA-Turner implemented it for Sphinx 5.2.0. As such, index entries can be fairly easily added for args and kwargs (etc.) alongside the more uncommon terms, and should appear when users search.

However, it still isn’t possible to actually cross-reference/directly link to an index entry, nor does it give a concise definition of the term itself (with a link to a more detailed reference) so while this mostly solves the search issue, a glossary entry is still very helpful in being able to easily define a term with minimal additional effort.

Therefore, I also still believe a glossary entry would be helpful. Here’s my current proposal for how to handle this.

In fact, now that we added Intersphinx support to the PEPs repo, if we include it in the (or at least a) glossary in the CPython docs, PEP authors will be able to do :term:`kwargs` in PEPs and it will automatically link to the definition.

It would be sadder and more confusing for readers of well-written code if it wasn’t, though, as it allows using much more descriptive and contextually-appropriate parameter names.

The much more common and troublesome problem I see, for both novice and experienced programmers (including myself), is a stray comma getting left somewhere (particularly at the top-level of a nested dict) and causing the result to be interpreted as a tuple; I rarely see the opposite, and when I have it is usually quickly resolved. But, that’s neither here nor there.

This topic is about documenting existing functionality, if you have a proposal for new syntax, please make it under the Ideas category. To note, * is already used to signal any following parameters are keyword-only, and you should be able to simply do *_ and/or **__ to achieve what you’re asking for (and _/__, unlike * and ** you propose, is convention, not syntax), so it seems rather unlikely that new syntax would be justified here.