[Python-Dev] Special-casing "O"
M.-A. Lemburg
mal@lemburg.com
Mon, 28 May 2001 11:19:16 +0200
Tim Peters wrote:
>
> [Thomas Wouters]
> > And don't forget the method-specific errormessage by passing ':len' in
> > the format string. Of course, this can easily be (and probably should)
> > done by passing another argument to whatever parses arguments in
> > METH_O, rather than invoking string parsing magic every call.
>
> Martin's patch automatically inserts the name of the function in the
> TypeError it raises when a METH_O call doesn't get exactly one argument, or
> gets a (one or more) keyword argument.
>
> Stick to METH_O and it's a clear win, even in this respect: there's no info
> in an explicit ":len" he's not already deducing, and almost all instances of
> "O:name" formats today are exactly the same this way:
>
> if (!PyArg_ParseTuple(args, "O:abs", &v))
> if (!PyArg_ParseTuple(args, "O:callable", &v))
> if (!PyArg_ParseTuple(args, "O:id", &v))
> if (!PyArg_ParseTuple(args, "O:hash", &v))
> if (!PyArg_ParseTuple(args, "O:hex", &v))
> if (!PyArg_ParseTuple(args, "O:float", &v))
> if (!PyArg_ParseTuple(args, "O:len", &v))
> if (!PyArg_ParseTuple(args, "O:list", &v))
> else if (!PyArg_ParseTuple(args, "O:min/max", &v))
> if (!PyArg_ParseTuple(args, "O:oct", &v))
> if (!PyArg_ParseTuple(args, "O:ord", &obj))
> if (!PyArg_ParseTuple(args, "O:reload", &v))
> if (!PyArg_ParseTuple(args, "O:repr", &v))
> if (!PyArg_ParseTuple(args, "O:str", &v))
> if (!PyArg_ParseTuple(args, "O:tuple", &v))
> if (!PyArg_ParseTuple(args, "O:type", &v))
>
> Those are all the ones in bltinmodule.c, and nearly all of them are called
> extremely frequently in *some* programs. The only oddball is min/max, but
> then it supports more than one call-list format and so isn't a METH_O
> candidate anyway. Indeed, Martin's patch gives a *better* message than we
> get for some mistakes today:
>
> >>> len(val=2)
> Yraceback (most recent call last):
> File "<stdin>", line 1, in ?
> TypeError: len() takes exactly 1 argument (0 given)
> >>>
>
> Martin's would say
>
> TypeError: len takes no keyword arguments
>
> in this case. He should add "()" after the function name. He should also
> throw away the half of the patch complicating and slowing METH_O to get some
> theoretical speedup in other cases: make the one-arg builtins fly just as
> fast as humanly possible.
If we end up only optimizing the re.match("O+") case, we wouldn't need
the METH_SPECIAL masks; a simple METH_OBJARGS flag would do the trick
and Martin could call the underlying API with one or more PyObject*
taken directly from the Python VM stack.
In that case, please consider at least supporting "O", "OO" and "OOO"
with optional arguments treated like I suggested in an earlier
posting (simply pass NULL and let the API take care of assigning
a default value).
This would take care of most builtins:
Python/bltinmodule.c:
-- if (!PyArg_ParseTuple(args, "OO:filter", &func, &seq))
-- if (!PyArg_ParseTuple(args, "OO:cmp", &a, &b))
-- if (!PyArg_ParseTuple(args, "OO:coerce", &v, &w))
-- if (!PyArg_ParseTuple(args, "OO:divmod", &v, &w))
-- if (!PyArg_ParseTuple(args, "OO|O:getattr", &v, &name, &dflt))
-- if (!PyArg_ParseTuple(args, "OO:hasattr", &v, &name))
-- if (!PyArg_ParseTuple(args, "OOO:setattr", &v, &name, &value))
-- if (!PyArg_ParseTuple(args, "OO:delattr", &v, &name))
-- if (!PyArg_ParseTuple(args, "OO|O:pow", &v, &w, &z))
-- if (!PyArg_ParseTuple(args, "OO|O:reduce", &func, &seq, &result))
-- if (!PyArg_ParseTuple(args, "OO:isinstance", &inst, &cls))
-- if (!PyArg_ParseTuple(args, "OO:issubclass", &derived, &cls))
-- if (!PyArg_ParseTuple(args, "O:abs", &v))
-- if (!PyArg_ParseTuple(args, "O|OO:apply", &func, &alist, &kwdict))
-- if (!PyArg_ParseTuple(args, "O:callable", &v))
-- if (!PyArg_ParseTuple(args, "O|O:complex", &r, &i))
-- if (!PyArg_ParseTuple(args, "O:id", &v))
-- if (!PyArg_ParseTuple(args, "O:hash", &v))
-- if (!PyArg_ParseTuple(args, "O:hex", &v))
-- if (!PyArg_ParseTuple(args, "O:float", &v))
-- if (!PyArg_ParseTuple(args, "O|O:iter", &v, &w))
-- if (!PyArg_ParseTuple(args, "O:len", &v))
-- if (!PyArg_ParseTuple(args, "O:list", &v))
-- if (!PyArg_ParseTuple(args, "O|OO:slice", &start, &stop, &step))
-- else if (!PyArg_ParseTuple(args, "O:min/max", &v))
-- if (!PyArg_ParseTuple(args, "O:oct", &v))
-- if (!PyArg_ParseTuple(args, "O:ord", &obj))
-- if (!PyArg_ParseTuple(args, "O:reload", &v))
-- if (!PyArg_ParseTuple(args, "O:repr", &v))
-- if (!PyArg_ParseTuple(args, "O:str", &v))
-- if (!PyArg_ParseTuple(args, "O:tuple", &v))
-- if (!PyArg_ParseTuple(args, "O:type", &v))
--
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
______________________________________________________________________
Company & Consulting: http://www.egenix.com/
Python Software: http://www.lemburg.com/python/