Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e3eb1f2

Browse files
committed
Patch #427190: Implement and use METH_NOARGS and METH_O.
1 parent c354221 commit e3eb1f2

17 files changed

Lines changed: 430 additions & 552 deletions

Doc/api/api.tex

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5257,6 +5257,68 @@ \section{Common Object Structures \label{common-structs}}
52575257
\end{tableiii}
52585258
\end{ctypedesc}
52595259

5260+
The \var{ml_meth} is a C function pointer. The functions may be of
5261+
different types, but they always return \ctype{PyObject*}. If the
5262+
function is not of the \ctype{PyCFunction}, the compiler will require
5263+
a cast in the method table. Even though \ctype{PyCFunction} defines
5264+
the first parameter as \ctype{PyObject*}, it is common that the method
5265+
implementation uses a the specific C type of the \var{self} object.
5266+
5267+
The flags can have the following values. Only METH_VARARGS and
5268+
METH_KEYWORDS can be combined; the others can't.
5269+
5270+
\begin{datadesc}{METH_VARARGS}
5271+
5272+
This is the typical calling convention, where the methods have the
5273+
type \ctype{PyMethodDef}. The function expects two \ctype{PyObject*}.
5274+
The first one is the \var{self} object for methods; for module
5275+
functions, it has the value given to \cfunction{PyInitModule4} (or
5276+
\NULL{} if \cfunction{PyInitModule} was used). The second parameter
5277+
(often called \var{args}) is a tuple object representing all
5278+
arguments. This parameter is typically processed using
5279+
\cfunction{PyArg_ParseTuple}.
5280+
5281+
\end{datadesc}
5282+
5283+
\begin{datadesc}{METH_KEYWORDS}
5284+
5285+
Methods with these flags must be of type
5286+
\ctype{PyCFunctionWithKeywords}. The function expects three
5287+
parameters: \var{self}, \var{args}, and a dictionary of all the keyword
5288+
arguments. The flag is typically combined with METH_VARARGS, and the
5289+
parameters are typically processed using
5290+
\cfunction{PyArg_ParseTupleAndKeywords}.
5291+
5292+
\end{datadesc}
5293+
5294+
\begin{datadesc}{METH_NOARGS}
5295+
5296+
Methods without parameters don't need to check whether arguments are
5297+
given if they are listed with the \code{METH_NOARGS} flag. They need
5298+
to be of type \ctype{PyNoArgsFunction}, i.e. they expect a single
5299+
\var{self} parameter.
5300+
5301+
\end{datadesc}
5302+
5303+
\begin{datadesc}{METH_O}
5304+
5305+
Methods with a single object argument can be listed with the
5306+
\code{METH_O} flag, instead of invoking \cfunction{PyArg_ParseTuple}
5307+
with a \code{``O''} argument. They have the type \ctype{PyCFunction},
5308+
with the \var{self} parameter, and a \ctype{PyObject*} parameter
5309+
representing the single argument.
5310+
5311+
\end{datadesc}
5312+
5313+
\begin{datadesc}{METH_OLDARGS}
5314+
5315+
This calling convention is deprecated. The method must be of type
5316+
\ctype{PyCFunction}. The second argument is \NULL{} if no arguments
5317+
are given, a single object if exactly one argument is given, and a
5318+
tuple of objects if more than one argument is given.
5319+
5320+
\end{datadesc}
5321+
52605322
\begin{cfuncdesc}{PyObject*}{Py_FindMethod}{PyMethodDef[] table,
52615323
PyObject *ob, char *name}
52625324
Return a bound method object for an extension type implemented in C.

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ Core
9090
(These warnings currently don't conform to the warnings framework of
9191
PEP 230; we intend to fix this in 2.2a2.)
9292

93+
- Two new flags METH_NOARGS and METH_O are available in method definition
94+
tables to simplify implementation of methods with no arguments and a
95+
single untyped argument. Calling such methods is more efficient than
96+
calling corresponding METH_VARARGS methods. METH_OLDARGS is now
97+
deprecated.
98+
9399
- The UTF-16 codec was modified to be more RFC compliant. It will now
94100
only remove BOM characters at the start of the string and then
95101
only if running in native mode (UTF-16-LE and -BE won't remove a

Objects/complexobject.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -580,18 +580,16 @@ complex_float(PyObject *v)
580580
}
581581

