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

Steven Bethard steven.bethard at gmail.com
Mon Apr 17 18:36:21 CEST 2006


[Talin]
> 1) I don't know if this is already on the table, but I sure would like
> to be able to have more options as far as mixing positional and
> keyword arguments.

I thought it might be useful to look at a few places where we
currently have to do some hackery to get the function signature we
want.  I believe the first of these can be solved by the proposed
change.  I'm not sure if anything can (or should) be done about the
latter two.


------------------------------------------------------------------------
min/max (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/389659)
------------------------------------------------------------------------

::

    def __call__(self, *seq, **kwargs):
        key = kwargs.pop('key', None)
        if kwargs:
            raise TypeError("only 'key' accepted as a "
                            "keyword argument")
        ...

I believe this is straightforwardly cleaned up by the current proposal
by making key a keyword only argument::

    def __call__(self, *seq, key=None):
        ...


-------------------------
UserDict.DictMixin.update
-------------------------

::

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

this is actually wrong, since you can't create a dict like
``dict(self='foo', other='bar')``.  It needs to be written as::

    def __init__(*args, **kwargs):
        if len(args) == 1:
            self, = args
            other = None
        else:
            self, other = args
        ...

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...


----------------------
UserDict.DictMixin.pop
----------------------

::

    def pop(self, key, *args):
        if len(args) > 1:
            raise TypeError, "pop expected at most 2 arguments, got "\
                              + repr(1 + len(args))
        try:
            value = self[key]
        except KeyError:
            if args:
                return args[0]
            raise
        del self[key]
        return value

Here, you *have* to know how many arguments were supplied because an
exception must be raised if there were 2 and not if there were three. 
And even if you could define "default" as a keyword-only argument,
e.g.::

    def pop(self, key, *args, default=None):

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.


STeVe
--
Grammar am for people who can't think for myself.
        --- Bucky Katt, Get Fuzzy


More information about the Python-3000 mailing list