[Python-ideas] Keyword for direct pass through of kwargs to super

Steven D'Aprano steve at pearwood.info
Sat May 26 00:16:49 EDT 2018


On Sat, May 26, 2018 at 02:06:40AM +0200, Michael Lohmann wrote:

> I propose to add some mechanism that can automatically collect everything
> what would normally be collected by **kwargs in the __init__ method and
> directly pass it through to the super().__init__ call without being
> accessible in the __init__ itself. This way the autocompletion/docstring
> generation could safely ignore this argument which before would have showed
> up as **kwargs.

Why is this an advantage? Consider the following scenario: you are 
reading an unfamiliar code base and come across a class instantiation:

    obj = Aardvark(27, spam=3, eggs=5, cheese=True)

So you look up help(Aardvark), and it tells you that the signature is

    Aardvark.__init__(self, foo)

What the hell? If Aardvark.__init__ only takes a single argument (aside 
from self), why on earth isn't it an error to pass those keyword 
arguments?

If you're a beginner, this is probably going to be a mind-melting 
WTF-I-don't-even moment.

And even if you're *not* a beginner, it will probably cause a momentary 
sense of existential dread as, for a moment, everything you thought you 
understood about Python seems wrong. And then you remember that there's 
an obscure feature that tells the class to lie to you about what 
parameters it takes.

It is bad enough when a method collects a bunch of parameters under 
**kwargs and I have to pour through the documentation for all its super 
classes to work out what they are. But at least the use of an explicit 
**kwargs gives me a clue that this is what is going on.

Making **kwargs implicit and invisible reminds me of the old saying 
about coding for maintenance. To paraphrase:

    Design language features as if your language's users -- all of
    them -- are violent psychopaths who know where you live.


[...]
> With the current python version the code would have looked like
> 
>     class A:
>         def __init__(self, a_value, **kwargs):
>             super().__init__(**kwargs)
> 
> But the user could have had the false impression that additional kwargs
> could be given when instantiating A.

But they *can* be given when instantiating A. What makes you think they 
can't be?


> Obviously they are purely there for
> getting the init in the MRO working with multiple inheritance.

That's not always true. Even if it were true, it isn't obviously true.



-- 
Steve


More information about the Python-ideas mailing list