@@ -180,11 +180,22 @@ tuple_extend(PyObject **dst, Py_ssize_t dstindex,
180
180
PyObject *
181
181
_Py_make_parameters (PyObject * args )
182
182
{
183
+ assert (PyTuple_Check (args ) || PyList_Check (args ));
184
+ const bool is_args_list = PyList_Check (args );
185
+ PyObject * tuple_args = NULL ;
186
+ if (is_args_list ) {
187
+ args = tuple_args = PySequence_Tuple (args );
188
+ if (args == NULL ) {
189
+ return NULL ;
190
+ }
191
+ }
183
192
Py_ssize_t nargs = PyTuple_GET_SIZE (args );
184
193
Py_ssize_t len = nargs ;
185
194
PyObject * parameters = PyTuple_New (len );
186
- if (parameters == NULL )
195
+ if (parameters == NULL ) {
196
+ Py_XDECREF (tuple_args );
187
197
return NULL ;
198
+ }
188
199
Py_ssize_t iparam = 0 ;
189
200
for (Py_ssize_t iarg = 0 ; iarg < nargs ; iarg ++ ) {
190
201
PyObject * t = PyTuple_GET_ITEM (args , iarg );
@@ -195,6 +206,7 @@ _Py_make_parameters(PyObject *args)
195
206
int rc = PyObject_HasAttrWithError (t , & _Py_ID (__typing_subst__ ));
196
207
if (rc < 0 ) {
197
208
Py_DECREF (parameters );
209
+ Py_XDECREF (tuple_args );
198
210
return NULL ;
199
211
}
200
212
if (rc ) {
@@ -205,8 +217,19 @@ _Py_make_parameters(PyObject *args)
205
217
if (PyObject_GetOptionalAttr (t , & _Py_ID (__parameters__ ),
206
218
& subparams ) < 0 ) {
207
219
Py_DECREF (parameters );
220
+ Py_XDECREF (tuple_args );
208
221
return NULL ;
209
222
}
223
+ if (!subparams && (PyTuple_Check (t ) || PyList_Check (t ))) {
224
+ // Recursively call _Py_make_parameters for lists/tuples and
225
+ // add the results to the current parameters.
226
+ subparams = _Py_make_parameters (t );
227
+ if (subparams == NULL ) {
228
+ Py_DECREF (parameters );
229
+ Py_XDECREF (tuple_args );
230
+ return NULL ;
231
+ }
232
+ }
210
233
if (subparams && PyTuple_Check (subparams )) {
211
234
Py_ssize_t len2 = PyTuple_GET_SIZE (subparams );
212
235
Py_ssize_t needed = len2 - 1 - (iarg - iparam );
@@ -215,6 +238,7 @@ _Py_make_parameters(PyObject *args)
215
238
if (_PyTuple_Resize (& parameters , len ) < 0 ) {
216
239
Py_DECREF (subparams );
217
240
Py_DECREF (parameters );
241
+ Py_XDECREF (tuple_args );
218
242
return NULL ;
219
243
}
220
244
}
@@ -229,9 +253,11 @@ _Py_make_parameters(PyObject *args)
229
253
if (iparam < len ) {
230
254
if (_PyTuple_Resize (& parameters , iparam ) < 0 ) {
231
255
Py_XDECREF (parameters );
256
+ Py_XDECREF (tuple_args );
232
257
return NULL ;
233
258
}
234
259
}
260
+ Py_XDECREF (tuple_args );
235
261
return parameters ;
236
262
}
237
263
@@ -416,11 +442,22 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
416
442
t = list[T]; t[int] -> newargs = [int]
417
443
t = dict[str, T]; t[int] -> newargs = [str, int]
418
444
t = dict[T, list[S]]; t[str, int] -> newargs = [str, list[int]]
445
+ t = list[[T]]; t[str] -> newargs = [[str]]
419
446
*/
447
+ assert (PyTuple_Check (args ) || PyList_Check (args ));
448
+ const bool is_args_list = PyList_Check (args );
449
+ PyObject * tuple_args = NULL ;
450
+ if (is_args_list ) {
451
+ args = tuple_args = PySequence_Tuple (args );
452
+ if (args == NULL ) {
453
+ return NULL ;
454
+ }
455
+ }
420
456
Py_ssize_t nargs = PyTuple_GET_SIZE (args );
421
457
PyObject * newargs = PyTuple_New (nargs );
422
458
if (newargs == NULL ) {
423
459
Py_DECREF (item );
460
+ Py_XDECREF (tuple_args );
424
461
return NULL ;
425
462
}
426
463
for (Py_ssize_t iarg = 0 , jarg = 0 ; iarg < nargs ; iarg ++ ) {
@@ -430,17 +467,46 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
430
467
jarg ++ ;
431
468
continue ;
432
469
}
433
-
470
+ // Recursively substitute params in lists/tuples.
471
+ if (PyTuple_Check (arg ) || PyList_Check (arg )) {
472
+ PyObject * subargs = _Py_subs_parameters (self , arg , parameters , item );
473
+ if (subargs == NULL ) {
474
+ Py_DECREF (newargs );
475
+ Py_DECREF (item );
476
+ Py_XDECREF (tuple_args );
477
+ return NULL ;
478
+ }
479
+ if (PyTuple_Check (arg )) {
480
+ PyTuple_SET_ITEM (newargs , jarg , subargs );
481
+ }
482
+ else {
483
+ // _Py_subs_parameters returns a tuple. If the original arg was a list,
484
+ // convert subargs to a list as well.
485
+ PyObject * subargs_list = PySequence_List (subargs );
486
+ Py_DECREF (subargs );
487
+ if (subargs_list == NULL ) {
488
+ Py_DECREF (newargs );
489
+ Py_DECREF (item );
490
+ Py_XDECREF (tuple_args );
491
+ return NULL ;
492
+ }
493
+ PyTuple_SET_ITEM (newargs , jarg , subargs_list );
494
+ }
495
+ jarg ++ ;
496
+ continue ;
497
+ }
434
498
int unpack = _is_unpacked_typevartuple (arg );
435
499
if (unpack < 0 ) {
436
500
Py_DECREF (newargs );
437
501
Py_DECREF (item );
502
+ Py_XDECREF (tuple_args );
438
503
return NULL ;
439
504
}
440
505
PyObject * subst ;
441
506
if (PyObject_GetOptionalAttr (arg , & _Py_ID (__typing_subst__ ), & subst ) < 0 ) {
442
507
Py_DECREF (newargs );
443
508
Py_DECREF (item );
509
+ Py_XDECREF (tuple_args );
444
510
return NULL ;
445
511
}
446
512
if (subst ) {
@@ -455,6 +521,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
455
521
if (arg == NULL ) {
456
522
Py_DECREF (newargs );
457
523
Py_DECREF (item );
524
+ Py_XDECREF (tuple_args );
458
525
return NULL ;
459
526
}
460
527
if (unpack ) {
@@ -463,6 +530,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
463
530
Py_DECREF (arg );
464
531
if (jarg < 0 ) {
465
532
Py_DECREF (item );
533
+ Py_XDECREF (tuple_args );
466
534
return NULL ;
467
535
}
468
536
}
@@ -473,6 +541,7 @@ _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObje
473
541
}
474
542
475
543
Py_DECREF (item );
544
+ Py_XDECREF (tuple_args );
476
545
return newargs ;
477
546
}
478
547
0 commit comments