Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 41baebd

Browse files
Issue python#20186: Converted builtins enumerate() and reversed() to Argument Clinic.
Patch by Tal Einat.
1 parent c9ea933 commit 41baebd

File tree

2 files changed

+121
-39
lines changed

2 files changed

+121
-39
lines changed

Objects/clinic/enumobject.c.h

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*[clinic input]
2+
preserve
3+
[clinic start generated code]*/
4+
5+
PyDoc_STRVAR(enum_new__doc__,
6+
"enumerate(iterable, start=0)\n"
7+
"--\n"
8+
"\n"
9+
"Return an enumerate object.\n"
10+
"\n"
11+
" iterable\n"
12+
" an object supporting iteration\n"
13+
"\n"
14+
"The enumerate object yields pairs containing a count (from start, which\n"
15+
"defaults to zero) and a value yielded by the iterable argument.\n"
16+
"\n"
17+
"enumerate is useful for obtaining an indexed list:\n"
18+
" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
19+
20+
static PyObject *
21+
enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start);
22+
23+
static PyObject *
24+
enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
25+
{
26+
PyObject *return_value = NULL;
27+
static const char * const _keywords[] = {"iterable", "start", NULL};
28+
static _PyArg_Parser _parser = {"O|O:enumerate", _keywords, 0};
29+
PyObject *iterable;
30+
PyObject *start = 0;
31+
32+
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
33+
&iterable, &start)) {
34+
goto exit;
35+
}
36+
return_value = enum_new_impl(type, iterable, start);
37+
38+
exit:
39+
return return_value;
40+
}
41+
42+
PyDoc_STRVAR(reversed_new__doc__,
43+
"reversed(sequence, /)\n"
44+
"--\n"
45+
"\n"
46+
"Return a reverse iterator over the values of the given sequence.");
47+
48+
static PyObject *
49+
reversed_new_impl(PyTypeObject *type, PyObject *seq);
50+
51+
static PyObject *
52+
reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
53+
{
54+
PyObject *return_value = NULL;
55+
PyObject *seq;
56+
57+
if ((type == &PyReversed_Type) &&
58+
!_PyArg_NoKeywords("reversed", kwargs)) {
59+
goto exit;
60+
}
61+
if (!PyArg_UnpackTuple(args, "reversed",
62+
1, 1,
63+
&seq)) {
64+
goto exit;
65+
}
66+
return_value = reversed_new_impl(type, seq);
67+
68+
exit:
69+
return return_value;
70+
}
71+
/*[clinic end generated code: output=9008c36999c57218 input=a9049054013a1b77]*/

Objects/enumobject.c

Lines changed: 50 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
#include "Python.h"
44

5+
#include "clinic/enumobject.c.h"
6+
7+
/*[clinic input]
8+
class enumerate "enumobject *" "&PyEnum_Type"
9+
class reversed "reversedobject *" "&PyReversed_Type"
10+
[clinic start generated code]*/
11+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d2dfdf1a88c88975]*/
12+
513
typedef struct {
614
PyObject_HEAD
715
Py_ssize_t en_index; /* current index of enumeration */
@@ -10,17 +18,29 @@ typedef struct {
1018
PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */
1119
} enumobject;
1220

21+
22+
/*[clinic input]
23+
@classmethod
24+
enumerate.__new__ as enum_new
25+
26+
iterable: object
27+
an object supporting iteration
28+
start: object = 0
29+
30+
Return an enumerate object.
31+
32+
The enumerate object yields pairs containing a count (from start, which
33+
defaults to zero) and a value yielded by the iterable argument.
34+
35+
enumerate is useful for obtaining an indexed list:
36+
(0, seq[0]), (1, seq[1]), (2, seq[2]), ...
37+
[clinic start generated code]*/
38+
1339
static PyObject *
14-
enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
40+
enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start)
41+
/*[clinic end generated code: output=e95e6e439f812c10 input=782e4911efcb8acf]*/
1542
{
1643
enumobject *en;
17-
PyObject *seq = NULL;
18-
PyObject *start = NULL;
19-
static char *kwlist[] = {"iterable", "start", 0};
20-
21-
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
22-
&seq, &start))
23-
return NULL;
2444

