Skip to content

Commit bca12da

Browse files
Fidget-Spinnergvanrossumuriyyo
committed
bpo-44490: Partially backport refactor of pythonGH-26980 for easier bugfix backports
Co-Authored-By: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com> Co-Authored-By: Guido van Rossum <gvanrossum@gmail.com> Co-Authored-By: Yurii Karabas <1998uriyyo@gmail.com>
1 parent efda905 commit bca12da

File tree

2 files changed

+36
-19
lines changed

2 files changed

+36
-19
lines changed

Include/genericaliasobject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
extern "C" {
66
#endif
77

8+
#ifndef Py_LIMITED_API
9+
PyAPI_FUNC(PyObject *) _Py_subs_parameters(PyObject *, PyObject *, PyObject *, PyObject *);
10+
PyAPI_FUNC(PyObject *) _Py_make_parameters(PyObject *);
11+
#endif
12+
813
PyAPI_FUNC(PyObject *) Py_GenericAlias(PyObject *, PyObject *);
914
PyAPI_DATA(PyTypeObject) Py_GenericAliasType;
1015

Objects/genericaliasobject.c

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ tuple_add(PyObject *self, Py_ssize_t len, PyObject *item)
198198
return 0;
199199
}
200200

201-
static PyObject *
202-
make_parameters(PyObject *args)
201+
PyObject *
202+
_Py_make_parameters(PyObject *args)
203203
{
204204
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
205205
Py_ssize_t len = nargs;
@@ -294,18 +294,10 @@ subs_tvars(PyObject *obj, PyObject *params, PyObject **argitems)
294294
return obj;
295295
}
296296

297-
static PyObject *
298-
ga_getitem(PyObject *self, PyObject *item)
297+
PyObject *
298+
_Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObject *item)
299299
{
300-
gaobject *alias = (gaobject *)self;
301-
// do a lookup for __parameters__ so it gets populated (if not already)
302-
if (alias->parameters == NULL) {
303-
alias->parameters = make_parameters(alias->args);
304-
if (alias->parameters == NULL) {
305-
return NULL;
306-
}
307-
}
308-
Py_ssize_t nparams = PyTuple_GET_SIZE(alias->parameters);
300+
Py_ssize_t nparams = PyTuple_GET_SIZE(parameters);
309301
if (nparams == 0) {
310302
return PyErr_Format(PyExc_TypeError,
311303
"There are no type variables left in %R",
@@ -320,32 +312,32 @@ ga_getitem(PyObject *self, PyObject *item)
320312
nitems > nparams ? "many" : "few",
321313
self);
322314
}
323-
/* Replace all type variables (specified by alias->parameters)
315+
/* Replace all type variables (specified by parameters)
324316
with corresponding values specified by argitems.
325317
t = list[T]; t[int] -> newargs = [int]
326318
t = dict[str, T]; t[int] -> newargs = [str, int]
327319
t = dict[T, list[S]]; t[str, int] -> newargs = [str, list[int]]
328320
*/
329-
Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args);
321+
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
330322
PyObject *newargs = PyTuple_New(nargs);
331323
if (newargs == NULL) {
332324
return NULL;
333325
}
334326
for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
335-
PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg);
327+
PyObject *arg = PyTuple_GET_ITEM(args, iarg);
336328
int typevar = is_typevar(arg);
337329
if (typevar < 0) {
338330
Py_DECREF(newargs);
339331
return NULL;
340332
}
341333
if (typevar) {
342-
Py_ssize_t iparam = tuple_index(alias->parameters, nparams, arg);
334+
Py_ssize_t iparam = tuple_index(parameters, nparams, arg);
343335
assert(iparam >= 0);
344336
arg = argitems[iparam];
345337
Py_INCREF(arg);
346338
}
347339
else {
348-
arg = subs_tvars(arg, alias->parameters, argitems);
340+
arg = subs_tvars(arg, parameters, argitems);
349341
if (arg == NULL) {
350342
Py_DECREF(newargs);
351343
return NULL;
@@ -354,6 +346,26 @@ ga_getitem(PyObject *self, PyObject *item)
354346
PyTuple_SET_ITEM(newargs, iarg, arg);
355347
}
356348

349+
return newargs;
350+
}
351+
352+
static PyObject *
353+
ga_getitem(PyObject *self, PyObject *item)
354+
{
355+
gaobject *alias = (gaobject *)self;
356+
// Populate __parameters__ if needed.
357+
if (alias->parameters == NULL) {
358+
alias->parameters = _Py_make_parameters(alias->args);
359+
if (alias->parameters == NULL) {
360+
return NULL;
361+
}
362+
}
363+
364+
PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item);
365+
if (newargs == NULL) {
366+
return NULL;
367+
}
368+
357369
PyObject *res = Py_GenericAlias(alias->origin, newargs);
358370

359371
Py_DECREF(newargs);
@@ -550,7 +562,7 @@ ga_parameters(PyObject *self, void *unused)
550562
{
551563
gaobject *alias = (gaobject *)self;
552564
if (alias->parameters == NULL) {
553-
alias->parameters = make_parameters(alias->args);
565+
alias->parameters = _Py_make_parameters(alias->args);
554566
if (alias->parameters == NULL) {
555567
return NULL;
556568
}

0 commit comments

Comments
 (0)