582582
static PyObject *
583-
complex_conjugate(PyObject *self, PyObject *args)
583+
complex_conjugate(PyObject *self)
584584
{
585585
Py_complex c;
586-
if (!PyArg_ParseTuple(args, ":conjugate"))
587-
return NULL;
588586
c = ((PyComplexObject *)self)->cval;
589587
c.imag = -c.imag;
590588
return PyComplex_FromCComplex(c);
591589
}
592590

593591
static PyMethodDef complex_methods[] = {
594-
{"conjugate", complex_conjugate, 1},
592+
{"conjugate", (PyCFunction)complex_conjugate, METH_NOARGS},
595593
{NULL, NULL} /* sentinel */
596594
};
597595

Objects/descrobject.c

Lines changed: 10 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -601,12 +601,8 @@ static PySequenceMethods proxy_as_sequence = {
601601
};
602602

603603
static PyObject *
604-
proxy_has_key(proxyobject *pp, PyObject *args)
604+
proxy_has_key(proxyobject *pp, PyObject *key)
605605
{
606-
PyObject *key;
607-
608-
if (!PyArg_ParseTuple(args, "O:has_key", &key))
609-
return NULL;
610606
return PyInt_FromLong(PySequence_Contains(pp->dict, key));
611607
}
612608

@@ -621,44 +617,36 @@ proxy_get(proxyobject *pp, PyObject *args)
621617
}
622618

623619
static PyObject *
624-
proxy_keys(proxyobject *pp, PyObject *args)
620+
proxy_keys(proxyobject *pp)
625621
{
626-
if (!PyArg_ParseTuple(args, ":keys"))
627-
return NULL;
628622
return PyMapping_Keys(pp->dict);
629623
}
630624

631625
static PyObject *
632-
proxy_values(proxyobject *pp, PyObject *args)
626+
proxy_values(proxyobject *pp)
633627
{
634-
if (!PyArg_ParseTuple(args, ":values"))
635-
return NULL;
636628
return PyMapping_Values(pp->dict);
637629
}
638630

639631
static PyObject *
640-
proxy_items(proxyobject *pp, PyObject *args)
632+
proxy_items(proxyobject *pp)
641633
{
642-
if (!PyArg_ParseTuple(args, ":items"))
643-
return NULL;
644634
return PyMapping_Items(pp->dict);
645635
}
646636

647637
static PyObject *
648-
proxy_copy(proxyobject *pp, PyObject *args)
638+
proxy_copy(proxyobject *pp)
649639
{
650-
if (!PyArg_ParseTuple(args, ":copy"))
651-
return NULL;
652640
return PyObject_CallMethod(pp->dict, "copy", NULL);
653641
}
654642

655643
static PyMethodDef proxy_methods[] = {
656-
{"has_key", (PyCFunction)proxy_has_key, METH_VARARGS, "XXX"},
644+
{"has_key", (PyCFunction)proxy_has_key, METH_O, "XXX"},
657645
{"get", (PyCFunction)proxy_get, METH_VARARGS, "XXX"},
658-
{"keys", (PyCFunction)proxy_keys, METH_VARARGS, "XXX"},
659-
{"values", (PyCFunction)proxy_values, METH_VARARGS, "XXX"},
660-
{"items", (PyCFunction)proxy_items, METH_VARARGS, "XXX"},
661-
{"copy", (PyCFunction)proxy_copy, METH_VARARGS, "XXX"},
646+
{"keys", (PyCFunction)proxy_keys, METH_NOARGS, "XXX"},
647+
{"values", (PyCFunction)proxy_values, METH_NOARGS, "XXX"},
648+
{"items", (PyCFunction)proxy_items, METH_NOARGS, "XXX"},
649+
{"copy", (PyCFunction)proxy_copy, METH_NOARGS, "XXX"},
662650
{0}
663651
};
664652

Objects/dictobject.c

Lines changed: 25 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -875,13 +875,11 @@ static PyMappingMethods dict_as_mapping = {
875875
};
876876

877877
static PyObject *
878-
dict_keys(register dictobject *mp, PyObject *args)
878+
dict_keys(register dictobject *mp)
879879
{
880880
register PyObject *v;
881881
register int i, j, n;
882882

883-
if (!PyArg_NoArgs(args))
884-
return NULL;
885883
again:
886884
n = mp->ma_used;
887885
v = PyList_New(n);
@@ -906,13 +904,11 @@ dict_keys(register dictobject *mp, PyObject *args)
906904
}
907905

