[Python-Dev] Special-casing "O"

Martin v. Loewis martin@loewis.home.cs.tu-berlin.de
Fri, 25 May 2001 21:51:26 +0200


> Now this would be more flexible if you would implement a scheme
> which lets us put the parser string into the method list. The
> call mechanism could then easily figure out how to call the
> method and it would also be more easily extensible:
> 
>  {"append", (PyCFunction)listappend,  METH_DIRECT, append_doc, "O"},

I'd like to hear other people's comment on this specific issue, so I
guess I should probably write a PEP outlining the options.

My immediate reaction to your proposal is that it only complicates the
interface without any savings. We still can only support a limited
number of calling conventions. E.g. it is not possible to write
portable C code that does all the calling conventions for "l", "ll",
"lll", "llll", and so on - you have to cast the function pointer to
the right prototype, which must be done in source code.

So with this interface, you may end up at run-time finding out that
you cannot support the signature. With the current patch, you'd have
to know to convert "OO" into METH_OO, which I think is not asked too
much - and it gives you a compile-time error if you use an unsupported
calling convention.

> A parser marker "OO" would then call a method like this:
> 
>  method(self, arg0, arg1)
> 
> and so on.

That is indeed the plan, but since you have to code the parameter
combinations in C code, you can only support so many of them.

> allows implementing a generic scheme which
> then again relies on PyArg_ParseTuple() to do the argument
> parsing, e.g. "is#" could be implemented as:

The point of the patch is to get rid of PyArg_ParseTuple in the
"common case". For functions with complex calling conventions, getting
rid of the PyArg_ParseTuple string parsing is not that important,
since they are expensive, anyway (not that "is#" couldn't be
supported, I'd call it METH_is_hash).

> For optional arguments we'd need some convention which then
> lets the called function add the default value as needed.

For the moment, I'd only support "|O", and perhaps "|z"; an omitted
argument would be represented as a NULL pointer. That means that "|i"
couldn't participate in the fast calling convention - unless we
translate that to

void foo(PyObject*self, int i, bool ipresent);

BTW, the most frequent function in my measurements that would make use
of this convention is "OO|i:replace", which scores at 4.5%.

Regards,
Martin