mirror of https://github.com/python/cpython
Issue #20186: Converted builtins enumerate() and reversed() to Argument Clinic.
Patch by Tal Einat.
This commit is contained in:
parent
c9ea933586
commit
41baebd8b9
|
@ -0,0 +1,71 @@
|
||||||
|
/*[clinic input]
|
||||||
|
preserve
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
PyDoc_STRVAR(enum_new__doc__,
|
||||||
|
"enumerate(iterable, start=0)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return an enumerate object.\n"
|
||||||
|
"\n"
|
||||||
|
" iterable\n"
|
||||||
|
" an object supporting iteration\n"
|
||||||
|
"\n"
|
||||||
|
"The enumerate object yields pairs containing a count (from start, which\n"
|
||||||
|
"defaults to zero) and a value yielded by the iterable argument.\n"
|
||||||
|
"\n"
|
||||||
|
"enumerate is useful for obtaining an indexed list:\n"
|
||||||
|
" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
enum_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
static const char * const _keywords[] = {"iterable", "start", NULL};
|
||||||
|
static _PyArg_Parser _parser = {"O|O:enumerate", _keywords, 0};
|
||||||
|
PyObject *iterable;
|
||||||
|
PyObject *start = 0;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
|
||||||
|
&iterable, &start)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = enum_new_impl(type, iterable, start);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(reversed_new__doc__,
|
||||||
|
"reversed(sequence, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return a reverse iterator over the values of the given sequence.");
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
reversed_new_impl(PyTypeObject *type, PyObject *seq);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *seq;
|
||||||
|
|
||||||
|
if ((type == &PyReversed_Type) &&
|
||||||
|
!_PyArg_NoKeywords("reversed", kwargs)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!PyArg_UnpackTuple(args, "reversed",
|
||||||
|
1, 1,
|
||||||
|
&seq)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = reversed_new_impl(type, seq);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
/*[clinic end generated code: output=9008c36999c57218 input=a9049054013a1b77]*/
|
|
@ -2,6 +2,14 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
|
#include "clinic/enumobject.c.h"
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
class enumerate "enumobject *" "&PyEnum_Type"
|
||||||
|
class reversed "reversedobject *" "&PyReversed_Type"
|
||||||
|
[clinic start generated code]*/
|
||||||
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=d2dfdf1a88c88975]*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
Py_ssize_t en_index; /* current index of enumeration */
|
Py_ssize_t en_index; /* current index of enumeration */
|
||||||
|
@ -10,17 +18,29 @@ typedef struct {
|
||||||
PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */
|
PyObject* en_longindex; /* index for sequences >= PY_SSIZE_T_MAX */
|
||||||
} enumobject;
|
} enumobject;
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
@classmethod
|
||||||
|
enumerate.__new__ as enum_new
|
||||||
|
|
||||||
|
iterable: object
|
||||||
|
an object supporting iteration
|
||||||
|
start: object = 0
|
||||||
|
|
||||||
|
Return an enumerate object.
|
||||||
|
|
||||||
|
The enumerate object yields pairs containing a count (from start, which
|
||||||
|
defaults to zero) and a value yielded by the iterable argument.
|
||||||
|
|
||||||
|
enumerate is useful for obtaining an indexed list:
|
||||||
|
(0, seq[0]), (1, seq[1]), (2, seq[2]), ...
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start)
|
||||||
|
/*[clinic end generated code: output=e95e6e439f812c10 input=782e4911efcb8acf]*/
|
||||||
{
|
{
|
||||||
enumobject *en;
|
enumobject *en;
|
||||||
PyObject *seq = NULL;
|
|
||||||
PyObject *start = NULL;
|
|
||||||
static char *kwlist[] = {"iterable", "start", 0};
|
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:enumerate", kwlist,
|
|
||||||
&seq, &start))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
en = (enumobject *)type->tp_alloc(type, 0);
|
en = (enumobject *)type->tp_alloc(type, 0);
|
||||||
if (en == NULL)
|
if (en == NULL)
|
||||||
|
@ -45,7 +65,7 @@ enum_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
||||||
en->en_index = 0;
|
en->en_index = 0;
|
||||||
en->en_longindex = NULL;
|
en->en_longindex = NULL;
|
||||||
}
|
}
|
||||||
en->en_sit = PyObject_GetIter(seq);
|
en->en_sit = PyObject_GetIter(iterable);
|
||||||
if (en->en_sit == NULL) {
|
if (en->en_sit == NULL) {
|
||||||
Py_DECREF(en);
|
Py_DECREF(en);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -174,15 +194,6 @@ static PyMethodDef enum_methods[] = {
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyDoc_STRVAR(enum_doc,
|
|
||||||
"enumerate(iterable[, start]) -> iterator for index, value of iterable\n"
|
|
||||||
"\n"
|
|
||||||
"Return an enumerate object. iterable must be another object that supports\n"
|
|
||||||
"iteration. The enumerate object yields pairs containing a count (from\n"
|
|
||||||
"start, which defaults to zero) and a value yielded by the iterable argument.\n"
|
|
||||||
"enumerate is useful for obtaining an indexed list:\n"
|
|
||||||
" (0, seq[0]), (1, seq[1]), (2, seq[2]), ...");
|
|
||||||
|
|
||||||
PyTypeObject PyEnum_Type = {
|
PyTypeObject PyEnum_Type = {
|
||||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||||
"enumerate", /* tp_name */
|
"enumerate", /* tp_name */
|
||||||
|
@ -205,13 +216,13 @@ PyTypeObject PyEnum_Type = {
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
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, /* tp_flags */
|
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
enum_doc, /* tp_doc */
|
enum_new__doc__, /* tp_doc */
|
||||||
(traverseproc)enum_traverse, /* tp_traverse */
|
(traverseproc)enum_traverse, /* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)enum_next, /* tp_iternext */
|
(iternextfunc)enum_next, /* tp_iternext */
|
||||||
enum_methods, /* tp_methods */
|
enum_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
|
@ -235,20 +246,25 @@ typedef struct {
|
||||||
PyObject* seq;
|
PyObject* seq;
|
||||||
} reversedobject;
|
} reversedobject;
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
@classmethod
|
||||||
|
reversed.__new__ as reversed_new
|
||||||
|
|
||||||
|
sequence as seq: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Return a reverse iterator over the values of the given sequence.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
reversed_new_impl(PyTypeObject *type, PyObject *seq)
|
||||||
|
/*[clinic end generated code: output=f7854cc1df26f570 input=aeb720361e5e3f1d]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
PyObject *seq, *reversed_meth;
|
PyObject *reversed_meth;
|
||||||
reversedobject *ro;
|
reversedobject *ro;
|
||||||
_Py_IDENTIFIER(__reversed__);
|
_Py_IDENTIFIER(__reversed__);
|
||||||
|
|
||||||
if (type == &PyReversed_Type && !_PyArg_NoKeywords("reversed()", kwds))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!PyArg_UnpackTuple(args, "reversed", 1, 1, &seq) )
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__);
|
reversed_meth = _PyObject_LookupSpecial(seq, &PyId___reversed__);
|
||||||
if (reversed_meth == Py_None) {
|
if (reversed_meth == Py_None) {
|
||||||
Py_DECREF(reversed_meth);
|
Py_DECREF(reversed_meth);
|
||||||
|
@ -322,11 +338,6 @@ reversed_next(reversedobject *ro)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(reversed_doc,
|
|
||||||
"reversed(sequence) -> reverse iterator over values of the sequence\n"
|
|
||||||
"\n"
|
|
||||||
"Return a reverse iterator");
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
reversed_len(reversedobject *ro)
|
reversed_len(reversedobject *ro)
|
||||||
{
|
{
|
||||||
|
@ -393,7 +404,7 @@ PyTypeObject PyReversed_Type = {
|
||||||
0, /* tp_reserved */
|
0, /* tp_reserved */
|
||||||
0, /* tp_repr */
|
0, /* tp_repr */
|
||||||
0, /* tp_as_number */
|
0, /* tp_as_number */
|
||||||
0, /* tp_as_sequence */
|
0, /* tp_as_sequence */
|
||||||
0, /* tp_as_mapping */
|
0, /* tp_as_mapping */
|
||||||
0, /* tp_hash */
|
0, /* tp_hash */
|
||||||
0, /* tp_call */
|
0, /* tp_call */
|
||||||
|
@ -402,15 +413,15 @@ PyTypeObject PyReversed_Type = {
|
||||||
0, /* tp_setattro */
|
0, /* tp_setattro */
|
||||||
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, /* tp_flags */
|
Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
reversed_doc, /* tp_doc */
|
reversed_new__doc__, /* tp_doc */
|
||||||
(traverseproc)reversed_traverse,/* tp_traverse */
|
(traverseproc)reversed_traverse,/* tp_traverse */
|
||||||
0, /* tp_clear */
|
0, /* tp_clear */
|
||||||
0, /* tp_richcompare */
|
0, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
PyObject_SelfIter, /* tp_iter */
|
PyObject_SelfIter, /* tp_iter */
|
||||||
(iternextfunc)reversed_next, /* tp_iternext */
|
(iternextfunc)reversed_next, /* tp_iternext */
|
||||||
reversediter_methods, /* tp_methods */
|
reversediter_methods, /* tp_methods */
|
||||||
0, /* tp_members */
|
0, /* tp_members */
|
||||||
0, /* tp_getset */
|
0, /* tp_getset */
|
||||||
0, /* tp_base */
|
0, /* tp_base */
|
||||||
|
|
Loading…
Reference in New Issue