10000 bpo-20186: Convert tuple object implementation to Argument Clinic. (#… · python/cpython@0b56159 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0b56159

Browse files
bpo-20186: Convert tuple object implementation to Argument Clinic. (#614)
1 parent 5c643a0 commit 0b56159

File tree

2 files changed

+176
-46
lines changed

2 files changed

+176
-46
lines changed

Objects/clinic/tupleobject.c.h

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*[clinic input]
2+
preserve
3+
[clinic start generated code]*/
4+
5+
PyDoc_STRVAR(tuple_index__doc__,
6+
"index($self, value, start=0, stop=sys.maxsize, /)\n"
7+
"--\n"
8+
"\n"
9+
"Return first index of value.\n"
10+
"\n"
11+
"Raises ValueError if the value is not present.");
12+
13+
#define TUPLE_INDEX_METHODDEF \
14+
{"index", (PyCFunction)tuple_index, METH_FASTCALL, tuple_index__doc__},
15+
16+
static PyObject *
17+
tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start,
18+
Py_ssize_t stop);
19+
20+
static PyObject *
21+
tuple_index(PyTupleObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
22+
{
23+
PyObject *return_value = NULL;
24+
PyObject *value;
25+
Py_ssize_t start = 0;
26+
Py_ssize_t stop = PY_SSIZE_T_MAX;
27+
28+
if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
29+
&value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
30+
goto exit;
31+
}
32+
33+
if (!_PyArg_NoStackKeywords("index", kwnames)) {
34+
goto exit;
35+
}
36+
return_value = tuple_index_impl(self, value, start, stop);
37+
38+
exit:
39+
return return_value;
40+
}
41+
42+
PyDoc_STRVAR(tuple_count__doc__,
43+
"count($self, value, /)\n"
44+
"--\n"
45+
"\n"
46+
"Return number of occurrences of value.");
47+
48+
#define TUPLE_COUNT_METHODDEF \
49+
{"count", (PyCFunction)tuple_count, METH_O, tuple_count__doc__},
50+
51+
PyDoc_STRVAR(tuple_new__doc__,
52+
"tuple(iterable=(), /)\n"
53+
"--\n"
54+
"\n"
55+
"Built-in immutable sequence.\n"
56+
"\n"
57+
"If no argument is given, the constructor returns an empty tuple.\n"
58+
"If iterable is specified the tuple is initialized from iterable\'s items.\n"
59+
"\n"
60+
"If the argument is a tuple, the return value is the same object.");
61+
62+
static PyObject *
63+
tuple_new_impl(PyTypeObject *type, PyObject *iterable);
64+
65+
static PyObject *
66+
tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
67+
{
68+
PyObject *return_value = NULL;
69+
PyObject *iterable = NULL;
70+
71+
if ((type == &PyTuple_Type) &&
72+
!_PyArg_NoKeywords("tuple", kwargs)) {
73+
goto exit;
74+
}
75+
if (!PyArg_UnpackTuple(args, "tuple",
76+
0, 1,
77+
&iterable)) {
78+
goto exit;
79+
}
80+
return_value = tuple_new_impl(type, iterable);
81+
82+
exit:
83+
return return_value;
84+
}
85+
86+
PyDoc_STRVAR(tuple___getnewargs____doc__,
87+
"__getnewargs__($self, /)\n"
88+
"--\n"
89+
"\n");
90+
91+
#define TUPLE___GETNEWARGS___METHODDEF \
92+
{"__getnewargs__", (PyCFunction)tuple___getnewargs__, METH_NOARGS, tuple___getnewargs____doc__},
93+
94+
static PyObject *
95+
tuple___getnewargs___impl(PyTupleObject *self);
96+
97+
static PyObject *
98+
tuple___getnewargs__(PyTupleObject *self, PyObject *Py_UNUSED(ignored))
99+
{
100+
return tuple___getnewargs___impl(self);
101+
}
102+
/*[clinic end generated code: output=561a3654411d2225 input=a9049054013a1b77]*/

Objects/tupleobject.c

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@
44
#include "Python.h"
55
#include "accu.h"
66

7+
/*[clinic input]
8+
class tuple "PyTupleObject *" "&PyTuple_Type"
9+
[clinic start generated code]*/
10+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f051ba3cfdf9a189]*/
11+
12+
#include "clinic/tupleobject.c.h"
13+
714
/* Speed optimization to avoid frequent malloc/free of small tuples */
815
#ifndef PyTuple_MAXSAVESIZE
916
#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
@@ -523,28 +530,39 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
523530
return (PyObject *) np;
524531
}
525532

