mirror of https://github.com/python/cpython
bpo-20186: Convert tuple object implementation to Argument Clinic. (#614)
This commit is contained in:
parent
5c643a028e
commit
0b5615926a
|
@ -0,0 +1,102 @@
|
||||||
|
/*[clinic input]
|
||||||
|
preserve
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
PyDoc_STRVAR(tuple_index__doc__,
|
||||||
|
"index($self, value, start=0, stop=sys.maxsize, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return first index of value.\n"
|
||||||
|
"\n"
|
||||||
|
"Raises ValueError if the value is not present.");
|
||||||
|
|
||||||
|
#define TUPLE_INDEX_METHODDEF \
|
||||||
|
{"index", (PyCFunction)tuple_index, METH_FASTCALL, tuple_index__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start,
|
||||||
|
Py_ssize_t stop);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple_index(PyTupleObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *value;
|
||||||
|
Py_ssize_t start = 0;
|
||||||
|
Py_ssize_t stop = PY_SSIZE_T_MAX;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
|
||||||
|
&value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_PyArg_NoStackKeywords("index", kwnames)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = tuple_index_impl(self, value, start, stop);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(tuple_count__doc__,
|
||||||
|
"count($self, value, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return number of occurrences of value.");
|
||||||
|
|
||||||
|
#define TUPLE_COUNT_METHODDEF \
|
||||||
|
{"count", (PyCFunction)tuple_count, METH_O, tuple_count__doc__},
|
||||||
|
|
||||||
|
PyDoc_STRVAR(tuple_new__doc__,
|
||||||
|
"tuple(iterable=(), /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Built-in immutable sequence.\n"
|
||||||
|
"\n"
|
||||||
|
"If no argument is given, the constructor returns an empty tuple.\n"
|
||||||
|
"If iterable is specified the tuple is initialized from iterable\'s items.\n"
|
||||||
|
"\n"
|
||||||
|
"If the argument is a tuple, the return value is the same object.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple_new_impl(PyTypeObject *type, PyObject *iterable);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *iterable = NULL;
|
||||||
|
|
||||||
|
if ((type == &PyTuple_Type) &&
|
||||||
|
!_PyArg_NoKeywords("tuple", kwargs)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!PyArg_UnpackTuple(args, "tuple",
|
||||||
|
0, 1,
|
||||||
|
&iterable)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = tuple_new_impl(type, iterable);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(tuple___getnewargs____doc__,
|
||||||
|
"__getnewargs__($self, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
|
#define TUPLE___GETNEWARGS___METHODDEF \
|
||||||
|
{"__getnewargs__", (PyCFunction)tuple___getnewargs__, METH_NOARGS, tuple___getnewargs____doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple___getnewargs___impl(PyTupleObject *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return tuple___getnewargs___impl(self);
|
||||||
|
}
|
||||||
|
/*[clinic end generated code: output=561a3654411d2225 input=a9049054013a1b77]*/
|
|
@ -4,6 +4,13 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "accu.h"
|
#include "accu.h"
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
class tuple "PyTupleObject *" "&PyTuple_Type"
|
||||||
|
[clinic start generated code]*/
|
||||||
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f051ba3cfdf9a189]*/
|
||||||
|
|
||||||
|
#include "clinic/tupleobject.c.h"
|
||||||
|
|
||||||
/* Speed optimization to avoid frequent malloc/free of small tuples */
|
/* Speed optimization to avoid frequent malloc/free of small tuples */
|
||||||
#ifndef PyTuple_MAXSAVESIZE
|
#ifndef PyTuple_MAXSAVESIZE
|
||||||
#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
|
#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
|
||||||
|
@ -523,16 +530,26 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
|
||||||
return (PyObject *) np;
|
return (PyObject *) np;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
/*[clinic input]
|
||||||
tupleindex(PyTupleObject *self, PyObject *args)
|
tuple.index
|
||||||
{
|
|
||||||
Py_ssize_t i, start=0, stop=Py_SIZE(self);
|
value: object
|
||||||
PyObject *v;
|
start: object(converter="_PyEval_SliceIndex", type="Py_ssize_t") = 0
|
||||||
|
stop: object(converter="_PyEval_SliceIndex", type="Py_ssize_t", c_default="PY_SSIZE_T_MAX") = sys.maxsize
|
||||||
|
/
|
||||||
|
|
||||||
|
Return first index of value.
|
||||||
|
|
||||||
|
Raises ValueError if the value is not present.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start,
|
||||||
|
Py_ssize_t stop)
|
||||||
|
/*[clinic end generated code: output=07b6f9f3cb5c33eb input=28890d4bec234471]*/
|
||||||
|
{
|
||||||
|
Py_ssize_t i;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
|
|
||||||
_PyEval_SliceIndex, &start,
|
|
||||||
_PyEval_SliceIndex, &stop))
|
|
||||||
return NULL;
|
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start += Py_SIZE(self);
|
start += Py_SIZE(self);
|
||||||
if (start < 0)
|
if (start < 0)
|
||||||
|
@ -540,11 +557,12 @@ tupleindex(PyTupleObject *self, PyObject *args)
|
||||||
}
|
}
|
||||||
if (stop < 0) {
|
if (stop < 0) {
|
||||||
stop += Py_SIZE(self);
|
stop += Py_SIZE(self);
|
||||||
if (stop < 0)
|
|
||||||
stop = 0;
|
|
||||||
}
|
}
|
||||||
for (i = start; i < stop && i < Py_SIZE(self); i++) {
|
else if (stop > Py_SIZE(self)) {
|
||||||
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
|
stop = Py_SIZE(self);
|
||||||
|
}
|
||||||
|
for (i = start; i < stop; i++) {
|
||||||
|
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
return PyLong_FromSsize_t(i);
|
return PyLong_FromSsize_t(i);
|
||||||
else if (cmp < 0)
|
else if (cmp < 0)
|
||||||
|
@ -554,14 +572,24 @@ tupleindex(PyTupleObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
tuple.count
|
||||||
|
|
||||||
|
value: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Return number of occurrences of value.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tuplecount(PyTupleObject *self, PyObject *v)
|
tuple_count(PyTupleObject *self, PyObject *value)
|
||||||
|
/*[clinic end generated code: output=aa927affc5a97605 input=531721aff65bd772]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t count = 0;
|
Py_ssize_t count = 0;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
for (i = 0; i < Py_SIZE(self); i++) {
|
for (i = 0; i < Py_SIZE(self); i++) {
|
||||||
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
|
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
count++;
|
count++;
|
||||||
else if (cmp < 0)
|
else if (cmp < 0)
|
||||||
|
@ -650,34 +678,43 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
|
tuple_subtype_new(PyTypeObject *type, PyObject *iterable);
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
@classmethod
|
||||||
|
tuple.__new__ as tuple_new
|
||||||
|
iterable: object(c_default="NULL") = ()
|
||||||
|
/
|
||||||
|
|
||||||
|
Built-in immutable sequence.
|
||||||
|
|
||||||
|
If no argument is given, the constructor returns an empty tuple.
|
||||||
|
If iterable is specified the tuple is initialized from iterable's items.
|
||||||
|
|
||||||
|
If the argument is a tuple, the return value is the same object.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
tuple_new_impl(PyTypeObject *type, PyObject *iterable)
|
||||||
|
/*[clinic end generated code: output=4546d9f0d469bce7 input=86963bcde633b5a2]*/
|
||||||
{
|
{
|
||||||
PyObject *arg = NULL;
|
|
||||||
|
|
||||||
if (type != &PyTuple_Type)
|
if (type != &PyTuple_Type)
|
||||||
return tuple_subtype_new(type, args, kwds);
|
return tuple_subtype_new(type, iterable);
|
||||||
if (!_PyArg_NoKeywords("tuple()", kwds))
|
|
||||||
return NULL;
|
|
||||||
if (!PyArg_UnpackTuple(args, "tuple", 0, 1, &arg))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (arg == NULL)
|
if (iterable == NULL)
|
||||||
return PyTuple_New(0);
|
return PyTuple_New(0);
|
||||||
else
|
else
|
||||||
return PySequence_Tuple(arg);
|
return PySequence_Tuple(iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
|
||||||
{
|
{
|
||||||
PyObject *tmp, *newobj, *item;
|
PyObject *tmp, *newobj, *item;
|
||||||
Py_ssize_t i, n;
|
Py_ssize_t i, n;
|
||||||
|
|
||||||
assert(PyType_IsSubtype(type, &PyTuple_Type));
|
assert(PyType_IsSubtype(type, &PyTuple_Type));
|
||||||
tmp = tuple_new(&PyTuple_Type, args, kwds);
|
tmp = tuple_new_impl(&PyTuple_Type, iterable);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(PyTuple_Check(tmp));
|
assert(PyTuple_Check(tmp));
|
||||||
|
@ -693,12 +730,6 @@ tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
return newobj;
|
return newobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(tuple_doc,
|
|
||||||
"tuple() -> empty tuple\n\
|
|
||||||
tuple(iterable) -> tuple initialized from iterable's items\n\
|
|
||||||
\n\
|
|
||||||
If the argument is a tuple, the return value is the same object.");
|
|
||||||
|
|
||||||
static PySequenceMethods tuple_as_sequence = {
|
static PySequenceMethods tuple_as_sequence = {
|
||||||
(lenfunc)tuplelength, /* sq_length */
|
(lenfunc)tuplelength, /* sq_length */
|
||||||
(binaryfunc)tupleconcat, /* sq_concat */
|
(binaryfunc)tupleconcat, /* sq_concat */
|
||||||
|
@ -766,24 +797,21 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
/*[clinic input]
|
||||||
tuple_getnewargs(PyTupleObject *v)
|
tuple.__getnewargs__
|
||||||
{
|
[clinic start generated code]*/
|
||||||
return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
|
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
tuple___getnewargs___impl(PyTupleObject *self)
|
||||||
|
/*[clinic end generated code: output=25e06e3ee56027e2 input=1aeb4b286a21639a]*/
|
||||||
|
{
|
||||||
|
return Py_BuildValue("(N)", tupleslice(self, 0, Py_SIZE(self)));
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(index_doc,
|
|
||||||
"T.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
|
|
||||||
"Raises ValueError if the value is not present."
|
|
||||||
);
|
|
||||||
PyDoc_STRVAR(count_doc,
|
|
||||||
"T.count(value) -> integer -- return number of occurrences of value");
|
|
||||||
|
|
||||||
static PyMethodDef tuple_methods[] = {
|
static PyMethodDef tuple_methods[] = {
|
||||||
{"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS},
|
TUPLE___GETNEWARGS___METHODDEF
|
||||||
{"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc},
|
TUPLE_INDEX_METHODDEF
|
||||||
{"count", (PyCFunction)tuplecount, METH_O, count_doc},
|
TUPLE_COUNT_METHODDEF
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -817,7 +845,7 @@ PyTypeObject PyTuple_Type = {
|
||||||
0, /* tp_as_buffer */
|
0, /* tp_as_buffer */
|
||||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
|
||||||
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
|
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
|
||||||
tuple_doc, /* tp_doc */
|
tuple_new__doc__, /* tp_doc */
|
||||||
(traverseproc)tupletraverse, /* tp_traverse */
|
(traverseproc)tupletraverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
tuplerichcompare, /* tp_richcompare */
|
tuplerichcompare, /* tp_richcompare */
|
||||||
|
|
Loading…
Reference in New Issue