blob: c5a81a5c1aab22456e2a01e23560549e438c8531 [file] [log] [blame]
Guido van Rossum48b069a2020-04-07 09:50:06 -07001// types.GenericAlias -- used to represent e.g. list[int].
2
3#include "Python.h"
4#include "pycore_object.h"
Victor Stinner4a21e572020-04-15 02:35:41 +02005#include "structmember.h" // PyMemberDef
Guido van Rossum48b069a2020-04-07 09:50:06 -07006
7typedef struct {
8 PyObject_HEAD
9 PyObject *origin;
10 PyObject *args;
11 PyObject *parameters;
kj71ba5f52020-11-18 05:45:08 +070012 PyObject* weakreflist;
Guido van Rossum48b069a2020-04-07 09:50:06 -070013} gaobject;
14
15static void
16ga_dealloc(PyObject *self)
17{
18 gaobject *alias = (gaobject *)self;
19
20 _PyObject_GC_UNTRACK(self);
kj71ba5f52020-11-18 05:45:08 +070021 if (alias->weakreflist != NULL) {
22 PyObject_ClearWeakRefs((PyObject *)alias);
23 }
Guido van Rossum48b069a2020-04-07 09:50:06 -070024 Py_XDECREF(alias->origin);
25 Py_XDECREF(alias->args);
26 Py_XDECREF(alias->parameters);
27 self->ob_type->tp_free(self);
28}
29
30static int
31ga_traverse(PyObject *self, visitproc visit, void *arg)
32{
33 gaobject *alias = (gaobject *)self;
34 Py_VISIT(alias->origin);
35 Py_VISIT(alias->args);
36 Py_VISIT(alias->parameters);
37 return 0;
38}
39
40static int
41ga_repr_item(_PyUnicodeWriter *writer, PyObject *p)
42{
43 _Py_IDENTIFIER(__module__);
44 _Py_IDENTIFIER(__qualname__);
45 _Py_IDENTIFIER(__origin__);
46 _Py_IDENTIFIER(__args__);
47 PyObject *qualname = NULL;
48 PyObject *module = NULL;
49 PyObject *r = NULL;
50 PyObject *tmp;
51 int err;
52
53 if (p == Py_Ellipsis) {
54 // The Ellipsis object
55 r = PyUnicode_FromString("...");
56 goto done;
57 }
58
59 if (_PyObject_LookupAttrId(p, &PyId___origin__, &tmp) < 0) {
60 goto done;
61 }
62 if (tmp != NULL) {
63 Py_DECREF(tmp);
64 if (_PyObject_LookupAttrId(p, &PyId___args__, &tmp) < 0) {
65 goto done;
66 }
67 if (tmp != NULL) {
68 Py_DECREF(tmp);
69 // It looks like a GenericAlias
70 goto use_repr;
71 }
72 }
73
74 if (_PyObject_LookupAttrId(p, &PyId___qualname__, &qualname) < 0) {
75 goto done;
76 }
77 if (qualname == NULL) {
78 goto use_repr;
79 }
80 if (_PyObject_LookupAttrId(p, &PyId___module__, &module) < 0) {
81 goto done;
82 }
83 if (module == NULL || module == Py_None) {
84 goto use_repr;
85 }
86
87 // Looks like a class
88 if (PyUnicode_Check(module) &&
89 _PyUnicode_EqualToASCIIString(module, "builtins"))
90 {
91 // builtins don't need a module name
92 r = PyObject_Str(qualname);
93 goto done;
94 }
95 else {
96 r = PyUnicode_FromFormat("%S.%S", module, qualname);
97 goto done;
98 }
99
100use_repr:
101 r = PyObject_Repr(p);
102
103done:
104 Py_XDECREF(qualname);
105 Py_XDECREF(module);
106 if (r == NULL) {
107 // error if any of the above PyObject_Repr/PyUnicode_From* fail
108 err = -1;
109 }
110 else {
111 err = _PyUnicodeWriter_WriteStr(writer, r);
112 Py_DECREF(r);
113 }
114 return err;
115}
116
117static PyObject *
118ga_repr(PyObject *self)
119{
120 gaobject *alias = (gaobject *)self;
121 Py_ssize_t len = PyTuple_GET_SIZE(alias->args);
122
123 _PyUnicodeWriter writer;
124 _PyUnicodeWriter_Init(&writer);
Victor Stinner4a21e572020-04-15 02:35:41 +0200125
Guido van Rossum48b069a2020-04-07 09:50:06 -0700126 if (ga_repr_item(&writer, alias->origin) < 0) {
127 goto error;
128 }
129 if (_PyUnicodeWriter_WriteASCIIString(&writer, "[", 1) < 0) {
130 goto error;
131 }
132 for (Py_ssize_t i = 0; i < len; i++) {
133 if (i > 0) {
134 if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) {
135 goto error;
136 }
137 }
138 PyObject *p = PyTuple_GET_ITEM(alias->args, i);
139 if (ga_repr_item(&writer, p) < 0) {
140 goto error;
141 }
142 }
143 if (len == 0) {
144 // for something like tuple[()] we should print a "()"
145 if (_PyUnicodeWriter_WriteASCIIString(&writer, "()", 2) < 0) {
146 goto error;
147 }
148 }
149 if (_PyUnicodeWriter_WriteASCIIString(&writer, "]", 1) < 0) {
150 goto error;
151 }
152 return _PyUnicodeWriter_Finish(&writer);
153error:
154 _PyUnicodeWriter_Dealloc(&writer);
155 return NULL;
156}
157
158// isinstance(obj, TypeVar) without importing typing.py.
159// Returns -1 for errors.
160static int
161is_typevar(PyObject *obj)
162{
163 PyTypeObject *type = Py_TYPE(obj);
164 if (strcmp(type->tp_name, "TypeVar") != 0) {
165 return 0;
166 }
167 PyObject *module = PyObject_GetAttrString((PyObject *)type, "__module__");
168 if (module == NULL) {
169 return -1;
170 }
171 int res = PyUnicode_Check(module)
172 && _PyUnicode_EqualToASCIIString(module, "typing");
173 Py_DECREF(module);
174 return res;
175}
176
177// Index of item in self[:len], or -1 if not found (self is a tuple)
178static Py_ssize_t
179tuple_index(PyObject *self, Py_ssize_t len, PyObject *item)
180{
181 for (Py_ssize_t i = 0; i < len; i++) {
182 if (PyTuple_GET_ITEM(self, i) == item) {
183 return i;
184 }
185 }
186 return -1;
187}
188
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300189static int
190tuple_add(PyObject *self, Py_ssize_t len, PyObject *item)
191{
192 if (tuple_index(self, len, item) < 0) {
193 Py_INCREF(item);
194 PyTuple_SET_ITEM(self, len, item);
195 return 1;
196 }
197 return 0;
198}
199
Guido van Rossum48b069a2020-04-07 09:50:06 -0700200static PyObject *
201make_parameters(PyObject *args)
202{
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300203 Py_ssize_t nargs = PyTuple_GET_SIZE(args);
204 Py_ssize_t len = nargs;
Guido van Rossum48b069a2020-04-07 09:50:06 -0700205 PyObject *parameters = PyTuple_New(len);
206 if (parameters == NULL)
207 return NULL;
208 Py_ssize_t iparam = 0;
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300209 for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
Guido van Rossum48b069a2020-04-07 09:50:06 -0700210 PyObject *t = PyTuple_GET_ITEM(args, iarg);
211 int typevar = is_typevar(t);
212 if (typevar < 0) {
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300213 Py_DECREF(parameters);
Guido van Rossum48b069a2020-04-07 09:50:06 -0700214 return NULL;
215 }
216 if (typevar) {
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300217 iparam += tuple_add(parameters, iparam, t);
218 }
219 else {
220 _Py_IDENTIFIER(__parameters__);
221 PyObject *subparams;
222 if (_PyObject_LookupAttrId(t, &PyId___parameters__, &subparams) < 0) {
223 Py_DECREF(parameters);
224 return NULL;
Guido van Rossum48b069a2020-04-07 09:50:06 -0700225 }
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300226 if (subparams && PyTuple_Check(subparams)) {
227 Py_ssize_t len2 = PyTuple_GET_SIZE(subparams);
228 Py_ssize_t needed = len2 - 1 - (iarg - iparam);
229 if (needed > 0) {
230 len += needed;
231 if (_PyTuple_Resize(&parameters, len) < 0) {
232 Py_DECREF(subparams);
233 Py_DECREF(parameters);
234 return NULL;
235 }
236 }
237 for (Py_ssize_t j = 0; j < len2; j++) {
238 PyObject *t2 = PyTuple_GET_ITEM(subparams, j);
239 iparam += tuple_add(parameters, iparam, t2);
240 }
241 }
242 Py_XDECREF(subparams);
Guido van Rossum48b069a2020-04-07 09:50:06 -0700243 }
244 }
245 if (iparam < len) {
246 if (_PyTuple_Resize(&parameters, iparam) < 0) {
247 Py_XDECREF(parameters);
248 return NULL;
249 }
250 }
251 return parameters;
252}
253
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300254/* If obj is a generic alias, substitute type variables params
255 with substitutions argitems. For example, if obj is list[T],
256 params is (T, S), and argitems is (str, int), return list[str].
257 If obj doesn't have a __parameters__ attribute or that's not
258 a non-empty tuple, return a new reference to obj. */
259static PyObject *
260subs_tvars(PyObject *obj, PyObject *params, PyObject **argitems)
261{
262 _Py_IDENTIFIER(__parameters__);
263 PyObject *subparams;
264 if (_PyObject_LookupAttrId(obj, &PyId___parameters__, &subparams) < 0) {
265 return NULL;
266 }
267 if (subparams && PyTuple_Check(subparams) && PyTuple_GET_SIZE(subparams)) {
268 Py_ssize_t nparams = PyTuple_GET_SIZE(params);
269 Py_ssize_t nsubargs = PyTuple_GET_SIZE(subparams);
270 PyObject *subargs = PyTuple_New(nsubargs);
271 if (subargs == NULL) {
272 Py_DECREF(subparams);
273 return NULL;
274 }
275 for (Py_ssize_t i = 0; i < nsubargs; ++i) {
276 PyObject *arg = PyTuple_GET_ITEM(subparams, i);
277 Py_ssize_t iparam = tuple_index(params, nparams, arg);
278 if (iparam >= 0) {
279 arg = argitems[iparam];
280 }
281 Py_INCREF(arg);
282 PyTuple_SET_ITEM(subargs, i, arg);
283 }
284
285 obj = PyObject_GetItem(obj, subargs);
286
287 Py_DECREF(subargs);
288 }
289 else {
290 Py_INCREF(obj);
291 }
292 Py_XDECREF(subparams);
293 return obj;
294}
295
Guido van Rossum48b069a2020-04-07 09:50:06 -0700296static PyObject *
297ga_getitem(PyObject *self, PyObject *item)
298{
299 gaobject *alias = (gaobject *)self;
300 // do a lookup for __parameters__ so it gets populated (if not already)
301 if (alias->parameters == NULL) {
302 alias->parameters = make_parameters(alias->args);
303 if (alias->parameters == NULL) {
304 return NULL;
305 }
306 }
307 Py_ssize_t nparams = PyTuple_GET_SIZE(alias->parameters);
308 if (nparams == 0) {
309 return PyErr_Format(PyExc_TypeError,
310 "There are no type variables left in %R",
311 self);
312 }
313 int is_tuple = PyTuple_Check(item);
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300314 Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1;
315 PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item;
316 if (nitems != nparams) {
Guido van Rossum48b069a2020-04-07 09:50:06 -0700317 return PyErr_Format(PyExc_TypeError,
318 "Too %s arguments for %R",
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300319 nitems > nparams ? "many" : "few",
Guido van Rossum48b069a2020-04-07 09:50:06 -0700320 self);
321 }
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300322 /* Replace all type variables (specified by alias->parameters)
323 with corresponding values specified by argitems.
324 t = list[T]; t[int] -> newargs = [int]
325 t = dict[str, T]; t[int] -> newargs = [str, int]
326 t = dict[T, list[S]]; t[str, int] -> newargs = [str, list[int]]
327 */
Guido van Rossum48b069a2020-04-07 09:50:06 -0700328 Py_ssize_t nargs = PyTuple_GET_SIZE(alias->args);
329 PyObject *newargs = PyTuple_New(nargs);
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300330 if (newargs == NULL) {
Guido van Rossum48b069a2020-04-07 09:50:06 -0700331 return NULL;
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300332 }
Guido van Rossum48b069a2020-04-07 09:50:06 -0700333 for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
334 PyObject *arg = PyTuple_GET_ITEM(alias->args, iarg);
335 int typevar = is_typevar(arg);
336 if (typevar < 0) {
337 Py_DECREF(newargs);
338 return NULL;
339 }
340 if (typevar) {
341 Py_ssize_t iparam = tuple_index(alias->parameters, nparams, arg);
342 assert(iparam >= 0);
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300343 arg = argitems[iparam];
344 Py_INCREF(arg);
345 }
346 else {
347 arg = subs_tvars(arg, alias->parameters, argitems);
348 if (arg == NULL) {
349 Py_DECREF(newargs);
350 return NULL;
Guido van Rossum48b069a2020-04-07 09:50:06 -0700351 }
352 }
Guido van Rossum48b069a2020-04-07 09:50:06 -0700353 PyTuple_SET_ITEM(newargs, iarg, arg);
354 }
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300355
Guido van Rossum48b069a2020-04-07 09:50:06 -0700356 PyObject *res = Py_GenericAlias(alias->origin, newargs);
Serhiy Storchaka41a64582020-05-04 10:56:05 +0300357
Guido van Rossum48b069a2020-04-07 09:50:06 -0700358 Py_DECREF(newargs);
359 return res;
360}
361
362static PyMappingMethods ga_as_mapping = {
363 .mp_subscript = ga_getitem,
364};
365
366static Py_hash_t
367ga_hash(PyObject *self)
368{
369 gaobject *alias = (gaobject *)self;
370 // TODO: Hash in the hash for the origin
371 Py_hash_t h0 = PyObject_Hash(alias->origin);
372 if (h0 == -1) {
373 return -1;
374 }
375 Py_hash_t h1 = PyObject_Hash(alias->args);
376 if (h1 == -1) {
377 return -1;
378 }
379 return h0 ^ h1;
380}
381
382static PyObject *
383ga_call(PyObject *self, PyObject *args, PyObject *kwds)
384{
385 gaobject *alias = (gaobject *)self;
386 PyObject *obj = PyObject_Call(alias->origin, args, kwds);
387 if (obj != NULL) {
388 if (PyObject_SetAttrString(obj, "__orig_class__", self) < 0) {
389 if (!PyErr_ExceptionMatches(PyExc_AttributeError) &&
390 !PyErr_ExceptionMatches(PyExc_TypeError))
391 {
392 Py_DECREF(obj);
393 return NULL;
394 }
395 PyErr_Clear();
396 }
397 }
398 return obj;
399}
400
401static const char* const attr_exceptions[] = {
402 "__origin__",
403 "__args__",
404 "__parameters__",
405 "__mro_entries__",
406 "__reduce_ex__", // needed so we don't look up object.__reduce_ex__
407 "__reduce__",
408 NULL,
409};
410
411static PyObject *
412ga_getattro(PyObject *self, PyObject *name)
413{
414 gaobject *alias = (gaobject *)self;
415 if (PyUnicode_Check(name)) {
416 for (const char * const *p = attr_exceptions; ; p++) {
417 if (*p == NULL) {
418 return PyObject_GetAttr(alias->origin, name);
419 }
420 if (_PyUnicode_EqualToASCIIString(name, *p)) {
421 break;
422 }
423 }
424 }
425 return PyObject_GenericGetAttr(self, name);
426}
427
428static PyObject *
429ga_richcompare(PyObject *a, PyObject *b, int op)
430{
Hai Shi5e8ffe12020-05-04 21:31:38 +0800431 if (!Py_IS_TYPE(a, &Py_GenericAliasType) ||
432 !Py_IS_TYPE(b, &Py_GenericAliasType) ||
Guido van Rossum48b069a2020-04-07 09:50:06 -0700433 (op != Py_EQ && op != Py_NE))
434 {
435 Py_RETURN_NOTIMPLEMENTED;
436 }
437
438 if (op == Py_NE) {
439 PyObject *eq = ga_richcompare(a, b, Py_EQ);
440 if (eq == NULL)
441 return NULL;
442 Py_DECREF(eq);
443 if (eq == Py_True) {
444 Py_RETURN_FALSE;
445 }
446 else {
447 Py_RETURN_TRUE;
448 }
449 }
450
451 gaobject *aa = (gaobject *)a;
452 gaobject *bb = (gaobject *)b;
453 int eq = PyObject_RichCompareBool(aa->origin, bb->origin, Py_EQ);
454 if (eq < 0) {
455 return NULL;
456 }
457 if (!eq) {
458 Py_RETURN_FALSE;
459 }
460 return PyObject_RichCompare(aa->args, bb->args, Py_EQ);
461}
462
463static PyObject *
464ga_mro_entries(PyObject *self, PyObject *args)
465{
466 gaobject *alias = (gaobject *)self;
467 return PyTuple_Pack(1, alias->origin);
468}
469
470static PyObject *
471ga_instancecheck(PyObject *self, PyObject *Py_UNUSED(ignored))
472{
473 PyErr_SetString(PyExc_TypeError,
474 "isinstance() argument 2 cannot be a parameterized generic");
475 return NULL;
476}
477
478static PyObject *
479ga_subclasscheck(PyObject *self, PyObject *Py_UNUSED(ignored))
480{
481 PyErr_SetString(PyExc_TypeError,
482 "issubclass() argument 2 cannot be a parameterized generic");
483 return NULL;
484}
485
486static PyObject *
487ga_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
488{
489 gaobject *alias = (gaobject *)self;
490 return Py_BuildValue("O(OO)", Py_TYPE(alias),
491 alias->origin, alias->args);
492}
493
Miss Islington (bot)49917d52020-09-15 16:37:13 -0700494static PyObject *
495ga_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
496{
497 gaobject *alias = (gaobject *)self;
498 PyObject *dir = PyObject_Dir(alias->origin);
499 if (dir == NULL) {
500 return NULL;
501 }
502
503 PyObject *dir_entry = NULL;
504 for (const char * const *p = attr_exceptions; ; p++) {
505 if (*p == NULL) {
506 break;
507 }
508 else {
509 dir_entry = PyUnicode_FromString(*p);
510 if (dir_entry == NULL) {
511 goto error;
512 }
513 int contains = PySequence_Contains(dir, dir_entry);
514 if (contains < 0) {
515 goto error;
516 }
517 if (contains == 0 && PyList_Append(dir, dir_entry) < 0) {
518 goto error;
519 }
520
521 Py_CLEAR(dir_entry);
522 }
523 }
524 return dir;
525
526error:
527 Py_DECREF(dir);
528 Py_XDECREF(dir_entry);
529 return NULL;
530}
531
Guido van Rossum48b069a2020-04-07 09:50:06 -0700532static PyMethodDef ga_methods[] = {
533 {"__mro_entries__", ga_mro_entries, METH_O},
534 {"__instancecheck__", ga_instancecheck, METH_O},
535 {"__subclasscheck__", ga_subclasscheck, METH_O},
536 {"__reduce__", ga_reduce, METH_NOARGS},
Miss Islington (bot)49917d52020-09-15 16:37:13 -0700537 {"__dir__", ga_dir, METH_NOARGS},
Guido van Rossum48b069a2020-04-07 09:50:06 -0700538 {0}
539};
540
541static PyMemberDef ga_members[] = {
542 {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},
543 {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY},
544 {0}
545};
546
547static PyObject *
548ga_parameters(PyObject *self, void *unused)
549{
550 gaobject *alias = (gaobject *)self;
551 if (alias->parameters == NULL) {
552 alias->parameters = make_parameters(alias->args);
553 if (alias->parameters == NULL) {
554 return NULL;
555 }
556 }
557 Py_INCREF(alias->parameters);
558 return alias->parameters;
559}
560
561static PyGetSetDef ga_properties[] = {
562 {"__parameters__", ga_parameters, (setter)NULL, "Type variables in the GenericAlias.", NULL},
563 {0}
564};
565
566static PyObject *
567ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
568{
Miss Islington (bot)d5c029b2020-12-05 08:24:38 -0800569 if (!_PyArg_NoKeywords("GenericAlias", kwds)) {
Guido van Rossum48b069a2020-04-07 09:50:06 -0700570 return NULL;
571 }
Dong-hee Na02e44842020-04-24 01:25:53 +0900572 if (!_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 2)) {
Guido van Rossum48b069a2020-04-07 09:50:06 -0700573 return NULL;
574 }
575 PyObject *origin = PyTuple_GET_ITEM(args, 0);
576 PyObject *arguments = PyTuple_GET_ITEM(args, 1);
577 return Py_GenericAlias(origin, arguments);
578}
579
580// TODO:
581// - argument clinic?
582// - __doc__?
583// - cache?
584PyTypeObject Py_GenericAliasType = {
585 PyVarObject_HEAD_INIT(&PyType_Type, 0)
586 .tp_name = "types.GenericAlias",
587 .tp_doc = "Represent a PEP 585 generic type\n"
588 "\n"
Miss Skeleton (bot)3da210b2020-10-08 15:02:26 -0700589 "E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).",
Guido van Rossum48b069a2020-04-07 09:50:06 -0700590 .tp_basicsize = sizeof(gaobject),
591 .tp_dealloc = ga_dealloc,
592 .tp_repr = ga_repr,
593 .tp_as_mapping = &ga_as_mapping,
594 .tp_hash = ga_hash,
595 .tp_call = ga_call,
596 .tp_getattro = ga_getattro,
597 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
598 .tp_traverse = ga_traverse,
599 .tp_richcompare = ga_richcompare,
kj71ba5f52020-11-18 05:45:08 +0700600 .tp_weaklistoffset = offsetof(gaobject, weakreflist),
Guido van Rossum48b069a2020-04-07 09:50:06 -0700601 .tp_methods = ga_methods,
602 .tp_members = ga_members,
603 .tp_alloc = PyType_GenericAlloc,
604 .tp_new = ga_new,
605 .tp_free = PyObject_GC_Del,
606 .tp_getset = ga_properties,
607};
608
609PyObject *
610Py_GenericAlias(PyObject *origin, PyObject *args)
611{
612 if (!PyTuple_Check(args)) {
613 args = PyTuple_Pack(1, args);
614 if (args == NULL) {
615 return NULL;
616 }
617 }
618 else {
619 Py_INCREF(args);
620 }
621
622 gaobject *alias = PyObject_GC_New(gaobject, &Py_GenericAliasType);
623 if (alias == NULL) {
624 Py_DECREF(args);
625 return NULL;
626 }
627
628 Py_INCREF(origin);
629 alias->origin = origin;
630 alias->args = args;
631 alias->parameters = NULL;
kj71ba5f52020-11-18 05:45:08 +0700632 alias->weakreflist = NULL;
Guido van Rossum48b069a2020-04-07 09:50:06 -0700633 _PyObject_GC_TRACK(alias);
634 return (PyObject *)alias;
635}