[Python-Dev] TypeError: f() missing 1 required positional argument: 'x'

Terry Reedy tjreedy at udel.edu
Thu Sep 20 17:57:10 CEST 2012

On 9/20/2012 7:56 AM, Mark Dickinson wrote:
> I suspect I've missed the boat on this one (certainly for 3.3.0), but
> here goes.  The new TypeError reporting for bad function calls is a
> huge improvement (thanks Benjamin!), but I have one small nitpick:
> what *is* a positional argument?  For example:
>      >>> def f(x): pass
>      ...
>      >>> f()
>      Traceback (most recent call last):
>        File "<stdin>", line 1, in <module>
>      TypeError: f() missing 1 required positional argument: 'x'
> I think it's confusing to describe 'x' as a positional argument.  It's
> a required formal parameter, certainly.  But a caller of 'f' could
> pass 'x' either by position or by 'keyword'.
> When running training (generally Python 2.6 or 2.7 based), I
> frequently have to devote some time to unravelling student confusion
> between 'arguments passed by keyword' on one hand and 'optional formal
> parameters' on the other.  The outline of the explanation goes
> something like:
> (0) Preamble: be careful to separate out details of function calling
> from those of function definition; distinguish formal parameters from
> actual arguments.
> (1) On the function *definition* side, formal parameters may be either
> *required* or *optional*.

and optional params may or may not have an overt default object

> (2) On the function *calling* side, actual arguments may be passed
> either positionally or by keyword.

Sometimes position is required, sometimes keyword is required, and 
usually both are allowed.

> (3) The notions in (1) and (2) are entirely orthogonal!

Moreover, all six combinations of passing mode and requirement are 
possible, although for Python functions, some combinations require setup 
code in addition to the header. Built-in print accepts an indefinite 
number of optional no-default position-only args followed by up to three 
optional defaulted keyword-only args. print() emits the default end='\n'.

> (3a) (Although in practice, callers tend to use pass-by-keyword for
> optional formal parameters.)
> That's all for Python 2;  Python 3, of course, requires a bit more
> explanation related to the keyword-only arguments.
> There already seems to be a fair amount of confusion in the Python
> world about point (3);

I have strongly suggested that the docs not adds to the confusion in at 
least one tracker discussion.

>  I've seen professional Python training slides
> that show how to define optional formal parameters under the heading
> "keyword arguments".
> I submit that the word 'positional' in the TypeError message
> exacerbates this confusion, and that little would be lost by simply
> dropping it from the exception message.

For this example that would be sufficient, but your later message shows 
that we need a one-word abbreviations for positional-or-keyword: either 
something indicating that its default nature -- 'normal', 'standard', 
'flexible', 'usual', 'typical' -- or something indicating its dual 
nature (possibly coined or metaphorical -- 'pos-key', 'bi-mode', 
'dual-mode', 'Janus-like'.

Terry Jan Reedy

More information about the Python-Dev mailing list