44#include "pycore_ceval.h" // _PyEval_GetBuiltin()
55#include "pycore_modsupport.h" // _PyArg_NoKeywords()
66#include "pycore_object.h"
7+ #include "pycore_tuple.h" // _PyTuple_ITEMS()
78#include "pycore_typevarobject.h" // _Py_typing_type_repr
89#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
910#include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check
@@ -161,22 +162,6 @@ tuple_add(PyObject *self, Py_ssize_t len, PyObject *item)
161162 return 0 ;
162163}
163164
164- static Py_ssize_t
165- tuple_extend (PyObject * * dst , Py_ssize_t dstindex ,
166- PyObject * * src , Py_ssize_t count )
167- {
168- assert (count >= 0 );
169- if (_PyTuple_Resize (dst , PyTuple_GET_SIZE (* dst ) + count - 1 ) != 0 ) {
170- return -1 ;
171- }
172- assert (dstindex + count <= PyTuple_GET_SIZE (* dst ));
173- for (Py_ssize_t i = 0 ; i < count ; ++ i ) {
174- PyObject * item = src [i ];
175- PyTuple_SET_ITEM (* dst , dstindex + i , Py_NewRef (item ));
176- }
177- return dstindex + count ;
178- }
179-
180165PyObject *
181166_Py_make_parameters (PyObject * args )
182167{
@@ -274,43 +259,54 @@ subs_tvars(PyObject *obj, PyObject *params,
274259 if (PyObject_GetOptionalAttr (obj , & _Py_ID (__parameters__ ), & subparams ) < 0 ) {
275260 return NULL ;
276261 }
262+
277263 if (subparams && PyTuple_Check (subparams ) && PyTuple_GET_SIZE (subparams )) {
278264 Py_ssize_t nparams = PyTuple_GET_SIZE (params );
279265 Py_ssize_t nsubargs = PyTuple_GET_SIZE (subparams );
280- PyObject * subargs = PyTuple_New (nsubargs );
281- if (subargs == NULL ) {
282- Py_DECREF (subparams );
283- return NULL ;
266+ PyTupleWriter * writer = PyTupleWriter_Create (nsubargs );
267+ if (writer == NULL ) {
268+ goto error ;
284269 }
285- Py_ssize_t j = 0 ;
286270 for (Py_ssize_t i = 0 ; i < nsubargs ; ++ i ) {
287271 PyObject * arg = PyTuple_GET_ITEM (subparams , i );
288272 Py_ssize_t iparam = tuple_index (params , nparams , arg );
289273 if (iparam >= 0 ) {
290274 PyObject * param = PyTuple_GET_ITEM (params , iparam );
291275 arg = argitems [iparam ];
292276 if (Py_TYPE (param )-> tp_iter && PyTuple_Check (arg )) { // TypeVarTuple
293- j = tuple_extend (& subargs , j ,
294- & PyTuple_GET_ITEM (arg , 0 ),
295- PyTuple_GET_SIZE (arg ));
296- if (j < 0 ) {
297- return NULL ;
277+ if (PyTupleWriter_AddArray (writer ,
278+ _PyTuple_ITEMS (arg ),
279+ PyTuple_GET_SIZE (arg )) < 0 ) {
280+ goto error ;
298281 }
299282 continue ;
300283 }
301284 }
302- PyTuple_SET_ITEM (subargs , j , Py_NewRef (arg ));
303- j ++ ;
285+ if (PyTupleWriter_Add (writer , arg ) < 0 ) {
286+ goto error ;
287+ }
304288 }
305- assert (j == PyTuple_GET_SIZE (subargs ));
306289
307- obj = PyObject_GetItem (obj , subargs );
290+ PyObject * subargs = PyTupleWriter_Finish (writer );
291+ if (subargs != NULL ) {
292+ obj = PyObject_GetItem (obj , subargs );
293+ Py_DECREF (subargs );
294+ }
295+ else {
296+ obj = NULL ;
297+ }
298+ goto done ;
308299
309- Py_DECREF (subargs );
300+ error :
301+ PyTupleWriter_Discard (writer );
302+ Py_DECREF (subparams );
303+ return NULL ;
310304 }
311305 else {
312306 Py_INCREF (obj );
313307 }
308+
309+ done :
314310 Py_XDECREF (subparams );
315311 return obj ;
316312}
@@ -454,60 +450,50 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
454450 }
455451 }
456452 Py_ssize_t nargs = PyTuple_GET_SIZE (args );
457- PyObject * newargs = PyTuple_New (nargs );
453+ PyTupleWriter * newargs = PyTupleWriter_Create (nargs );
458454 if (newargs == NULL ) {
459- Py_DECREF (item );
460- Py_XDECREF (tuple_args );
461- return NULL ;
455+ goto error ;
462456 }
463- for (Py_ssize_t iarg = 0 , jarg = 0 ; iarg < nargs ; iarg ++ ) {
457+
458+ for (Py_ssize_t iarg = 0 ; iarg < nargs ; iarg ++ ) {
464459 PyObject * arg = PyTuple_GET_ITEM (args , iarg );
465460 if (PyType_Check (arg )) {
466- PyTuple_SET_ITEM (newargs , jarg , Py_NewRef (arg ));
467- jarg ++ ;
461+ if (PyTupleWriter_Add (newargs , arg ) < 0 ) {
462+ goto error ;
463+ }
468464 continue ;
469465 }
466+
470467 // Recursively substitute params in lists/tuples.
471468 if (PyTuple_Check (arg ) || PyList_Check (arg )) {
472469 PyObject * subargs = _Py_subs_parameters (self , arg , parameters , item );
473470 if (subargs == NULL ) {
474- Py_DECREF (newargs );
475- Py_DECREF (item );
476- Py_XDECREF (tuple_args );
477- return NULL ;
471+ goto error ;
478472 }
479473 if (PyTuple_Check (arg )) {
480- PyTuple_SET_ITEM (newargs , jarg , subargs );
474+ if (PyTupleWriter_AddSteal (newargs , subargs ) < 0 ) {
475+ goto error ;
476+ }
481477 }
482478 else {
483479 // _Py_subs_parameters returns a tuple. If the original arg was a list,
484480 // convert subargs to a list as well.
485481 PyObject * subargs_list = PySequence_List (subargs );
486482 Py_DECREF (subargs );
487- if (subargs_list == NULL ) {
488- Py_DECREF (newargs );
489- Py_DECREF (item );
490- Py_XDECREF (tuple_args );
491- return NULL ;
483+ if (PyTupleWriter_AddSteal (newargs , subargs_list ) < 0 ) {
484+ goto error ;
492485 }
493- PyTuple_SET_ITEM (newargs , jarg , subargs_list );
494486 }
495- jarg ++ ;
496487 continue ;
497488 }
489+
498490 int unpack = _is_unpacked_typevartuple (arg );
499491 if (unpack < 0 ) {
500- Py_DECREF (newargs );
501- Py_DECREF (item );
502- Py_XDECREF (tuple_args );
503- return NULL ;
492+ goto error ;
504493 }
505494 PyObject * subst ;
506495 if (PyObject_GetOptionalAttr (arg , & _Py_ID (__typing_subst__ ), & subst ) < 0 ) {
507- Py_DECREF (newargs );
508- Py_DECREF (item );
509- Py_XDECREF (tuple_args );
510- return NULL ;
496+ goto error ;
511497 }
512498 if (subst ) {
513499 Py_ssize_t iparam = tuple_index (parameters , nparams , arg );
@@ -518,43 +504,42 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
518504 else {
519505 arg = subs_tvars (arg , parameters , argitems , nitems );
520506 }
521- if (arg == NULL ) {
522- Py_DECREF (newargs );
523- Py_DECREF (item );
524- Py_XDECREF (tuple_args );
525- return NULL ;
526- }
527507 if (unpack ) {
508+ if (arg == NULL ) {
509+ goto error ;
510+ }
528511 if (!PyTuple_Check (arg )) {
529- Py_DECREF (newargs );
530- Py_DECREF (item );
531- Py_XDECREF (tuple_args );
532512 PyObject * original = PyTuple_GET_ITEM (args , iarg );
533513 PyErr_Format (PyExc_TypeError ,
534514 "expected __typing_subst__ of %T objects to return a tuple, not %T" ,
535515 original , arg );
536516 Py_DECREF (arg );
537- return NULL ;
517+ goto error ;
538518 }
539- jarg = tuple_extend (& newargs , jarg ,
540- & PyTuple_GET_ITEM (arg , 0 ), PyTuple_GET_SIZE (arg ));
541- Py_DECREF (arg );
542- if (jarg < 0 ) {
543- Py_DECREF (item );
544- Py_XDECREF (tuple_args );
545- assert (newargs == NULL );
546- return NULL ;
519+ if (PyTupleWriter_AddArray (newargs ,
520+ _PyTuple_ITEMS (arg ),
521+ PyTuple_GET_SIZE (arg )) < 0 ) {
522+ Py_DECREF (arg );
523+ goto error ;
547524 }
525+ Py_DECREF (arg );
548526 }
549527 else {
550- PyTuple_SET_ITEM (newargs , jarg , arg );
551- jarg ++ ;
528+ if (PyTupleWriter_AddSteal (newargs , arg ) < 0 ) {
529+ goto error ;
530+ }
552531 }
553532 }
554533
555534 Py_DECREF (item );
556535 Py_XDECREF (tuple_args );
557- return newargs ;
536+ return PyTupleWriter_Finish (newargs );
537+
538+ error :
539+ PyTupleWriter_Discard (newargs );
540+ Py_DECREF (item );
541+ Py_XDECREF (tuple_args );
542+ return NULL ;
558543}
559544
560545PyDoc_STRVAR (genericalias__doc__ ,
0 commit comments