533+
/*[clinic input]
534+
tuple.index
535+
536+
value: object
537+
start: object(converter="_PyEval_SliceIndex", type="Py_ssize_t") = 0
538+
stop: object(converter="_PyEval_SliceIndex", type="Py_ssize_t", c_default="PY_SSIZE_T_MAX") = sys.maxsize
539+
/
540+
541+
Return first index of value.
542+
543+
Raises ValueError if the value is not present.
544+
[clinic start generated code]*/
545+
526546
static PyObject *
527-
tupleindex(PyTupleObject *self, PyObject *args)
547+
tuple_index_impl(PyTupleObject *self, PyObject *value, Py_ssize_t start,
548+
Py_ssize_t stop)
549+
/*[clinic end generated code: output=07b6f9f3cb5c33eb input=28890d4bec234471]*/
528550
{
529-
Py_ssize_t i, start=0, stop=Py_SIZE(self);
530-
PyObject *v;
551+
Py_ssize_t i;
531552

532-
if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
533-
_PyEval_SliceIndex, &start,
534-
_PyEval_SliceIndex, &stop))
535-
return NULL;
536553
if (start < 0) {
537554
start += Py_SIZE(self);
538555
if (start < 0)
539556
start = 0;
540557
}
541558
if (stop < 0) {
542559
stop += Py_SIZE(self);
543-
if (stop < 0)
544-
stop = 0;
545560
}
546-
for (i = start; i < stop && i < Py_SIZE(self); i++) {
547-
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
561+
else if (stop > Py_SIZE(self)) {
562+
stop = Py_SIZE(self);
563+
}
564+
for (i = start; i < stop; i++) {
565+
int cmp = PyObject_R E377 ichCompareBool(self->ob_item[i], value, Py_EQ);
548566
if (cmp > 0)
549567
return PyLong_FromSsize_t(i);
550568
else if (cmp < 0)
@@ -554,14 +572,24 @@ tupleindex(PyTupleObject *self, PyObject *args)
554572
return NULL;
555573
}
556574

575+
/*[clinic input]
576+
tuple.count
577+
578+
value: object
579+
/
580+
581+
Return number of occurrences of value.
582+
[clinic start generated code]*/
583+
557584
static PyObject *
558-
tuplecount(PyTupleObject *self, PyObject *v)
585+
tuple_count(PyTupleObject *self, PyObject *value)
586+
/*[clinic end generated code: output=aa927affc5a97605 input=531721aff65bd772]*/
559587
{
560588
Py_ssize_t count = 0;
561589
Py_ssize_t i;
562590

563591
for (i = 0; i < Py_SIZE(self); i++) {
564-
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
592+
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
565593
if (cmp > 0)
566594
count++;
567595
else if (cmp < 0)
@@ -650,34 +678,43 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)
650678
}
651679

652680
static PyObject *
653-
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
681+
tuple_subtype_new(PyTypeObject *type, PyObject *iterable);
682+
683+
/*[clinic input]
684+
@classmethod
685+
tuple.__new__ as tuple_new
686+
iterable: object(c_default="NULL") = ()
687+
/
688+
689+
Built-in immutable sequence.
690+
691+
If no argument is given, the constructor returns an empty tuple.
692+
If iterable is specified the tuple is initialized from iterable's items.
693+
694+
If the argument is a tuple, the return value is the same object.
695+
[clinic start generated code]*/
654696

655697
static PyObject *
656-
tuple_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
698+
tuple_new_impl(PyTypeObject *type, PyObject *iterable)
699+
/*[clinic end generated code: output=4546d9f0d469bce7 input=86963bcde633b5a2]*/
657700
{
658-
PyObject *arg = NULL;
659-
660701
if (type != &PyTuple_Type)
661-
return tuple_subtype_new(type, args, kwds);
662-
if (!_PyArg_NoKeywords("tuple()", kwds))
663-
return NULL;
664-
if (!PyArg_UnpackTuple(args, "tuple", 0, 1, &arg))
665-
return NULL;
702+
return tuple_subtype_new(type, iterable);
666703

667-
if (arg == NULL)
704+
if (iterable == NULL)
668705
return PyTuple_New(0);
669706
else
670-
return PySequence_Tuple(arg);
707+
return PySequence_Tuple(iterable);
671708
}
672709

673710
static PyObject *
674-
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
711+
tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
675712
{
676713
PyObject *tmp, *newobj, *item;
677714
Py_ssize_t i, n;
678715

679716
assert(PyType_IsSubtype(type, &PyTuple_Type));
680-
tmp = tuple_new(&PyTuple_Type, args, kwds);
717+
tmp = tuple_new_impl(&PyTuple_Type, iterable);
681718
if (tmp == NULL)
682719
return NULL;
683720
assert(PyTuple_Check(tmp));
@@ -693,12 +730,6 @@ tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
693730
return newobj;
694731
}
695732

696-
PyDoc_STRVAR(tuple_doc,
697-
"tuple() -> empty tuple\n\
698-
tuple(iterable) -> tuple initialized from iterable's items\n\
699-
\n\
700-
If the argument is a tuple, the return value is the same object.");
701-
702733
static PySequenceMethods tuple_as_sequence = {
703734
(lenfunc)tuplelength, /* sq_length */
704735
(binaryfunc)tupleconcat, /* sq_concat */
@@ -766,24 +797,21 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
766797
}
767798
}
768799

800+
/*[clinic input]
801+
tuple.__getnewargs__
802+
[clinic start generated code]*/
803+
769804
static PyObject *
770-
tuple_getnewargs(PyTupleObject *v)
805+
tuple___getnewargs___impl(PyTupleObject *self)
806+
/*[clinic end generated code: output=25e06e3ee56027e2 input=1aeb4b286a21639a]*/
771807
{
772-
return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
773-
808+
return Py_BuildValue("(N)", tupleslice(self, 0, Py_SIZE(self)));
774809
}
775810

776-
PyDoc_STRVAR(index_doc,
777-
"T.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
778-
"Raises ValueError if the value is not present."
779-
);
780-
PyDoc_STRVAR(count_doc,
781-
"T.count(value) -> integer -- return number of occurrences of value");
782-
783811
static PyMethodDef tuple_methods[] = {
784-
{"__getnewargs__", (PyCFunction)tuple_getnewargs, METH_NOARGS},
785-
{"index", (PyCFunction)tupleindex, METH_VARARGS, index_doc},
786-
{"count", (PyCFunction)tuplecount, METH_O, count_doc},
812+
TUPLE___GETNEWARGS___METHODDEF
813+
TUPLE_INDEX_METHODDEF
814+
TUPLE_COUNT_METHODDEF
787815
{NULL, NULL} /* sentinel */
788816
};
789817

@@ -817,7 +845,7 @@ PyTypeObject PyTuple_Type = {
817845
0, /* tp_as_buffer */
818846
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
819847
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
820-
tuple_doc, /* tp_doc */
848+
tuple_new__doc__, /* tp_doc */
821849
(traverseproc)tupletraverse, /* tp_traverse */
822850
0, /* tp_clear */
823851
tuplerichcompare, /* tp_richcompare */

0 commit comments

Comments
 (0)
0