2 /* Tuple object implementation */
6 /* Speed optimization to avoid frequent malloc/free of small tuples */
7 #ifndef PyTuple_MAXSAVESIZE
8 #define PyTuple_MAXSAVESIZE 20 /* Largest tuple to save on free list */
10 #ifndef PyTuple_MAXFREELIST
11 #define PyTuple_MAXFREELIST 2000 /* Maximum number of tuples of each size to save */
14 #if PyTuple_MAXSAVESIZE > 0
15 /* Entries 1 up to PyTuple_MAXSAVESIZE are free lists, entry 0 is the empty
16 tuple () of which at most one instance will be allocated.
18 static PyTupleObject
*free_list
[PyTuple_MAXSAVESIZE
];
19 static int numfree
[PyTuple_MAXSAVESIZE
];
22 Py_ssize_t fast_tuple_allocs
;
23 Py_ssize_t tuple_zero_allocs
;
26 /* Debug statistic to count GC tracking of tuples.
27 Please note that tuples are only untracked when considered by the GC, and
28 many of them will be dead before. Therefore, a tracking rate close to 100%
29 does not necessarily prove that the heuristic is inefficient.
31 #ifdef SHOW_TRACK_COUNT
32 static Py_ssize_t count_untracked
= 0;
33 static Py_ssize_t count_tracked
= 0;
38 fprintf(stderr
, "Tuples created: %" PY_FORMAT_SIZE_T
"d\n",
39 count_tracked
+ count_untracked
);
40 fprintf(stderr
, "Tuples tracked by the GC: %" PY_FORMAT_SIZE_T
41 "d\n", count_tracked
);
42 fprintf(stderr
, "%.2f%% tuple tracking rate\n\n",
43 (100.0*count_tracked
/(count_untracked
+count_tracked
)));
49 PyTuple_New(register Py_ssize_t size
)
51 register PyTupleObject
*op
;
54 PyErr_BadInternalCall();
57 #if PyTuple_MAXSAVESIZE > 0
58 if (size
== 0 && free_list
[0]) {
64 return (PyObject
*) op
;
66 if (size
< PyTuple_MAXSAVESIZE
&& (op
= free_list
[size
]) != NULL
) {
67 free_list
[size
] = (PyTupleObject
*) op
->ob_item
[0];
72 /* Inline PyObject_InitVar */
75 Py_TYPE(op
) = &PyTuple_Type
;
77 _Py_NewReference((PyObject
*)op
);
82 Py_ssize_t nbytes
= size
* sizeof(PyObject
*);
83 /* Check for overflow */
84 if (nbytes
/ sizeof(PyObject
*) != (size_t)size
||
85 (nbytes
> PY_SSIZE_T_MAX
- sizeof(PyTupleObject
) - sizeof(PyObject
*)))
87 return PyErr_NoMemory();
89 nbytes
+= sizeof(PyTupleObject
) - sizeof(PyObject
*);
91 op
= PyObject_GC_NewVar(PyTupleObject
, &PyTuple_Type
, size
);
95 for (i
=0; i
< size
; i
++)
96 op
->ob_item
[i
] = NULL
;
97 #if PyTuple_MAXSAVESIZE > 0
101 Py_INCREF(op
); /* extra INCREF so that this is never freed */
104 #ifdef SHOW_TRACK_COUNT
107 _PyObject_GC_TRACK(op
);
108 return (PyObject
*) op
;
112 PyTuple_Size(register PyObject
*op
)
114 if (!PyTuple_Check(op
)) {
115 PyErr_BadInternalCall();
123 PyTuple_GetItem(register PyObject
*op
, register Py_ssize_t i
)
125 if (!PyTuple_Check(op
)) {
126 PyErr_BadInternalCall();
129 if (i
< 0 || i
>= Py_SIZE(op
)) {
130 PyErr_SetString(PyExc_IndexError
, "tuple index out of range");
133 return ((PyTupleObject
*)op
) -> ob_item
[i
];
137 PyTuple_SetItem(register PyObject
*op
, register Py_ssize_t i
, PyObject
*newitem
)
139 register PyObject
*olditem
;
140 register PyObject
**p
;
141 if (!PyTuple_Check(op
) || op
->ob_refcnt
!= 1) {
143 PyErr_BadInternalCall();
146 if (i
< 0 || i
>= Py_SIZE(op
)) {
148 PyErr_SetString(PyExc_IndexError
,
149 "tuple assignment index out of range");
152 p
= ((PyTupleObject
*)op
) -> ob_item
+ i
;
160 _PyTuple_MaybeUntrack(PyObject
*op
)
165 if (!PyTuple_CheckExact(op
) || !_PyObject_GC_IS_TRACKED(op
))
167 t
= (PyTupleObject
*) op
;
169 for (i
= 0; i
< n
; i
++) {
170 PyObject
*elt
= PyTuple_GET_ITEM(t
, i
);
171 /* Tuple with NULL elements aren't
172 fully constructed, don't untrack
175 _PyObject_GC_MAY_BE_TRACKED(elt
))
178 #ifdef SHOW_TRACK_COUNT
182 _PyObject_GC_UNTRACK(op
);
186 PyTuple_Pack(Py_ssize_t n
, ...)
195 result
= PyTuple_New(n
);
198 items
= ((PyTupleObject
*)result
)->ob_item
;
199 for (i
= 0; i
< n
; i
++) {
200 o
= va_arg(vargs
, PyObject
*);
212 tupledealloc(register PyTupleObject
*op
)
214 register Py_ssize_t i
;
215 register Py_ssize_t len
= Py_SIZE(op
);
216 PyObject_GC_UnTrack(op
);
217 Py_TRASHCAN_SAFE_BEGIN(op
)
221 Py_XDECREF(op
->ob_item
[i
]);
222 #if PyTuple_MAXSAVESIZE > 0
223 if (len
< PyTuple_MAXSAVESIZE
&&
224 numfree
[len
] < PyTuple_MAXFREELIST
&&
225 Py_TYPE(op
) == &PyTuple_Type
)
227 op
->ob_item
[0] = (PyObject
*) free_list
[len
];
230 goto done
; /* return */
234 Py_TYPE(op
)->tp_free((PyObject
*)op
);
236 Py_TRASHCAN_SAFE_END(op
)
240 tupleprint(PyTupleObject
*op
, FILE *fp
, int flags
)
243 Py_BEGIN_ALLOW_THREADS
246 for (i
= 0; i
< Py_SIZE(op
); i
++) {
248 Py_BEGIN_ALLOW_THREADS
252 if (PyObject_Print(op
->ob_item
[i
], fp
, 0) != 0)
256 Py_BEGIN_ALLOW_THREADS
265 tuplerepr(PyTupleObject
*v
)
269 PyObject
*pieces
, *result
= NULL
;
273 return PyString_FromString("()");
275 /* While not mutable, it is still possible to end up with a cycle in a
276 tuple through an object that stores itself within a tuple (and thus
277 infinitely asks for the repr of itself). This should only be
278 possible within a type. */
279 i
= Py_ReprEnter((PyObject
*)v
);
281 return i
> 0 ? PyString_FromString("(...)") : NULL
;
284 pieces
= PyTuple_New(n
);
288 /* Do repr() on each element. */
289 for (i
= 0; i
< n
; ++i
) {
290 if (Py_EnterRecursiveCall(" while getting the repr of a tuple"))
292 s
= PyObject_Repr(v
->ob_item
[i
]);
293 Py_LeaveRecursiveCall();
296 PyTuple_SET_ITEM(pieces
, i
, s
);
299 /* Add "()" decorations to the first and last items. */
301 s
= PyString_FromString("(");
304 temp
= PyTuple_GET_ITEM(pieces
, 0);
305 PyString_ConcatAndDel(&s
, temp
);
306 PyTuple_SET_ITEM(pieces
, 0, s
);
310 s
= PyString_FromString(n
== 1 ? ",)" : ")");
313 temp
= PyTuple_GET_ITEM(pieces
, n
-1);
314 PyString_ConcatAndDel(&temp
, s
);
315 PyTuple_SET_ITEM(pieces
, n
-1, temp
);
319 /* Paste them all together with ", " between. */
320 s
= PyString_FromString(", ");
323 result
= _PyString_Join(s
, pieces
);
328 Py_ReprLeave((PyObject
*)v
);
332 /* The addend 82520, was selected from the range(0, 1000000) for
333 generating the greatest number of prime multipliers for tuples
336 1082527, 1165049, 1082531, 1165057, 1247581, 1330103, 1082533,
337 1330111, 1412633, 1165069, 1247599, 1495177, 1577699
341 tuplehash(PyTupleObject
*v
)
344 register Py_ssize_t len
= Py_SIZE(v
);
345 register PyObject
**p
;
346 long mult
= 1000003L;
350 y
= PyObject_Hash(*p
++);
354 /* the cast might truncate len; that doesn't change hash stability */
355 mult
+= (long)(82520L + len
+ len
);
364 tuplelength(PyTupleObject
*a
)
370 tuplecontains(PyTupleObject
*a
, PyObject
*el
)
375 for (i
= 0, cmp
= 0 ; cmp
== 0 && i
< Py_SIZE(a
); ++i
)
376 cmp
= PyObject_RichCompareBool(el
, PyTuple_GET_ITEM(a
, i
),
382 tupleitem(register PyTupleObject
*a
, register Py_ssize_t i
)
384 if (i
< 0 || i
>= Py_SIZE(a
)) {
385 PyErr_SetString(PyExc_IndexError
, "tuple index out of range");
388 Py_INCREF(a
->ob_item
[i
]);
389 return a
->ob_item
[i
];
393 tupleslice(register PyTupleObject
*a
, register Py_ssize_t ilow
,
394 register Py_ssize_t ihigh
)
396 register PyTupleObject
*np
;
397 PyObject
**src
, **dest
;
398 register Py_ssize_t i
;
402 if (ihigh
> Py_SIZE(a
))
406 if (ilow
== 0 && ihigh
== Py_SIZE(a
) && PyTuple_CheckExact(a
)) {
408 return (PyObject
*)a
;
411 np
= (PyTupleObject
*)PyTuple_New(len
);
414 src
= a
->ob_item
+ ilow
;
416 for (i
= 0; i
< len
; i
++) {
417 PyObject
*v
= src
[i
];
421 return (PyObject
*)np
;
425 PyTuple_GetSlice(PyObject
*op
, Py_ssize_t i
, Py_ssize_t j
)
427 if (op
== NULL
|| !PyTuple_Check(op
)) {
428 PyErr_BadInternalCall();
431 return tupleslice((PyTupleObject
*)op
, i
, j
);
435 tupleconcat(register PyTupleObject
*a
, register PyObject
*bb
)
437 register Py_ssize_t size
;
438 register Py_ssize_t i
;
439 PyObject
**src
, **dest
;
441 if (!PyTuple_Check(bb
)) {
442 PyErr_Format(PyExc_TypeError
,
443 "can only concatenate tuple (not \"%.200s\") to tuple",
444 Py_TYPE(bb
)->tp_name
);
447 #define b ((PyTupleObject *)bb)
448 size
= Py_SIZE(a
) + Py_SIZE(b
);
450 return PyErr_NoMemory();
451 np
= (PyTupleObject
*) PyTuple_New(size
);
457 for (i
= 0; i
< Py_SIZE(a
); i
++) {
458 PyObject
*v
= src
[i
];
463 dest
= np
->ob_item
+ Py_SIZE(a
);
464 for (i
= 0; i
< Py_SIZE(b
); i
++) {
465 PyObject
*v
= src
[i
];
469 return (PyObject
*)np
;
474 tuplerepeat(PyTupleObject
*a
, Py_ssize_t n
)
479 PyObject
**p
, **items
;
482 if (Py_SIZE(a
) == 0 || n
== 1) {
483 if (PyTuple_CheckExact(a
)) {
484 /* Since tuples are immutable, we can return a shared
487 return (PyObject
*)a
;
490 return PyTuple_New(0);
492 size
= Py_SIZE(a
) * n
;
493 if (size
/Py_SIZE(a
) != n
)
494 return PyErr_NoMemory();
495 np
= (PyTupleObject
*) PyTuple_New(size
);
500 for (i
= 0; i
< n
; i
++) {
501 for (j
= 0; j
< Py_SIZE(a
); j
++) {
507 return (PyObject
*) np
;
511 tupleindex(PyTupleObject
*self
, PyObject
*args
)
513 Py_ssize_t i
, start
=0, stop
=Py_SIZE(self
);
516 if (!PyArg_ParseTuple(args
, "O|O&O&:index", &v
,
517 _PyEval_SliceIndex
, &start
,
518 _PyEval_SliceIndex
, &stop
))
521 start
+= Py_SIZE(self
);
526 stop
+= Py_SIZE(self
);
530 for (i
= start
; i
< stop
&& i
< Py_SIZE(self
); i
++) {
531 int cmp
= PyObject_RichCompareBool(self
->ob_item
[i
], v
, Py_EQ
);
533 return PyInt_FromSsize_t(i
);
537 PyErr_SetString(PyExc_ValueError
, "tuple.index(x): x not in tuple");
542 tuplecount(PyTupleObject
*self
, PyObject
*v
)
544 Py_ssize_t count
= 0;
547 for (i
= 0; i
< Py_SIZE(self
); i
++) {
548 int cmp
= PyObject_RichCompareBool(self
->ob_item
[i
], v
, Py_EQ
);
554 return PyInt_FromSsize_t(count
);
558 tupletraverse(PyTupleObject
*o
, visitproc visit
, void *arg
)
562 for (i
= Py_SIZE(o
); --i
>= 0; )
563 Py_VISIT(o
->ob_item
[i
]);
568 tuplerichcompare(PyObject
*v
, PyObject
*w
, int op
)
570 PyTupleObject
*vt
, *wt
;
572 Py_ssize_t vlen
, wlen
;
574 if (!PyTuple_Check(v
) || !PyTuple_Check(w
)) {
575 Py_INCREF(Py_NotImplemented
);
576 return Py_NotImplemented
;
579 vt
= (PyTupleObject
*)v
;
580 wt
= (PyTupleObject
*)w
;
585 /* Note: the corresponding code for lists has an "early out" test
586 * here when op is EQ or NE and the lengths differ. That pays there,
587 * but Tim was unable to find any real code where EQ/NE tuple
588 * compares don't have the same length, so testing for it here would
589 * have cost without benefit.
592 /* Search for the first index where items are different.
593 * Note that because tuples are immutable, it's safe to reuse
594 * vlen and wlen across the comparison calls.
596 for (i
= 0; i
< vlen
&& i
< wlen
; i
++) {
597 int k
= PyObject_RichCompareBool(vt
->ob_item
[i
],
598 wt
->ob_item
[i
], Py_EQ
);
605 if (i
>= vlen
|| i
>= wlen
) {
606 /* No more items to compare -- compare sizes */
610 case Py_LT
: cmp
= vlen
< wlen
; break;
611 case Py_LE
: cmp
= vlen
<= wlen
; break;
612 case Py_EQ
: cmp
= vlen
== wlen
; break;
613 case Py_NE
: cmp
= vlen
!= wlen
; break;
614 case Py_GT
: cmp
= vlen
> wlen
; break;
615 case Py_GE
: cmp
= vlen
>= wlen
; break;
616 default: return NULL
; /* cannot happen */
626 /* We have an item that differs -- shortcuts for EQ/NE */
636 /* Compare the final item again using the proper operator */
637 return PyObject_RichCompare(vt
->ob_item
[i
], wt
->ob_item
[i
], op
);
641 tuple_subtype_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
);
644 tuple_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
646 PyObject
*arg
= NULL
;
647 static char *kwlist
[] = {"sequence", 0};
649 if (type
!= &PyTuple_Type
)
650 return tuple_subtype_new(type
, args
, kwds
);
651 if (!PyArg_ParseTupleAndKeywords(args
, kwds
, "|O:tuple", kwlist
, &arg
))
655 return PyTuple_New(0);
657 return PySequence_Tuple(arg
);
661 tuple_subtype_new(PyTypeObject
*type
, PyObject
*args
, PyObject
*kwds
)
663 PyObject
*tmp
, *newobj
, *item
;
666 assert(PyType_IsSubtype(type
, &PyTuple_Type
));
667 tmp
= tuple_new(&PyTuple_Type
, args
, kwds
);
670 assert(PyTuple_Check(tmp
));
671 newobj
= type
->tp_alloc(type
, n
= PyTuple_GET_SIZE(tmp
));
674 for (i
= 0; i
< n
; i
++) {
675 item
= PyTuple_GET_ITEM(tmp
, i
);
677 PyTuple_SET_ITEM(newobj
, i
, item
);
683 PyDoc_STRVAR(tuple_doc
,
684 "tuple() -> an empty tuple\n"
685 "tuple(sequence) -> tuple initialized from sequence's items\n"
687 "If the argument is a tuple, the return value is the same object.");
689 static PySequenceMethods tuple_as_sequence
= {
690 (lenfunc
)tuplelength
, /* sq_length */
691 (binaryfunc
)tupleconcat
, /* sq_concat */
692 (ssizeargfunc
)tuplerepeat
, /* sq_repeat */
693 (ssizeargfunc
)tupleitem
, /* sq_item */
694 (ssizessizeargfunc
)tupleslice
, /* sq_slice */
696 0, /* sq_ass_slice */
697 (objobjproc
)tuplecontains
, /* sq_contains */
701 tuplesubscript(PyTupleObject
* self
, PyObject
* item
)
703 if (PyIndex_Check(item
)) {
704 Py_ssize_t i
= PyNumber_AsSsize_t(item
, PyExc_IndexError
);
705 if (i
== -1 && PyErr_Occurred())
708 i
+= PyTuple_GET_SIZE(self
);
709 return tupleitem(self
, i
);
711 else if (PySlice_Check(item
)) {
712 Py_ssize_t start
, stop
, step
, slicelength
, cur
, i
;
715 PyObject
**src
, **dest
;
717 if (PySlice_GetIndicesEx((PySliceObject
*)item
,
718 PyTuple_GET_SIZE(self
),
719 &start
, &stop
, &step
, &slicelength
) < 0) {
723 if (slicelength
<= 0) {
724 return PyTuple_New(0);
726 else if (start
== 0 && step
== 1 &&
727 slicelength
== PyTuple_GET_SIZE(self
) &&
728 PyTuple_CheckExact(self
)) {
730 return (PyObject
*)self
;
733 result
= PyTuple_New(slicelength
);
734 if (!result
) return NULL
;
737 dest
= ((PyTupleObject
*)result
)->ob_item
;
738 for (cur
= start
, i
= 0; i
< slicelength
;
749 PyErr_Format(PyExc_TypeError
,
750 "tuple indices must be integers, not %.200s",
751 Py_TYPE(item
)->tp_name
);
757 tuple_getnewargs(PyTupleObject
*v
)
759 return Py_BuildValue("(N)", tupleslice(v
, 0, Py_SIZE(v
)));
764 tuple_sizeof(PyTupleObject
*self
)
768 res
= PyTuple_Type
.tp_basicsize
+ Py_SIZE(self
) * sizeof(PyObject
*);
769 return PyInt_FromSsize_t(res
);
772 PyDoc_STRVAR(index_doc
,
773 "T.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
774 "Raises ValueError if the value is not present."
776 PyDoc_STRVAR(count_doc
,
777 "T.count(value) -> integer -- return number of occurrences of value");
778 PyDoc_STRVAR(sizeof_doc
,
779 "T.__sizeof__() -- size of T in memory, in bytes");
781 static PyMethodDef tuple_methods
[] = {
782 {"__getnewargs__", (PyCFunction
)tuple_getnewargs
, METH_NOARGS
},
783 {"__sizeof__", (PyCFunction
)tuple_sizeof
, METH_NOARGS
, sizeof_doc
},
784 {"index", (PyCFunction
)tupleindex
, METH_VARARGS
, index_doc
},
785 {"count", (PyCFunction
)tuplecount
, METH_O
, count_doc
},
786 {NULL
, NULL
} /* sentinel */
789 static PyMappingMethods tuple_as_mapping
= {
790 (lenfunc
)tuplelength
,
791 (binaryfunc
)tuplesubscript
,
795 static PyObject
*tuple_iter(PyObject
*seq
);
797 PyTypeObject PyTuple_Type
= {
798 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
800 sizeof(PyTupleObject
) - sizeof(PyObject
*),
802 (destructor
)tupledealloc
, /* tp_dealloc */
803 (printfunc
)tupleprint
, /* tp_print */
807 (reprfunc
)tuplerepr
, /* tp_repr */
808 0, /* tp_as_number */
809 &tuple_as_sequence
, /* tp_as_sequence */
810 &tuple_as_mapping
, /* tp_as_mapping */
811 (hashfunc
)tuplehash
, /* tp_hash */
814 PyObject_GenericGetAttr
, /* tp_getattro */
816 0, /* tp_as_buffer */
817 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
|
818 Py_TPFLAGS_BASETYPE
| Py_TPFLAGS_TUPLE_SUBCLASS
, /* tp_flags */
819 tuple_doc
, /* tp_doc */
820 (traverseproc
)tupletraverse
, /* tp_traverse */
822 tuplerichcompare
, /* tp_richcompare */
823 0, /* tp_weaklistoffset */
824 tuple_iter
, /* tp_iter */
826 tuple_methods
, /* tp_methods */
831 0, /* tp_descr_get */
832 0, /* tp_descr_set */
833 0, /* tp_dictoffset */
836 tuple_new
, /* tp_new */
837 PyObject_GC_Del
, /* tp_free */
840 /* The following function breaks the notion that tuples are immutable:
841 it changes the size of a tuple. We get away with this only if there
842 is only one module referencing the object. You can also think of it
843 as creating a new tuple object and destroying the old one, only more
844 efficiently. In any case, don't use this if the tuple may already be
845 known to some other part of the code. */
848 _PyTuple_Resize(PyObject
**pv
, Py_ssize_t newsize
)
850 register PyTupleObject
*v
;
851 register PyTupleObject
*sv
;
855 v
= (PyTupleObject
*) *pv
;
856 if (v
== NULL
|| Py_TYPE(v
) != &PyTuple_Type
||
857 (Py_SIZE(v
) != 0 && Py_REFCNT(v
) != 1)) {
860 PyErr_BadInternalCall();
863 oldsize
= Py_SIZE(v
);
864 if (oldsize
== newsize
)
868 /* Empty tuples are often shared, so we should never
869 resize them in-place even if we do own the only
870 (current) reference */
872 *pv
= PyTuple_New(newsize
);
873 return *pv
== NULL
? -1 : 0;
876 /* XXX UNREF/NEWREF interface should be more symmetrical */
878 _PyObject_GC_UNTRACK(v
);
879 _Py_ForgetReference((PyObject
*) v
);
880 /* DECREF items deleted by shrinkage */
881 for (i
= newsize
; i
< oldsize
; i
++) {
882 Py_XDECREF(v
->ob_item
[i
]);
883 v
->ob_item
[i
] = NULL
;
885 sv
= PyObject_GC_Resize(PyTupleObject
, v
, newsize
);
891 _Py_NewReference((PyObject
*) sv
);
892 /* Zero out items added by growing */
893 if (newsize
> oldsize
)
894 memset(&sv
->ob_item
[oldsize
], 0,
895 sizeof(*sv
->ob_item
) * (newsize
- oldsize
));
896 *pv
= (PyObject
*) sv
;
897 _PyObject_GC_TRACK(sv
);
902 PyTuple_ClearFreeList(void)
904 int freelist_size
= 0;
905 #if PyTuple_MAXSAVESIZE > 0
907 for (i
= 1; i
< PyTuple_MAXSAVESIZE
; i
++) {
908 PyTupleObject
*p
, *q
;
910 freelist_size
+= numfree
[i
];
915 p
= (PyTupleObject
*)(p
->ob_item
[0]);
920 return freelist_size
;
926 #if PyTuple_MAXSAVESIZE > 0
927 /* empty tuples are used all over the place and applications may
928 * rely on the fact that an empty tuple is a singleton. */
929 Py_XDECREF(free_list
[0]);
932 (void)PyTuple_ClearFreeList();
934 #ifdef SHOW_TRACK_COUNT
939 /*********************** Tuple Iterator **************************/
944 PyTupleObject
*it_seq
; /* Set to NULL when iterator is exhausted */
948 tupleiter_dealloc(tupleiterobject
*it
)
950 _PyObject_GC_UNTRACK(it
);
951 Py_XDECREF(it
->it_seq
);
956 tupleiter_traverse(tupleiterobject
*it
, visitproc visit
, void *arg
)
958 Py_VISIT(it
->it_seq
);
963 tupleiter_next(tupleiterobject
*it
)
972 assert(PyTuple_Check(seq
));
974 if (it
->it_index
< PyTuple_GET_SIZE(seq
)) {
975 item
= PyTuple_GET_ITEM(seq
, it
->it_index
);
987 tupleiter_len(tupleiterobject
*it
)
991 len
= PyTuple_GET_SIZE(it
->it_seq
) - it
->it_index
;
992 return PyInt_FromSsize_t(len
);
995 PyDoc_STRVAR(length_hint_doc
, "Private method returning an estimate of len(list(it)).");
997 static PyMethodDef tupleiter_methods
[] = {
998 {"__length_hint__", (PyCFunction
)tupleiter_len
, METH_NOARGS
, length_hint_doc
},
999 {NULL
, NULL
} /* sentinel */
1002 PyTypeObject PyTupleIter_Type
= {
1003 PyVarObject_HEAD_INIT(&PyType_Type
, 0)
1004 "tupleiterator", /* tp_name */
1005 sizeof(tupleiterobject
), /* tp_basicsize */
1006 0, /* tp_itemsize */
1008 (destructor
)tupleiter_dealloc
, /* tp_dealloc */
1014 0, /* tp_as_number */
1015 0, /* tp_as_sequence */
1016 0, /* tp_as_mapping */
1020 PyObject_GenericGetAttr
, /* tp_getattro */
1021 0, /* tp_setattro */
1022 0, /* tp_as_buffer */
1023 Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_HAVE_GC
,/* tp_flags */
1025 (traverseproc
)tupleiter_traverse
, /* tp_traverse */
1027 0, /* tp_richcompare */
1028 0, /* tp_weaklistoffset */
1029 PyObject_SelfIter
, /* tp_iter */
1030 (iternextfunc
)tupleiter_next
, /* tp_iternext */
1031 tupleiter_methods
, /* tp_methods */
1036 tuple_iter(PyObject
*seq
)
1038 tupleiterobject
*it
;
1040 if (!PyTuple_Check(seq
)) {
1041 PyErr_BadInternalCall();
1044 it
= PyObject_GC_New(tupleiterobject
, &PyTupleIter_Type
);
1049 it
->it_seq
= (PyTupleObject
*)seq
;
1050 _PyObject_GC_TRACK(it
);
1051 return (PyObject
*)it
;