908906
static PyObject *
909-
dict_values(register dictobject *mp, PyObject *args)
907+
dict_values(register dictobject *mp)
910908
{
911909
register PyObject *v;
912910
register int i, j, n;
913911

914-
if (!PyArg_NoArgs(args))
915-
return NULL;
916912
again:
917913
n = mp->ma_used;
918914
v = PyList_New(n);
@@ -937,14 +933,12 @@ dict_values(register dictobject *mp, PyObject *args)
937933
}
938934

939935
static PyObject *
940-
dict_items(register dictobject *mp, PyObject *args)
936+
dict_items(register dictobject *mp)
941937
{
942938
register PyObject *v;
943939
register int i, j, n;
944940
PyObject *item, *key, *value;
945941

946-
if (!PyArg_NoArgs(args))
947-
return NULL;
948942
/* Preallocate the list of tuples, to avoid allocations during
949943
* the loop over the items, which could trigger GC, which
950944
* could resize the dict. :-(
@@ -987,12 +981,8 @@ dict_items(register dictobject *mp, PyObject *args)
987981
}
988982

989983
static PyObject *
990-
dict_update(PyObject *mp, PyObject *args)
984+
dict_update(PyObject *mp, PyObject *other)
991985
{
992-
PyObject *other;
993-
994-
if (!PyArg_ParseTuple(args, "O:update", &other))
995-
return NULL;
996986
if (PyDict_Update(mp, other) < 0)
997987
return NULL;
998988
Py_INCREF(Py_None);
@@ -1099,10 +1089,8 @@ PyDict_Merge(PyObject *a, PyObject *b, int override)
10991089
}
11001090

11011091
static PyObject *
1102-
dict_copy(register dictobject *mp, PyObject *args)
1092+
dict_copy(register dictobject *mp)
11031093
{
1104-
if (!PyArg_Parse(args, ""))
1105-
return NULL;
11061094
return PyDict_Copy((PyObject*)mp);
11071095
}
11081096

@@ -1155,7 +1143,7 @@ PyDict_Keys(PyObject *mp)
11551143
PyErr_BadInternalCall();
11561144
return NULL;
11571145
}
1158-
return dict_keys((dictobject *)mp, (PyObject *)NULL);
1146+
return dict_keys((dictobject *)mp);
11591147
}
11601148

11611149
PyObject *
@@ -1165,7 +1153,7 @@ PyDict_Values(PyObject *mp)
11651153
PyErr_BadInternalCall();
11661154
return NULL;
11671155
}
1168-
return dict_values((dictobject *)mp, (PyObject *)NULL);
1156+
return dict_values((dictobject *)mp);
11691157
}
11701158

11711159
PyObject *
@@ -1175,7 +1163,7 @@ PyDict_Items(PyObject *mp)
11751163
PyErr_BadInternalCall();
11761164
return NULL;
11771165
}
1178-
return dict_items((dictobject *)mp, (PyObject *)NULL);
1166+
return dict_items((dictobject *)mp);
11791167
}
11801168

11811169
/* Subroutine which returns the smallest key in a for which b's value
@@ -1366,13 +1354,10 @@ dict_richcompare(PyObject *v, PyObject *w, int op)
13661354
}
13671355

13681356
static PyObject *
1369-
dict_has_key(register dictobject *mp, PyObject *args)
1357+
dict_has_key(register dictobject *mp, PyObject *key)
13701358
{
1371-
PyObject *key;
13721359
long hash;
13731360
register long ok;
1374-
if (!PyArg_ParseTuple(args, "O:has_key", &key))
1375-
return NULL;
13761361
#ifdef CACHE_HASH
13771362
if (!PyString_Check(key) ||
13781363
(hash = ((PyStringObject *) key)->ob_shash) == -1)
@@ -1447,24 +1432,20 @@ dict_setdefault(register dictobject *mp, PyObject *args)
14471432

14481433

14491434
static PyObject *
1450-
dict_clear(register dictobject *mp, PyObject *args)
1435+
dict_clear(register dictobject *mp)
14511436
{
1452-
if (!PyArg_NoArgs(args))
1453-
return NULL;
14541437
PyDict_Clear((PyObject *)mp);
14551438
Py_INCREF(Py_None);
14561439
return Py_None;
14571440
}
14581441

14591442
static PyObject *
1460-
dict_popitem(dictobject *mp, PyObject *args)
1443+
dict_popitem(dictobject *mp)
14611444
{
14621445
int i = 0;
14631446
dictentry *ep;
14641447
PyObject *res;
14651448

1466-
if (!PyArg_NoArgs(args))
1467-
return NULL;
14681449
/* Allocate the result tuple before checking the size. Believe it
14691450
* or not, this allocation could trigger a garbage collection which
14701451
* could empty the dict, so if we checked the size first and that
@@ -1573,26 +1554,20 @@ select_item(PyObject *key, PyObject *value)
15731554
}
15741555

15751556
static PyObject *
1576-
dict_iterkeys(dictobject *dict, PyObject *args)
1557+
dict_iterkeys(dictobject *dict)
15771558
{
1578-
if (!PyArg_ParseTuple(args, ""))
1579-
return NULL;
15801559
return dictiter_new(dict, select_key);
15811560
}
15821561

15831562
static PyObject *
1584-
dict_itervalues(dictobject *dict, PyObject *args)
1563+
dict_itervalues(dictobject *dict)
15851564
{
1586-
if (!PyArg_ParseTuple(args, ""))
1587-
return NULL;
15881565
return dictiter_new(dict, select_value);
15891566
}
15901567

15911568
static PyObject *
1592-
dict_iteritems(dictobject *dict, PyObject *args)
1569+
dict_iteritems(dictobject *dict)
15931570
{
1594-
if (!PyArg_ParseTuple(args, ""))
1595-
return NULL;
15961571
return dictiter_new(dict, select_item);
15971572
}
15981573

@@ -1638,31 +1613,31 @@ static char iteritems__doc__[] =
16381613
"D.iteritems() -> an iterator over the (key, value) items of D";
16391614

16401615
static PyMethodDef mapp_methods[] = {
1641-
{"has_key", (PyCFunction)dict_has_key, METH_VARARGS,
1616+
{"has_key", (PyCFunction)dict_has_key, METH_O,
16421617
has_key__doc__},
16431618
{"get", (PyCFunction)dict_get, METH_VARARGS,
16441619
get__doc__},
16451620
{"setdefault", (PyCFunction)dict_setdefault, METH_VARARGS,
16461621
setdefault_doc__},
1647-
{"popitem", (PyCFunction)dict_popitem, METH_OLDARGS,
1622+
{"popitem", (PyCFunction)dict_popitem, METH_NOARGS,
16481623
popitem__doc__},
1649-
{"keys", (PyCFunction)dict_keys, METH_OLDARGS,
1624+
{"keys", (PyCFunction)dict_keys, METH_NOARGS,
16501625
keys__doc__},
1651-
{"items", (PyCFunction)dict_items, METH_OLDARGS,
1626+
{"items", (PyCFunction)dict_items, METH_NOARGS,
16521627
items__doc__},
1653-
{"values", (PyCFunction)dict_values, METH_OLDARGS,
1628+
{"values", (PyCFunction)dict_values, METH_NOARGS,
16541629
values__doc__},
1655-
{"update", (PyCFunction)dict_update, METH_VARARGS,
1630+
{"update", (PyCFunction)dict_update, METH_O,
16561631
update__doc__},
1657-
{"clear", (PyCFunction)dict_clear, METH_OLDARGS,
1632+
{"clear", (PyCFunction)dict_clear, METH_NOARGS,
16581633
clear__doc__},
1659-
{"copy", (PyCFunction)dict_copy, METH_OLDARGS,
1634+
{"copy", (PyCFunction)dict_copy, METH_NOARGS,
16601635
copy__doc__},
1661-
{"iterkeys", (PyCFunction)dict_iterkeys, METH_VARARGS,
1636+
{"iterkeys", (PyCFunction)dict_iterkeys, METH_NOARGS,
16621637
iterkeys__doc__},
1663-
{"itervalues", (PyCFunction)dict_itervalues, METH_VARARGS,
1638+
{"itervalues", (PyCFunction)dict_itervalues, METH_NOARGS,
16641639
itervalues__doc__},
1665-
{"iteritems", (PyCFunction)dict_iteritems, METH_VARARGS,
1640+
{"iteritems", (PyCFunction)dict_iteritems, METH_NOARGS,
16661641
iteritems__doc__},
16671642
{NULL, NULL} /* sentinel */
16681643
};

0 commit comments

Comments
 (0)