Re: PROPOSAL: A Generic Python Object Interface for Python C Modules

Guido.van.Rossum@cwi.nl
Thu, 02 Mar 1995 15:30:58 +0100

> > PyObject* PyObject_CallMethod(object, method-name, args...)
>
> I like it. I should have included it. I'm for adding it. How about a
> family of routines:
[...]

The 1.2 release defines PyEval_CallMethod with the semantics of
your PyObject_CallMethodStringV. This may be a bit confusing.

Actually, it makes no sense to have both a callable_object and a
method object as parameter -- a callable object doesn't take a method,
and a method itself is already a callable object. And since passing
the argument list as a tuple is only one call away from just using
PyEval_CallObject(), why not just have to variants:

- PyEval_CallFunction(object *callable_obj, char *format, ...)

- PyEval_CallMethod(object *obj, char *methonname, char *format, ...)

This would correspond to your 'C' family of functions. Again, the 'V'
family is easily emulated using the 'C' family and a format string
like "OOO", so there really is no pressing need for that many
different variants.

> Call the method named m of object o. Special method names,
> such as "__add__", "__getitem__", and so on are supported.
> Arguments are given by the tuple, args. If no arguments are
> needed, then args may be NULL. Returns the result of the
> call on success, or NULL on failure. This is the equivalent
> of the Python expression: o.method(args).

Should "__add__" etc. work for built-in object types (e.g. integers)
too? That would be nice but lots of work, since it isn't implemented
currently. Also, since the vast majority of these calls would have
constant string literals for this argument, it would encourage users
to write

z = PyEval_CallMethod(x, "__add__", "o", y)

instead of the more efficient and direct

z = PyNumber_Add(x, y)

> Also, to handle conversion of the output of this and other functions
> returning PyObject pointers to C, I suggest:
>
> PyArg_ParseTupleD(PyObject *o, char *format, ...)

(== PyArg_ParseTuple followed by Py_DECREF(o)).

While I like the semantics of checking for NULL and then leaving an
existing exception (which I suppose could be made the standard
semantics of PyArg_ParseTuple), again I don't like defining a new
function as a shorthand for two other calls.

> > PyObject *args = PyTuple_New(1);
> > <how to set a tuple's item here: sq_ass_item not defined?>
>
> Hm, well, maybe you set a tuple's item with PySequence_SetItem:
>
> PySequence_SetItem(args,0,some_value)
>
> Ah, but of course, there is a problem here, since tuple's only
> allow C routines to set their items through a separate interface.
>
> So, should PySequence_SetItem treat tuples as a special case, or
> should someone who needs to set a tuple item have to use the Tuple
> specific interface?

The latter, as I mentioned in my previous reply.

--Guido van Rossum, CWI, Amsterdam <mailto:Guido.van.Rossum@cwi.nl>
<http://www.cwi.nl/cwi/people/Guido.van.Rossum.html>