mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-20185: Convert list object implementation to Argument Clinic. (#542)
This commit is contained in:
parent
0710d75425
commit
fdd42c481e
3 changed files with 529 additions and 156 deletions
|
@ -58,7 +58,7 @@ class Get_signatureTest(unittest.TestCase):
|
||||||
'Create and return a new object. See help(type) for accurate signature.')
|
'Create and return a new object. See help(type) for accurate signature.')
|
||||||
gtest(list.__init__,
|
gtest(list.__init__,
|
||||||
'Initialize self. See help(type(self)) for accurate signature.')
|
'Initialize self. See help(type(self)) for accurate signature.')
|
||||||
append_doc = "L.append(object) -> None -- append object to end"
|
append_doc = "Append object to the end of the list."
|
||||||
gtest(list.append, append_doc)
|
gtest(list.append, append_doc)
|
||||||
gtest([].append, append_doc)
|
gtest([].append, append_doc)
|
||||||
gtest(List.append, append_doc)
|
gtest(List.append, append_doc)
|
||||||
|
@ -81,9 +81,9 @@ class Get_signatureTest(unittest.TestCase):
|
||||||
|
|
||||||
def test_multiline_docstring(self):
|
def test_multiline_docstring(self):
|
||||||
# Test fewer lines than max.
|
# Test fewer lines than max.
|
||||||
self.assertEqual(signature(list),
|
self.assertEqual(signature(range),
|
||||||
"list() -> new empty list\n"
|
"range(stop) -> range object\n"
|
||||||
"list(iterable) -> new list initialized from iterable's items")
|
"range(start, stop[, step]) -> range object")
|
||||||
|
|
||||||
# Test max lines
|
# Test max lines
|
||||||
self.assertEqual(signature(bytes), '''\
|
self.assertEqual(signature(bytes), '''\
|
||||||
|
|
300
Objects/clinic/listobject.c.h
Normal file
300
Objects/clinic/listobject.c.h
Normal file
|
@ -0,0 +1,300 @@
|
||||||
|
/*[clinic input]
|
||||||
|
preserve
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_insert__doc__,
|
||||||
|
"insert($self, index, object, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Insert object before index.");
|
||||||
|
|
||||||
|
#define LIST_INSERT_METHODDEF \
|
||||||
|
{"insert", (PyCFunction)list_insert, METH_FASTCALL, list_insert__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_insert(PyListObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
Py_ssize_t index;
|
||||||
|
PyObject *object;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStack(args, nargs, "nO:insert",
|
||||||
|
&index, &object)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_PyArg_NoStackKeywords("insert", kwnames)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = list_insert_impl(self, index, object);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_clear__doc__,
|
||||||
|
"clear($self, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Remove all items from list.");
|
||||||
|
|
||||||
|
#define LIST_CLEAR_METHODDEF \
|
||||||
|
{"clear", (PyCFunction)list_clear, METH_NOARGS, list_clear__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_clear_impl(PyListObject *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_clear(PyListObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return list_clear_impl(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_copy__doc__,
|
||||||
|
"copy($self, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return a shallow copy of the list.");
|
||||||
|
|
||||||
|
#define LIST_COPY_METHODDEF \
|
||||||
|
{"copy", (PyCFunction)list_copy, METH_NOARGS, list_copy__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_copy_impl(PyListObject *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_copy(PyListObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return list_copy_impl(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_append__doc__,
|
||||||
|
"append($self, object, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Append object to the end of the list.");
|
||||||
|
|
||||||
|
#define LIST_APPEND_METHODDEF \
|
||||||
|
{"append", (PyCFunction)list_append, METH_O, list_append__doc__},
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_extend__doc__,
|
||||||
|
"extend($self, iterable, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Extend list by appending elements from the iterable.");
|
||||||
|
|
||||||
|
#define LIST_EXTEND_METHODDEF \
|
||||||
|
{"extend", (PyCFunction)list_extend, METH_O, list_extend__doc__},
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_pop__doc__,
|
||||||
|
"pop($self, index=-1, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Remove and return item at index (default last).\n"
|
||||||
|
"\n"
|
||||||
|
"Raises IndexError if list is empty or index is out of range.");
|
||||||
|
|
||||||
|
#define LIST_POP_METHODDEF \
|
||||||
|
{"pop", (PyCFunction)list_pop, METH_FASTCALL, list_pop__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_pop_impl(PyListObject *self, Py_ssize_t index);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_pop(PyListObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
Py_ssize_t index = -1;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStack(args, nargs, "|n:pop",
|
||||||
|
&index)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_PyArg_NoStackKeywords("pop", kwnames)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = list_pop_impl(self, index);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_sort__doc__,
|
||||||
|
"sort($self, /, *, key=None, reverse=False)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Stable sort *IN PLACE*.");
|
||||||
|
|
||||||
|
#define LIST_SORT_METHODDEF \
|
||||||
|
{"sort", (PyCFunction)list_sort, METH_FASTCALL, list_sort__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_sort(PyListObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
static const char * const _keywords[] = {"key", "reverse", NULL};
|
||||||
|
static _PyArg_Parser _parser = {"|$Oi:sort", _keywords, 0};
|
||||||
|
PyObject *keyfunc = Py_None;
|
||||||
|
int reverse = 0;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser,
|
||||||
|
&keyfunc, &reverse)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = list_sort_impl(self, keyfunc, reverse);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_reverse__doc__,
|
||||||
|
"reverse($self, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Reverse *IN PLACE*.");
|
||||||
|
|
||||||
|
#define LIST_REVERSE_METHODDEF \
|
||||||
|
{"reverse", (PyCFunction)list_reverse, METH_NOARGS, list_reverse__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_reverse_impl(PyListObject *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_reverse(PyListObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return list_reverse_impl(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_index__doc__,
|
||||||
|
"index($self, value, start=0, stop=sys.maxsize, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return first index of value.\n"
|
||||||
|
"\n"
|
||||||
|
"Raises ValueError if the value is not present.");
|
||||||
|
|
||||||
|
#define LIST_INDEX_METHODDEF \
|
||||||
|
{"index", (PyCFunction)list_index, METH_FASTCALL, list_index__doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start,
|
||||||
|
Py_ssize_t stop);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_index(PyListObject *self, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
PyObject *value;
|
||||||
|
Py_ssize_t start = 0;
|
||||||
|
Py_ssize_t stop = PY_SSIZE_T_MAX;
|
||||||
|
|
||||||
|
if (!_PyArg_ParseStack(args, nargs, "O|O&O&:index",
|
||||||
|
&value, _PyEval_SliceIndex, &start, _PyEval_SliceIndex, &stop)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_PyArg_NoStackKeywords("index", kwnames)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = list_index_impl(self, value, start, stop);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_count__doc__,
|
||||||
|
"count($self, value, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return number of occurrences of value.");
|
||||||
|
|
||||||
|
#define LIST_COUNT_METHODDEF \
|
||||||
|
{"count", (PyCFunction)list_count, METH_O, list_count__doc__},
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list_remove__doc__,
|
||||||
|
"remove($self, value, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Remove first occurrence of value.\n"
|
||||||
|
"\n"
|
||||||
|
"Raises ValueError if the value is not present.");
|
||||||
|
|
||||||
|
#define LIST_REMOVE_METHODDEF \
|
||||||
|
{"remove", (PyCFunction)list_remove, METH_O, list_remove__doc__},
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list___init____doc__,
|
||||||
|
"list(iterable=(), /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Built-in mutable sequence.\n"
|
||||||
|
"\n"
|
||||||
|
"If no argument is given, the constructor creates a new empty list.\n"
|
||||||
|
"The argument must be an iterable if specified.");
|
||||||
|
|
||||||
|
static int
|
||||||
|
list___init___impl(PyListObject *self, PyObject *iterable);
|
||||||
|
|
||||||
|
static int
|
||||||
|
list___init__(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
|
{
|
||||||
|
int return_value = -1;
|
||||||
|
PyObject *iterable = NULL;
|
||||||
|
|
||||||
|
if ((Py_TYPE(self) == &PyList_Type) &&
|
||||||
|
!_PyArg_NoKeywords("list", kwargs)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
if (!PyArg_UnpackTuple(args, "list",
|
||||||
|
0, 1,
|
||||||
|
&iterable)) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
return_value = list___init___impl((PyListObject *)self, iterable);
|
||||||
|
|
||||||
|
exit:
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list___sizeof____doc__,
|
||||||
|
"__sizeof__($self, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return the size of the list in memory, in bytes.");
|
||||||
|
|
||||||
|
#define LIST___SIZEOF___METHODDEF \
|
||||||
|
{"__sizeof__", (PyCFunction)list___sizeof__, METH_NOARGS, list___sizeof____doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list___sizeof___impl(PyListObject *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list___sizeof__(PyListObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return list___sizeof___impl(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
PyDoc_STRVAR(list___reversed____doc__,
|
||||||
|
"__reversed__($self, /)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
"Return a reverse iterator over the list.");
|
||||||
|
|
||||||
|
#define LIST___REVERSED___METHODDEF \
|
||||||
|
{"__reversed__", (PyCFunction)list___reversed__, METH_NOARGS, list___reversed____doc__},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list___reversed___impl(PyListObject *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list___reversed__(PyListObject *self, PyObject *Py_UNUSED(ignored))
|
||||||
|
{
|
||||||
|
return list___reversed___impl(self);
|
||||||
|
}
|
||||||
|
/*[clinic end generated code: output=2a3b75efcf858ed5 input=a9049054013a1b77]*/
|
|
@ -9,6 +9,13 @@
|
||||||
#include <sys/types.h> /* For size_t */
|
#include <sys/types.h> /* For size_t */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
class list "PyListObject *" "&PyList_Type"
|
||||||
|
[clinic start generated code]*/
|
||||||
|
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=f9b222678f9f71e0]*/
|
||||||
|
|
||||||
|
#include "clinic/listobject.c.h"
|
||||||
|
|
||||||
/* Ensure ob_item has room for at least newsize elements, and set
|
/* Ensure ob_item has room for at least newsize elements, and set
|
||||||
* ob_size to newsize. If newsize > ob_size on entry, the content
|
* ob_size to newsize. If newsize > ob_size on entry, the content
|
||||||
* of the new slots at exit is undefined heap trash; it's the caller's
|
* of the new slots at exit is undefined heap trash; it's the caller's
|
||||||
|
@ -542,7 +549,7 @@ list_repeat(PyListObject *a, Py_ssize_t n)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
list_clear(PyListObject *a)
|
_list_clear(PyListObject *a)
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject **item = a->ob_item;
|
PyObject **item = a->ob_item;
|
||||||
|
@ -624,7 +631,7 @@ list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
|
||||||
d = n - norig;
|
d = n - norig;
|
||||||
if (Py_SIZE(a) + d == 0) {
|
if (Py_SIZE(a) + d == 0) {
|
||||||
Py_XDECREF(v_as_SF);
|
Py_XDECREF(v_as_SF);
|
||||||
return list_clear(a);
|
return _list_clear(a);
|
||||||
}
|
}
|
||||||
item = a->ob_item;
|
item = a->ob_item;
|
||||||
/* recycle the items that we are about to remove */
|
/* recycle the items that we are about to remove */
|
||||||
|
@ -700,7 +707,7 @@ list_inplace_repeat(PyListObject *self, Py_ssize_t n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n < 1) {
|
if (n < 1) {
|
||||||
(void)list_clear(self);
|
(void)_list_clear(self);
|
||||||
Py_INCREF(self);
|
Py_INCREF(self);
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
@ -740,45 +747,86 @@ list_ass_item(PyListObject *a, Py_ssize_t i, PyObject *v)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.insert
|
||||||
|
|
||||||
|
index: Py_ssize_t
|
||||||
|
object: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Insert object before index.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listinsert(PyListObject *self, PyObject *args)
|
list_insert_impl(PyListObject *self, Py_ssize_t index, PyObject *object)
|
||||||
|
/*[clinic end generated code: output=7f35e32f60c8cb78 input=858514cf894c7eab]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
if (ins1(self, index, object) == 0)
|
||||||
PyObject *v;
|
|
||||||
if (!PyArg_ParseTuple(args, "nO:insert", &i, &v))
|
|
||||||
return NULL;
|
|
||||||
if (ins1(self, i, v) == 0)
|
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.clear
|
||||||
|
|
||||||
|
Remove all items from list.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listclear(PyListObject *self)
|
list_clear_impl(PyListObject *self)
|
||||||
|
/*[clinic end generated code: output=67a1896c01f74362 input=ca3c1646856742f6]*/
|
||||||
{
|
{
|
||||||
list_clear(self);
|
_list_clear(self);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.copy
|
||||||
|
|
||||||
|
Return a shallow copy of the list.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listcopy(PyListObject *self)
|
list_copy_impl(PyListObject *self)
|
||||||
|
/*[clinic end generated code: output=ec6b72d6209d418e input=6453ab159e84771f]*/
|
||||||
{
|
{
|
||||||
return list_slice(self, 0, Py_SIZE(self));
|
return list_slice(self, 0, Py_SIZE(self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.append
|
||||||
|
|
||||||
|
object: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Append object to the end of the list.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listappend(PyListObject *self, PyObject *v)
|
list_append(PyListObject *self, PyObject *object)
|
||||||
|
/*[clinic end generated code: output=7c096003a29c0eae input=43a3fe48a7066e91]*/
|
||||||
{
|
{
|
||||||
if (app1(self, v) == 0)
|
if (app1(self, object) == 0)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.extend
|
||||||
|
|
||||||
|
iterable: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Extend list by appending elements from the iterable.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listextend(PyListObject *self, PyObject *b)
|
list_extend(PyListObject *self, PyObject *iterable)
|
||||||
|
/*[clinic end generated code: output=630fb3bca0c8e789 input=9ec5ba3a81be3a4d]*/
|
||||||
{
|
{
|
||||||
PyObject *it; /* iter(v) */
|
PyObject *it; /* iter(v) */
|
||||||
Py_ssize_t m; /* size of self */
|
Py_ssize_t m; /* size of self */
|
||||||
Py_ssize_t n; /* guess for size of b */
|
Py_ssize_t n; /* guess for size of iterable */
|
||||||
Py_ssize_t mn; /* m + n */
|
Py_ssize_t mn; /* m + n */
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *(*iternext)(PyObject *);
|
PyObject *(*iternext)(PyObject *);
|
||||||
|
@ -787,15 +835,16 @@ listextend(PyListObject *self, PyObject *b)
|
||||||
1) lists and tuples which can use PySequence_Fast ops
|
1) lists and tuples which can use PySequence_Fast ops
|
||||||
2) extending self to self requires making a copy first
|
2) extending self to self requires making a copy first
|
||||||
*/
|
*/
|
||||||
if (PyList_CheckExact(b) || PyTuple_CheckExact(b) || (PyObject *)self == b) {
|
if (PyList_CheckExact(iterable) || PyTuple_CheckExact(iterable) ||
|
||||||
|
(PyObject *)self == iterable) {
|
||||||
PyObject **src, **dest;
|
PyObject **src, **dest;
|
||||||
b = PySequence_Fast(b, "argument must be iterable");
|
iterable = PySequence_Fast(iterable, "argument must be iterable");
|
||||||
if (!b)
|
if (!iterable)
|
||||||
return NULL;
|
return NULL;
|
||||||
n = PySequence_Fast_GET_SIZE(b);
|
n = PySequence_Fast_GET_SIZE(iterable);
|
||||||
if (n == 0) {
|
if (n == 0) {
|
||||||
/* short circuit when b is empty */
|
/* short circuit when iterable is empty */
|
||||||
Py_DECREF(b);
|
Py_DECREF(iterable);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
m = Py_SIZE(self);
|
m = Py_SIZE(self);
|
||||||
|
@ -803,33 +852,33 @@ listextend(PyListObject *self, PyObject *b)
|
||||||
an overflow on any relevant platform */
|
an overflow on any relevant platform */
|
||||||
assert(m < PY_SSIZE_T_MAX - n);
|
assert(m < PY_SSIZE_T_MAX - n);
|
||||||
if (list_resize(self, m + n) < 0) {
|
if (list_resize(self, m + n) < 0) {
|
||||||
Py_DECREF(b);
|
Py_DECREF(iterable);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* note that we may still have self == b here for the
|
/* note that we may still have self == iterable here for the
|
||||||
* situation a.extend(a), but the following code works
|
* situation a.extend(a), but the following code works
|
||||||
* in that case too. Just make sure to resize self
|
* in that case too. Just make sure to resize self
|
||||||
* before calling PySequence_Fast_ITEMS.
|
* before calling PySequence_Fast_ITEMS.
|
||||||
*/
|
*/
|
||||||
/* populate the end of self with b's items */
|
/* populate the end of self with iterable's items */
|
||||||
src = PySequence_Fast_ITEMS(b);
|
src = PySequence_Fast_ITEMS(iterable);
|
||||||
dest = self->ob_item + m;
|
dest = self->ob_item + m;
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
PyObject *o = src[i];
|
PyObject *o = src[i];
|
||||||
Py_INCREF(o);
|
Py_INCREF(o);
|
||||||
dest[i] = o;
|
dest[i] = o;
|
||||||
}
|
}
|
||||||
Py_DECREF(b);
|
Py_DECREF(iterable);
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
it = PyObject_GetIter(b);
|
it = PyObject_GetIter(iterable);
|
||||||
if (it == NULL)
|
if (it == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
iternext = *it->ob_type->tp_iternext;
|
iternext = *it->ob_type->tp_iternext;
|
||||||
|
|
||||||
/* Guess a result list size. */
|
/* Guess a result list size. */
|
||||||
n = PyObject_LengthHint(b, 8);
|
n = PyObject_LengthHint(iterable, 8);
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
Py_DECREF(it);
|
Py_DECREF(it);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -890,9 +939,9 @@ listextend(PyListObject *self, PyObject *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
_PyList_Extend(PyListObject *self, PyObject *b)
|
_PyList_Extend(PyListObject *self, PyObject *iterable)
|
||||||
{
|
{
|
||||||
return listextend(self, b);
|
return list_extend(self, iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
|
@ -900,7 +949,7 @@ list_inplace_concat(PyListObject *self, PyObject *other)
|
||||||
{
|
{
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
result = listextend(self, other);
|
result = list_extend(self, other);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return result;
|
return result;
|
||||||
Py_DECREF(result);
|
Py_DECREF(result);
|
||||||
|
@ -908,29 +957,37 @@ list_inplace_concat(PyListObject *self, PyObject *other)
|
||||||
return (PyObject *)self;
|
return (PyObject *)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.pop
|
||||||
|
|
||||||
|
index: Py_ssize_t = -1
|
||||||
|
/
|
||||||
|
|
||||||
|
Remove and return item at index (default last).
|
||||||
|
|
||||||
|
Raises IndexError if list is empty or index is out of range.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listpop(PyListObject *self, PyObject *args)
|
list_pop_impl(PyListObject *self, Py_ssize_t index)
|
||||||
|
/*[clinic end generated code: output=6bd69dcb3f17eca8 input=b83675976f329e6f]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i = -1;
|
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "|n:pop", &i))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (Py_SIZE(self) == 0) {
|
if (Py_SIZE(self) == 0) {
|
||||||
/* Special-case most common failure cause */
|
/* Special-case most common failure cause */
|
||||||
PyErr_SetString(PyExc_IndexError, "pop from empty list");
|
PyErr_SetString(PyExc_IndexError, "pop from empty list");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (i < 0)
|
if (index < 0)
|
||||||
i += Py_SIZE(self);
|
index += Py_SIZE(self);
|
||||||
if (i < 0 || i >= Py_SIZE(self)) {
|
if (index < 0 || index >= Py_SIZE(self)) {
|
||||||
PyErr_SetString(PyExc_IndexError, "pop index out of range");
|
PyErr_SetString(PyExc_IndexError, "pop index out of range");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
v = self->ob_item[i];
|
v = self->ob_item[index];
|
||||||
if (i == Py_SIZE(self) - 1) {
|
if (index == Py_SIZE(self) - 1) {
|
||||||
status = list_resize(self, Py_SIZE(self) - 1);
|
status = list_resize(self, Py_SIZE(self) - 1);
|
||||||
if (status >= 0)
|
if (status >= 0)
|
||||||
return v; /* and v now owns the reference the list had */
|
return v; /* and v now owns the reference the list had */
|
||||||
|
@ -938,7 +995,7 @@ listpop(PyListObject *self, PyObject *args)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
Py_INCREF(v);
|
Py_INCREF(v);
|
||||||
status = list_ass_slice(self, i, i+1, (PyObject *)NULL);
|
status = list_ass_slice(self, index, index+1, (PyObject *)NULL);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1906,8 +1963,19 @@ reverse_sortslice(sortslice *s, Py_ssize_t n)
|
||||||
* list will be some permutation of its input state (nothing is lost or
|
* list will be some permutation of its input state (nothing is lost or
|
||||||
* duplicated).
|
* duplicated).
|
||||||
*/
|
*/
|
||||||
|
/*[clinic input]
|
||||||
|
list.sort
|
||||||
|
|
||||||
|
*
|
||||||
|
key as keyfunc: object = None
|
||||||
|
reverse: int(c_default="0") = False
|
||||||
|
|
||||||
|
Stable sort *IN PLACE*.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listsort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
|
list_sort_impl(PyListObject *self, PyObject *keyfunc, int reverse)
|
||||||
|
/*[clinic end generated code: output=57b9f9c5e23fbe42 input=5029c13c9209d86a]*/
|
||||||
{
|
{
|
||||||
MergeState ms;
|
MergeState ms;
|
||||||
Py_ssize_t nremaining;
|
Py_ssize_t nremaining;
|
||||||
|
@ -2057,7 +2125,7 @@ keyfunc_fail:
|
||||||
self->ob_item = saved_ob_item;
|
self->ob_item = saved_ob_item;
|
||||||
self->allocated = saved_allocated;
|
self->allocated = saved_allocated;
|
||||||
if (final_ob_item != NULL) {
|
if (final_ob_item != NULL) {
|
||||||
/* we cannot use list_clear() for this because it does not
|
/* we cannot use _list_clear() for this because it does not
|
||||||
guarantee that the list is really empty when it returns */
|
guarantee that the list is really empty when it returns */
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
Py_XDECREF(final_ob_item[i]);
|
Py_XDECREF(final_ob_item[i]);
|
||||||
|
@ -2070,19 +2138,6 @@ keyfunc_fail:
|
||||||
#undef IFLT
|
#undef IFLT
|
||||||
#undef ISLT
|
#undef ISLT
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
listsort(PyListObject *self, PyObject *args, PyObject *kwds)
|
|
||||||
{
|
|
||||||
static char *kwlist[] = {"key", "reverse", 0};
|
|
||||||
PyObject *keyfunc = NULL;
|
|
||||||
int reverse = 0;
|
|
||||||
|
|
||||||
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|$Oi:sort",
|
|
||||||
kwlist, &keyfunc, &reverse))
|
|
||||||
return NULL;
|
|
||||||
return listsort_impl(self, keyfunc, reverse);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
PyList_Sort(PyObject *v)
|
PyList_Sort(PyObject *v)
|
||||||
{
|
{
|
||||||
|
@ -2090,15 +2145,22 @@ PyList_Sort(PyObject *v)
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
v = listsort_impl((PyListObject *)v, NULL, 0);
|
v = list_sort_impl((PyListObject *)v, NULL, 0);
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.reverse
|
||||||
|
|
||||||
|
Reverse *IN PLACE*.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listreverse(PyListObject *self)
|
list_reverse_impl(PyListObject *self)
|
||||||
|
/*[clinic end generated code: output=482544fc451abea9 input=eefd4c3ae1bc9887]*/
|
||||||
{
|
{
|
||||||
if (Py_SIZE(self) > 1)
|
if (Py_SIZE(self) > 1)
|
||||||
reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
|
reverse_slice(self->ob_item, self->ob_item + Py_SIZE(self));
|
||||||
|
@ -2144,16 +2206,26 @@ PyList_AsTuple(PyObject *v)
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
/*[clinic input]
|
||||||
listindex(PyListObject *self, PyObject *args)
|
list.index
|
||||||
{
|
|
||||||
Py_ssize_t i, start=0, stop=Py_SIZE(self);
|
value: object
|
||||||
PyObject *v;
|
start: object(converter="_PyEval_SliceIndex", type="Py_ssize_t") = 0
|
||||||
|
stop: object(converter="_PyEval_SliceIndex", type="Py_ssize_t", c_default="PY_SSIZE_T_MAX") = sys.maxsize
|
||||||
|
/
|
||||||
|
|
||||||
|
Return first index of value.
|
||||||
|
|
||||||
|
Raises ValueError if the value is not present.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
list_index_impl(PyListObject *self, PyObject *value, Py_ssize_t start,
|
||||||
|
Py_ssize_t stop)
|
||||||
|
/*[clinic end generated code: output=ec51b88787e4e481 input=70b7247e398a6999]*/
|
||||||
|
{
|
||||||
|
Py_ssize_t i;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "O|O&O&:index", &v,
|
|
||||||
_PyEval_SliceIndex, &start,
|
|
||||||
_PyEval_SliceIndex, &stop))
|
|
||||||
return NULL;
|
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start += Py_SIZE(self);
|
start += Py_SIZE(self);
|
||||||
if (start < 0)
|
if (start < 0)
|
||||||
|
@ -2165,24 +2237,34 @@ listindex(PyListObject *self, PyObject *args)
|
||||||
stop = 0;
|
stop = 0;
|
||||||
}
|
}
|
||||||
for (i = start; i < stop && i < Py_SIZE(self); i++) {
|
for (i = start; i < stop && i < Py_SIZE(self); i++) {
|
||||||
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
|
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
return PyLong_FromSsize_t(i);
|
return PyLong_FromSsize_t(i);
|
||||||
else if (cmp < 0)
|
else if (cmp < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyErr_Format(PyExc_ValueError, "%R is not in list", v);
|
PyErr_Format(PyExc_ValueError, "%R is not in list", value);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.count
|
||||||
|
|
||||||
|
value: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Return number of occurrences of value.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listcount(PyListObject *self, PyObject *v)
|
list_count(PyListObject *self, PyObject *value)
|
||||||
|
/*[clinic end generated code: output=b1f5d284205ae714 input=3bdc3a5e6f749565]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t count = 0;
|
Py_ssize_t count = 0;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
for (i = 0; i < Py_SIZE(self); i++) {
|
for (i = 0; i < Py_SIZE(self); i++) {
|
||||||
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
|
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
|
||||||
if (cmp > 0)
|
if (cmp > 0)
|
||||||
count++;
|
count++;
|
||||||
else if (cmp < 0)
|
else if (cmp < 0)
|
||||||
|
@ -2191,13 +2273,25 @@ listcount(PyListObject *self, PyObject *v)
|
||||||
return PyLong_FromSsize_t(count);
|
return PyLong_FromSsize_t(count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.remove
|
||||||
|
|
||||||
|
value: object
|
||||||
|
/
|
||||||
|
|
||||||
|
Remove first occurrence of value.
|
||||||
|
|
||||||
|
Raises ValueError if the value is not present.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
listremove(PyListObject *self, PyObject *v)
|
list_remove(PyListObject *self, PyObject *value)
|
||||||
|
/*[clinic end generated code: output=f087e1951a5e30d1 input=2dc2ba5bb2fb1f82]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
for (i = 0; i < Py_SIZE(self); i++) {
|
for (i = 0; i < Py_SIZE(self); i++) {
|
||||||
int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ);
|
int cmp = PyObject_RichCompareBool(self->ob_item[i], value, Py_EQ);
|
||||||
if (cmp > 0) {
|
if (cmp > 0) {
|
||||||
if (list_ass_slice(self, i, i+1,
|
if (list_ass_slice(self, i, i+1,
|
||||||
(PyObject *)NULL) == 0)
|
(PyObject *)NULL) == 0)
|
||||||
|
@ -2289,16 +2383,22 @@ list_richcompare(PyObject *v, PyObject *w, int op)
|
||||||
return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
|
return PyObject_RichCompare(vl->ob_item[i], wl->ob_item[i], op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.__init__
|
||||||
|
|
||||||
|
iterable: object(c_default="NULL") = ()
|
||||||
|
/
|
||||||
|
|
||||||
|
Built-in mutable sequence.
|
||||||
|
|
||||||
|
If no argument is given, the constructor creates a new empty list.
|
||||||
|
The argument must be an iterable if specified.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
list_init(PyListObject *self, PyObject *args, PyObject *kw)
|
list___init___impl(PyListObject *self, PyObject *iterable)
|
||||||
|
/*[clinic end generated code: output=0f3c21379d01de48 input=b3f3fe7206af8f6b]*/
|
||||||
{
|
{
|
||||||
PyObject *arg = NULL;
|
|
||||||
|
|
||||||
if (!_PyArg_NoKeywords("list()", kw))
|
|
||||||
return -1;
|
|
||||||
if (!PyArg_UnpackTuple(args, "list", 0, 1, &arg))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* Verify list invariants established by PyType_GenericAlloc() */
|
/* Verify list invariants established by PyType_GenericAlloc() */
|
||||||
assert(0 <= Py_SIZE(self));
|
assert(0 <= Py_SIZE(self));
|
||||||
assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
|
assert(Py_SIZE(self) <= self->allocated || self->allocated == -1);
|
||||||
|
@ -2307,10 +2407,10 @@ list_init(PyListObject *self, PyObject *args, PyObject *kw)
|
||||||
|
|
||||||
/* Empty previous contents */
|
/* Empty previous contents */
|
||||||
if (self->ob_item != NULL) {
|
if (self->ob_item != NULL) {
|
||||||
(void)list_clear(self);
|
(void)_list_clear(self);
|
||||||
}
|
}
|
||||||
if (arg != NULL) {
|
if (iterable != NULL) {
|
||||||
PyObject *rv = listextend(self, arg);
|
PyObject *rv = list_extend(self, iterable);
|
||||||
if (rv == NULL)
|
if (rv == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
Py_DECREF(rv);
|
Py_DECREF(rv);
|
||||||
|
@ -2318,8 +2418,15 @@ list_init(PyListObject *self, PyObject *args, PyObject *kw)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.__sizeof__
|
||||||
|
|
||||||
|
Return the size of the list in memory, in bytes.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
list_sizeof(PyListObject *self)
|
list___sizeof___impl(PyListObject *self)
|
||||||
|
/*[clinic end generated code: output=3417541f95f9a53e input=b8030a5d5ce8a187]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t res;
|
Py_ssize_t res;
|
||||||
|
|
||||||
|
@ -2328,57 +2435,23 @@ list_sizeof(PyListObject *self)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *list_iter(PyObject *seq);
|
static PyObject *list_iter(PyObject *seq);
|
||||||
static PyObject *list_reversed(PyListObject* seq, PyObject* unused);
|
|
||||||
|
|
||||||
PyDoc_STRVAR(getitem_doc,
|
|
||||||
"x.__getitem__(y) <==> x[y]");
|
|
||||||
PyDoc_STRVAR(reversed_doc,
|
|
||||||
"L.__reversed__() -- return a reverse iterator over the list");
|
|
||||||
PyDoc_STRVAR(sizeof_doc,
|
|
||||||
"L.__sizeof__() -- size of L in memory, in bytes");
|
|
||||||
PyDoc_STRVAR(clear_doc,
|
|
||||||
"L.clear() -> None -- remove all items from L");
|
|
||||||
PyDoc_STRVAR(copy_doc,
|
|
||||||
"L.copy() -> list -- a shallow copy of L");
|
|
||||||
PyDoc_STRVAR(append_doc,
|
|
||||||
"L.append(object) -> None -- append object to end");
|
|
||||||
PyDoc_STRVAR(extend_doc,
|
|
||||||
"L.extend(iterable) -> None -- extend list by appending elements from the iterable");
|
|
||||||
PyDoc_STRVAR(insert_doc,
|
|
||||||
"L.insert(index, object) -- insert object before index");
|
|
||||||
PyDoc_STRVAR(pop_doc,
|
|
||||||
"L.pop([index]) -> item -- remove and return item at index (default last).\n"
|
|
||||||
"Raises IndexError if list is empty or index is out of range.");
|
|
||||||
PyDoc_STRVAR(remove_doc,
|
|
||||||
"L.remove(value) -> None -- remove first occurrence of value.\n"
|
|
||||||
"Raises ValueError if the value is not present.");
|
|
||||||
PyDoc_STRVAR(index_doc,
|
|
||||||
"L.index(value, [start, [stop]]) -> integer -- return first index of value.\n"
|
|
||||||
"Raises ValueError if the value is not present.");
|
|
||||||
PyDoc_STRVAR(count_doc,
|
|
||||||
"L.count(value) -> integer -- return number of occurrences of value");
|
|
||||||
PyDoc_STRVAR(reverse_doc,
|
|
||||||
"L.reverse() -- reverse *IN PLACE*");
|
|
||||||
PyDoc_STRVAR(sort_doc,
|
|
||||||
"L.sort(key=None, reverse=False) -> None -- stable sort *IN PLACE*");
|
|
||||||
|
|
||||||
static PyObject *list_subscript(PyListObject*, PyObject*);
|
static PyObject *list_subscript(PyListObject*, PyObject*);
|
||||||
|
|
||||||
static PyMethodDef list_methods[] = {
|
static PyMethodDef list_methods[] = {
|
||||||
{"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, getitem_doc},
|
{"__getitem__", (PyCFunction)list_subscript, METH_O|METH_COEXIST, "x.__getitem__(y) <==> x[y]"},
|
||||||
{"__reversed__",(PyCFunction)list_reversed, METH_NOARGS, reversed_doc},
|
LIST___REVERSED___METHODDEF
|
||||||
{"__sizeof__", (PyCFunction)list_sizeof, METH_NOARGS, sizeof_doc},
|
LIST___SIZEOF___METHODDEF
|
||||||
{"clear", (PyCFunction)listclear, METH_NOARGS, clear_doc},
|
LIST_CLEAR_METHODDEF
|
||||||
{"copy", (PyCFunction)listcopy, METH_NOARGS, copy_doc},
|
LIST_COPY_METHODDEF
|
||||||
{"append", (PyCFunction)listappend, METH_O, append_doc},
|
LIST_APPEND_METHODDEF
|
||||||
{"insert", (PyCFunction)listinsert, METH_VARARGS, insert_doc},
|
LIST_INSERT_METHODDEF
|
||||||
{"extend", (PyCFunction)listextend, METH_O, extend_doc},
|
LIST_EXTEND_METHODDEF
|
||||||
{"pop", (PyCFunction)listpop, METH_VARARGS, pop_doc},
|
LIST_POP_METHODDEF
|
||||||
{"remove", (PyCFunction)listremove, METH_O, remove_doc},
|
LIST_REMOVE_METHODDEF
|
||||||
{"index", (PyCFunction)listindex, METH_VARARGS, index_doc},
|
LIST_INDEX_METHODDEF
|
||||||
{"count", (PyCFunction)listcount, METH_O, count_doc},
|
LIST_COUNT_METHODDEF
|
||||||
{"reverse", (PyCFunction)listreverse, METH_NOARGS, reverse_doc},
|
LIST_REVERSE_METHODDEF
|
||||||
{"sort", (PyCFunction)listsort, METH_VARARGS | METH_KEYWORDS, sort_doc},
|
LIST_SORT_METHODDEF
|
||||||
{NULL, NULL} /* sentinel */
|
{NULL, NULL} /* sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2395,10 +2468,6 @@ static PySequenceMethods list_as_sequence = {
|
||||||
(ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */
|
(ssizeargfunc)list_inplace_repeat, /* sq_inplace_repeat */
|
||||||
};
|
};
|
||||||
|
|
||||||
PyDoc_STRVAR(list_doc,
|
|
||||||
"list() -> new empty list\n"
|
|
||||||
"list(iterable) -> new list initialized from iterable's items");
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
list_subscript(PyListObject* self, PyObject* item)
|
list_subscript(PyListObject* self, PyObject* item)
|
||||||
{
|
{
|
||||||
|
@ -2641,9 +2710,9 @@ PyTypeObject PyList_Type = {
|
||||||
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 | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */
|
Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */
|
||||||
list_doc, /* tp_doc */
|
list___init____doc__, /* tp_doc */
|
||||||
(traverseproc)list_traverse, /* tp_traverse */
|
(traverseproc)list_traverse, /* tp_traverse */
|
||||||
(inquiry)list_clear, /* tp_clear */
|
(inquiry)_list_clear, /* tp_clear */
|
||||||
list_richcompare, /* tp_richcompare */
|
list_richcompare, /* tp_richcompare */
|
||||||
0, /* tp_weaklistoffset */
|
0, /* tp_weaklistoffset */
|
||||||
list_iter, /* tp_iter */
|
list_iter, /* tp_iter */
|
||||||
|
@ -2656,13 +2725,12 @@ PyTypeObject PyList_Type = {
|
||||||
0, /* tp_descr_get */
|
0, /* tp_descr_get */
|
||||||
0, /* tp_descr_set */
|
0, /* tp_descr_set */
|
||||||
0, /* tp_dictoffset */
|
0, /* tp_dictoffset */
|
||||||
(initproc)list_init, /* tp_init */
|
(initproc)list___init__, /* tp_init */
|
||||||
PyType_GenericAlloc, /* tp_alloc */
|
PyType_GenericAlloc, /* tp_alloc */
|
||||||
PyType_GenericNew, /* tp_new */
|
PyType_GenericNew, /* tp_new */
|
||||||
PyObject_GC_Del, /* tp_free */
|
PyObject_GC_Del, /* tp_free */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*********************** List Iterator **************************/
|
/*********************** List Iterator **************************/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2671,7 +2739,6 @@ typedef struct {
|
||||||
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
|
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
|
||||||
} listiterobject;
|
} listiterobject;
|
||||||
|
|
||||||
static PyObject *list_iter(PyObject *);
|
|
||||||
static void listiter_dealloc(listiterobject *);
|
static void listiter_dealloc(listiterobject *);
|
||||||
static int listiter_traverse(listiterobject *, visitproc, void *);
|
static int listiter_traverse(listiterobject *, visitproc, void *);
|
||||||
static PyObject *listiter_next(listiterobject *);
|
static PyObject *listiter_next(listiterobject *);
|
||||||
|
@ -2825,7 +2892,6 @@ typedef struct {
|
||||||
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
|
PyListObject *it_seq; /* Set to NULL when iterator is exhausted */
|
||||||
} listreviterobject;
|
} listreviterobject;
|
||||||
|
|
||||||
static PyObject *list_reversed(PyListObject *, PyObject *);
|
|
||||||
static void listreviter_dealloc(listreviterobject *);
|
static void listreviter_dealloc(listreviterobject *);
|
||||||
static int listreviter_traverse(listreviterobject *, visitproc, void *);
|
static int listreviter_traverse(listreviterobject *, visitproc, void *);
|
||||||
static PyObject *listreviter_next(listreviterobject *);
|
static PyObject *listreviter_next(listreviterobject *);
|
||||||
|
@ -2873,18 +2939,25 @@ PyTypeObject PyListRevIter_Type = {
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
list.__reversed__
|
||||||
|
|
||||||
|
Return a reverse iterator over the list.
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
list_reversed(PyListObject *seq, PyObject *unused)
|
list___reversed___impl(PyListObject *self)
|
||||||
|
/*[clinic end generated code: output=b166f073208c888c input=eadb6e17f8a6a280]*/
|
||||||
{
|
{
|
||||||
listreviterobject *it;
|
listreviterobject *it;
|
||||||
|
|
||||||
it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);
|
it = PyObject_GC_New(listreviterobject, &PyListRevIter_Type);
|
||||||
if (it == NULL)
|
if (it == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
assert(PyList_Check(seq));
|
assert(PyList_Check(self));
|
||||||
it->it_index = PyList_GET_SIZE(seq) - 1;
|
it->it_index = PyList_GET_SIZE(self) - 1;
|
||||||
Py_INCREF(seq);
|
Py_INCREF(self);
|
||||||
it->it_seq = seq;
|
it->it_seq = self;
|
||||||
PyObject_GC_Track(it);
|
PyObject_GC_Track(it);
|
||||||
return (PyObject *)it;
|
return (PyObject *)it;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue