22
33#include "Python.h"
44#include "structmember.h"
5+ #include "pycore_tupleobject.h"
56
67/* Support objects whose length is > PY_SSIZE_T_MAX.
78
@@ -71,43 +72,35 @@ make_range_object(PyTypeObject *type, PyObject *start,
7172 range(0, 5, -1)
7273*/
7374static PyObject *
74- range_new (PyTypeObject * type , PyObject * args , PyObject * kw )
75+ range_from_array (PyTypeObject * type , PyObject * const * args , Py_ssize_t num_args )
7576{
7677 rangeobject * obj ;
7778 PyObject * start = NULL , * stop = NULL , * step = NULL ;
7879
79- if (!_PyArg_NoKeywords ("range" , kw ))
80- return NULL ;
81-
82- Py_ssize_t num_args = PyTuple_GET_SIZE (args );
8380 switch (num_args ) {
8481 case 3 :
85- step = PyTuple_GET_ITEM ( args , 2 ) ;
82+ step = args [ 2 ] ;
8683 /* fallthrough */
8784 case 2 :
88- start = PyTuple_GET_ITEM ( args , 0 );
89- start = PyNumber_Index (start );
85+ /* Convert borrowed refs to owned refs */
86+ start = PyNumber_Index (args [ 0 ] );
9087 if (!start ) {
9188 return NULL ;
9289 }
93-
94- stop = PyTuple_GET_ITEM (args , 1 );
95- stop = PyNumber_Index (stop );
90+ stop = PyNumber_Index (args [1 ]);
9691 if (!stop ) {
9792 Py_DECREF (start );
9893 return NULL ;
9994 }
100-
101- step = validate_step (step );
95+ step = validate_step (step ); /* Caution, this can clear exceptions */
10296 if (!step ) {
10397 Py_DECREF (start );
10498 Py_DECREF (stop );
10599 return NULL ;
106100 }
107101 break ;
108102 case 1 :
109- stop = PyTuple_GET_ITEM (args , 0 );
110- stop = PyNumber_Index (stop );
103+ stop = PyNumber_Index (args [0 ]);
111104 if (!stop ) {
112105 return NULL ;
113106 }
@@ -126,10 +119,10 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
126119 num_args );
127120 return NULL ;
128121 }
129-
130122 obj = make_range_object (type , start , stop , step );
131- if (obj != NULL )
123+ if (obj != NULL ) {
132124 return (PyObject * ) obj ;
125+ }
133126
134127 /* Failed to create object, release attributes */
135128 Py_DECREF (start );
@@ -138,6 +131,28 @@ range_new(PyTypeObject *type, PyObject *args, PyObject *kw)
138131 return NULL ;
139132}
140133
134+ static PyObject *
135+ range_new (PyTypeObject * type , PyObject * args , PyObject * kw )
136+ {
137+ if (!_PyArg_NoKeywords ("range" , kw ))
138+ return NULL ;
139+
140+ return range_from_array (type , _PyTuple_ITEMS (args ), PyTuple_GET_SIZE (args ));
141+ }
142+
143+
144+ static PyObject *
145+ range_vectorcall (PyTypeObject * type , PyObject * const * args ,
146+ size_t nargsf , PyObject * kwnames )
147+ {
148+ Py_ssize_t nargs = PyVectorcall_NARGS (nargsf );
149+ if (kwnames && PyTuple_GET_SIZE (kwnames ) != 0 ) {
150+ PyErr_Format (PyExc_TypeError , "range() takes no keyword arguments" );
151+ return NULL ;
152+ }
153+ return range_from_array (type , args , nargs );
154+ }
155+
141156PyDoc_STRVAR (range_doc ,
142157"range(stop) -> range object\n\
143158range(start, stop[, step]) -> range object\n\
@@ -719,6 +734,7 @@ PyTypeObject PyRange_Type = {
719734 0 , /* tp_init */
720735 0 , /* tp_alloc */
721736 range_new , /* tp_new */
737+ .tp_vectorcall = (vectorcallfunc )range_vectorcall
722738};
723739
724740/*********************** range Iterator **************************/
0 commit comments