[Python-Dev] Special-casing "O"

Tim Peters tim.one@home.com
Sun, 27 May 2001 16:37:43 -0400


[Jeremy]
> How is METH_O different than METH_OLDARGS?

I have no idea:  can you explain it?  The #define's for these symbols are
uncommented, and it's a mystery to me what they're *supposed* to mean.

> The old-style argument passing is definitely the most efficient for
> functions of a zero or one arguments.  There's special-case code in
> ceval to support it these cases -- fast_cfunction() -- primarily
> because in these cases the function can be invoked by using arguments
> directly from the Python stack instead of copying them to a tuple
> first.

OK, I'm looking in bltinmodule.c, at builtin_len.  It starts like so:

static PyObject *
builtin_len(PyObject *self, PyObject *args)
{
	PyObject *v;
	long res;

	if (!PyArg_ParseTuple(args, "O:len", &v))
		return NULL;

So it's clearly expecting a tuple.  But its entry in the builtin_methods[]
table is:

	{"len",		builtin_len, 1, len_doc},

That is, it says nothing about the calling convention.  Since C fills in a 0
for missing values, and methodobject.c has

/* Flag passed to newmethodobject */
#define METH_OLDARGS  0x0000
#define METH_VARARGS  0x0001
#define METH_KEYWORDS 0x0002

then doesn't the stuct for builtin_len implicitly specify METH_OLDARGS?  But
if that's true, and fast_cfunction() does not create a tuple in this case,
how is that builtin_len gets a tuple?

Something doesn't add up here.  Or does it?  There's no *reference* to
METH_OLDARGS anywhere in the code base other than its definition and its use
in method tables, so whatever code *keys* off it must be assuming a
hardcoded 0 value for it -- or indeed nothing keys off it at all.

I expect this line in ceval.c is doing the dirty assumption:

			    } else if (flags == 0) {

and should be testing against METH_OLDARGS instead.

But I see that builtin_len is falling into the METH_VARARGS case despite
that it wasn't declared that way and that it sure looks like METH_OLDARGS
(0) is the default.  Confusing!  Fix it <wink>.