[Python-3000] Cleaning up argument list parsing (was Re: More wishful thinking)

Nick Coghlan ncoghlan at gmail.com
Wed Apr 19 12:59:44 CEST 2006


Steven Bethard wrote:

> -------------------------
> UserDict.DictMixin.update
> -------------------------
...
> To clean this up, we'd need the ability to identify self and dict as
> positional only arguments.  AFAICT, the current proposal doesn't solve
> this problem.  Off the top of my head, I don't see an easy way of
> supporting this either...

One way would be to expand assignment to support positional argument to 
parameter matching when the sequence on the left is parenthesised:

   def __init__(*args, **kwargs):
       (self, other=None) = args
       ...

The signature info would still be lacking details on self & other, but the 
kwarg conflict would be addressed.

Taking this idea one step further, the info could be moved back into the 
signature by doing:

   def __init__(*(self, other=None), **kwargs):
       ...

Which actually suggests an alternate approach for keyword-only arguments: 
permitting argument expansion in a tuple after the **.

Then you'd have:

   def f(a, *(b, c=1, *args), **(d, e=2, **kwds)):
       # Silly function

'a' would be a normal positional-or-keyword argument
'b' would be a required positional-only argument
'c' would be an optional 3rd positional-only argument
'args' would contain any positional arguments after the 3rd
'd' would be a required keyword-only argument
'e' would be an optional keyword-only argument
'kwds' would contain any keyword arguments other than 'a', 'd' or 'e'

> ----------------------
> UserDict.DictMixin.pop
> ----------------------
...
> you still wouldn't know if "default" was None from the default in the
> signature or because the value None was supplied by the caller.

Making this distinction is where sentinel objects and identity tests are handy:

     _pop_sentinel = object()
     def pop(self, key, default=_pop_sentinel):
         try:
             value = self[key]
         except KeyError:
             if default is not self._pop_sentinel:
                 return default
             raise
         del self[key]
         return value

(IOW, this can be made simpler without touching Python's syntax)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://www.boredomandlaziness.org


More information about the Python-3000 mailing list