bpo-20186: Convert tuple object implementation to Argument Clinic. (#… · python/cpython@0b56159 (original) (raw)
`@@ -4,6 +4,13 @@
`
4
4
`#include "Python.h"
`
5
5
`#include "accu.h"
`
6
6
``
``
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
+
7
14
`/* Speed optimization to avoid frequent malloc/free of small tuples */
`
8
15
`#ifndef PyTuple_MAXSAVESIZE
`
9
16
`#define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
`
`@@ -523,28 +530,39 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)
`
523
530
`return (PyObject *) np;
`
524
531
`}
`
525
532
``
``
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
+
526
546
`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]/
`
528
550
`{
`
529
``
`-
Py_ssize_t i, start=0, stop=Py_SIZE(self);
`
530
``
`-
PyObject *v;
`
``
551
`+
Py_ssize_t i;
`
531
552
``
532
``
`-
if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
`
533
``
`-
_PyEval_SliceIndex, &start,
`
534
``
`-
_PyEval_SliceIndex, &stop))
`
535
``
`-
return NULL;
`
536
553
`if (start < 0) {
`
537
554
`start += Py_SIZE(self);
`
538
555
`if (start < 0)
`
539
556
`start = 0;
`
540
557
` }
`
541
558
`if (stop < 0) {
`
542
559
`stop += Py_SIZE(self);
`
543
``
`-
if (stop < 0)
`
544
``
`-
stop = 0;
`
545
560
` }
`
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_RichCompareBool(self->ob_item[i], value, Py_EQ);
`
548
566
`if (cmp > 0)
`
549
567
`return PyLong_FromSsize_t(i);
`
550
568
`else if (cmp < 0)
`
`@@ -554,14 +572,24 @@ tupleindex(PyTupleObject *self, PyObject *args)
`
554
572
`return NULL;
`
555
573
`}
`
556
574
``
``
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
+
557
584
`static PyObject *
`
558
``
`-
tuplecount(PyTupleObject *self, PyObject *v)
`
``
585
`+
tuple_count(PyTupleObject *self, PyObject *value)
`
``
586
`+
/[clinic end generated code: output=aa927affc5a97605 input=531721aff65bd772]/
`
559
587
`{
`
560
588
`Py_ssize_t count = 0;
`
561
589
`Py_ssize_t i;
`
562
590
``
563
591
`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);
`
565
593
`if (cmp > 0)
`
566
594
`count++;
`
567
595
`else if (cmp < 0)
`
`@@ -650,34 +678,43 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)
`
650
678
`}
`
651
679
``
652
680
`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]*/
`
654
696
``
655
697
`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]/
`
657
700
`{
`
658
``
`-
PyObject *arg = NULL;
`
659
``
-
660
701
`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);
`
666
703
``
667
``
`-
if (arg == NULL)
`
``
704
`+
if (iterable == NULL)
`
668
705
`return PyTuple_New(0);
`
669
706
`else
`
670
``
`-
return PySequence_Tuple(arg);
`
``
707
`+
return PySequence_Tuple(iterable);
`
671
708
`}
`
672
709
``
673
710
`static PyObject *
`
674
``
`-
tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
`
``
711
`+
tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
`
675
712
`{
`
676
713
`PyObject *tmp, *newobj, *item;
`
677
714
`Py_ssize_t i, n;
`
678
715
``
679
716
`assert(PyType_IsSubtype(type, &PyTuple_Type));
`
680
``
`-
tmp = tuple_new(&PyTuple_Type, args, kwds);
`
``
717
`+
tmp = tuple_new_impl(&PyTuple_Type, iterable);
`
681
718
`if (tmp == NULL)
`
682
719
`return NULL;
`
683
720
`assert(PyTuple_Check(tmp));
`
`@@ -693,12 +730,6 @@ tuple_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
`
693
730
`return newobj;
`
694
731
`}
`
695
732
``
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
``
-
702
733
`static PySequenceMethods tuple_as_sequence = {
`
703
734
` (lenfunc)tuplelength, /* sq_length */
`
704
735
` (binaryfunc)tupleconcat, /* sq_concat */
`
`@@ -766,24 +797,21 @@ tuplesubscript(PyTupleObject* self, PyObject* item)
`
766
797
` }
`
767
798
`}
`
768
799
``
``
800
`+
/*[clinic input]
`
``
801
`+
tuple.getnewargs
`
``
802
`+
[clinic start generated code]*/
`
``
803
+
769
804
`static PyObject *
`
770
``
`-
tuple_getnewargs(PyTupleObject *v)
`
``
805
`+
tuple___getnewargs___impl(PyTupleObject *self)
`
``
806
`+
/[clinic end generated code: output=25e06e3ee56027e2 input=1aeb4b286a21639a]/
`
771
807
`{
`
772
``
`-
return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
`
773
``
-
``
808
`+
return Py_BuildValue("(N)", tupleslice(self, 0, Py_SIZE(self)));
`
774
809
`}
`
775
810
``
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
``
-
783
811
`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
`
787
815
` {NULL, NULL} /* sentinel */
`
788
816
`};
`
789
817
``
`@@ -817,7 +845,7 @@ PyTypeObject PyTuple_Type = {
`
817
845
`0, /* tp_as_buffer */
`
818
846
`Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
`
819
847
`Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */
`
820
``
`-
tuple_doc, /* tp_doc */
`
``
848
`+
tuple_new__doc__, /* tp_doc */
`
821
849
` (traverseproc)tupletraverse, /* tp_traverse */
`
822
850
`0, /* tp_clear */
`
823
851
`tuplerichcompare, /* tp_richcompare */
`