2545
en = (enumobject *)type->tp_alloc(type, 0);
2646
if (en == NULL)
@@ -45,7 +65,7 @@ enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
4565
en->en_index = 0;
4666
en->en_longindex = NULL;
4767
}
48-
en->en_sit = PyObject_GetIter(seq);
68+
en->en_sit = PyObject_GetIter(iterable);
4969
if (en->en_sit == NULL) {
5070
Py_DECREF(en);
5171
return NULL;
@@ -174,15 +194,6 @@ static PyMethodDef enum_methods[] = {
174194
{NULL, NULL} /* sentinel */
175195
};
176196

177-
PyDoc_STRVAR(enum_doc,
178-
"enumerate(iterable[, start]) -> iterator for index, value of iterable\n"
179-
"\n"
180-
"Return an enumerate object. iterable must be another object that supports\n"
181-
"iteration. The enumerate object yields pairs containing a count (from\n"
182-
"start, which defaults to zero) and a value yielded by the iterable argument.\n"
183-
"enumerate is useful for obtaining an indexed list:\n"
184-
" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
185-
186197
PyTypeObject PyEnum_Type = {
187198
PyVarObject_HEAD_INIT(&PyType_Type, 0)
188199
"enumerate", /* tp_name */
@@ -205,13 +216,13 @@ PyTypeObject PyEnum_Type = {
205216
0, /* tp_setattro */
206217
0, /* tp_as_buffer */
207218
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
208-
Py_TPFLAGS_BASETYPE, /* tp_flags */
209-
enum_doc, /* tp_doc */
219+
Py_TPFLAGS_BASETYPE, /* tp_flags */
220+
enum_new__doc__, /* tp_doc */
210221
(traverseproc)enum_traverse, /* tp_traverse */
211222
0, /* tp_clear */
212223
0, /* tp_richcompare */
213224
0, /* tp_weaklistoffset */
214-
PyObject_SelfIter, /* tp_iter */
225+
PyObject_SelfIter, /* tp_iter */
215226
(iternextfunc)enum_next, /* tp_iternext */
216227
enum_methods, /* tp_methods */
217228
0, /* tp_members */
@@ -235,20 +246,25 @@ typedef struct {
235246
PyObject* seq;
236247
} reversedobject;
237248

249+
/*[clinic input]
250+
@classmethod
251+
reversed.__new__ as reversed_new
252+
253+
sequence as seq: object
254+
/
255+
256+
Return a reverse iterator over the values of the given sequence.
257+
[clinic start generated code]*/
258+
238259
static PyObject *
239-
reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
260+
reversed_new_impl(PyTypeObject *type, PyObject *seq)
261+
/*[clinic end generated code: output=f7854cc1df26f570 input=aeb720361e5e3f1d]*/
240262
{
241263
Py_ssize_t n;
242-
PyObject *seq, *reversed_meth;
264+
PyObject *reversed_meth;
243265
reversedobject *ro;
244266
_Py_IDENTIFIER(__reversed__);
245267

246-
if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
247-
return NULL;
248-
249-
if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
250-
return NULL;
251-
252268
reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__);
253269
if (reversed_meth == Py_None) {
254270
Py_DECREF(reversed_meth);
@@ -322,11 +338,6 @@ reversed_next(reversedobject *ro)
322338
return NULL;
323339
}
324340

325-
PyDoc_STRVAR(reversed_doc,
326-
"reversed(sequence) -> reverse iterator over values of the sequence\n"
327-
"\n"
328-
"Return a reverse iterator");
329-
330341
static PyObject *
331342
reversed_len(reversedobject *ro)
332343
{
@@ -393,7 +404,7 @@ PyTypeObject PyReversed_Type = {
393404
0, /* tp_reserved */
394405
0, /* tp_repr */
395406
0, /* tp_as_number */
396-
0, /* tp_as_sequence */
407+
0, /* tp_as_sequence */
397408
0, /* tp_as_mapping */
398409
0, /* tp_hash */
399410
0, /* tp_call */
@@ -402,15 +413,15 @@ PyTypeObject PyReversed_Type = {
402413
0, /* tp_setattro */
403414
0, /* tp_as_buffer */
404415
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
405-
Py_TPFLAGS_BASETYPE, /* tp_flags */
406-
reversed_doc, /* tp_doc */
416+
Py_TPFLAGS_BASETYPE, /* tp_flags */
417+
reversed_new__doc__, /* tp_doc */
407418
(traverseproc)reversed_traverse,/* tp_traverse */
408419
0, /* tp_clear */
409420
0, /* tp_richcompare */
410421
0, /* tp_weaklistoffset */
411-
PyObject_SelfIter, /* tp_iter */
422+
PyObject_SelfIter, /* tp_iter */
412423
(iternextfunc)reversed_next, /* tp_iternext */
413-
reversediter_methods, /* tp_methods */
424+
reversediter_methods, /* tp_methods */
414425
0, /* tp_members */
415426
0, /* tp_getset */
416427
0, /* tp_base */

0 commit comments

Comments
 (0)