1 // TypeVar, TypeVarTuple, and ParamSpec
2 #include "Python.h"
3 #include "pycore_object.h" // _PyObject_GC_TRACK/UNTRACK
4 #include "pycore_typevarobject.h"
5 #include "pycore_unionobject.h" // _Py_union_type_or
6 #include "structmember.h"
7
8 /*[clinic input]
9 class typevar "typevarobject *" "&_PyTypeVar_Type"
10 class paramspec "paramspecobject *" "&_PyParamSpec_Type"
11 class paramspecargs "paramspecattrobject *" "&_PyParamSpecArgs_Type"
12 class paramspeckwargs "paramspecattrobject *" "&_PyParamSpecKwargs_Type"
13 class typevartuple "typevartupleobject *" "&_PyTypeVarTuple_Type"
14 class typealias "typealiasobject *" "&_PyTypeAlias_Type"
15 class Generic "PyObject *" "&PyGeneric_Type"
16 [clinic start generated code]*/
17 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=aa86741931a0f55c]*/
18
19 typedef struct {
20 PyObject_HEAD
21 PyObject *name;
22 PyObject *bound;
23 PyObject *evaluate_bound;
24 PyObject *constraints;
25 PyObject *evaluate_constraints;
26 bool covariant;
27 bool contravariant;
28 bool infer_variance;
29 } typevarobject;
30
31 typedef struct {
32 PyObject_HEAD
33 PyObject *name;
34 } typevartupleobject;
35
36 typedef struct {
37 PyObject_HEAD
38 PyObject *name;
39 PyObject *bound;
40 bool covariant;
41 bool contravariant;
42 bool infer_variance;
43 } paramspecobject;
44
45 typedef struct {
46 PyObject_HEAD
47 PyObject *name;
48 PyObject *type_params;
49 PyObject *compute_value;
50 PyObject *value;
51 PyObject *module;
52 } typealiasobject;
53
54 #include "clinic/typevarobject.c.h"
55
56 static PyObject *
57 call_typing_func_object(const char *name, PyObject **args, size_t nargs)
58 {
59 PyObject *typing = PyImport_ImportModule("typing");
60 if (typing == NULL) {
61 return NULL;
62 }
63 PyObject *func = PyObject_GetAttrString(typing, name);
64 if (func == NULL) {
65 Py_DECREF(typing);
66 return NULL;
67 }
68 PyObject *result = PyObject_Vectorcall(func, args, nargs, NULL);
69 Py_DECREF(func);
70 Py_DECREF(typing);
71 return result;
72 }
73
74 static PyObject *
75 type_check(PyObject *arg, const char *msg)
76 {
77 // Calling typing.py here leads to bootstrapping problems
78 if (Py_IsNone(arg)) {
79 return Py_NewRef(Py_TYPE(arg));
80 }
81 PyObject *message_str = PyUnicode_FromString(msg);
82 if (message_str == NULL) {
83 return NULL;
84 }
85 PyObject *args[2] = {arg, message_str};
86 PyObject *result = call_typing_func_object("_type_check", args, 2);
87 Py_DECREF(message_str);
88 return result;
89 }
90
91 /*
92 * Return a typing.Union. This is used as the nb_or (|) operator for
93 * TypeVar and ParamSpec. We use this rather than _Py_union_type_or
94 * (which would produce a types.Union) because historically TypeVar
95 * supported unions with string forward references, and we want to
96 * preserve that behavior. _Py_union_type_or only allows a small set
97 * of types.
98 */
99 static PyObject *
100 make_union(PyObject *self, PyObject *other)
101 {
102 PyObject *args[2] = {self, other};
103 PyObject *result = call_typing_func_object("_make_union", args, 2);
104 return result;
105 }
106
107 static PyObject *
108 caller(void)
109 {
110 _PyInterpreterFrame *f = _PyThreadState_GET()->cframe->current_frame;
111 if (f == NULL) {
112 Py_RETURN_NONE;
113 }
114 if (f == NULL || f->f_funcobj == NULL) {
115 Py_RETURN_NONE;
116 }
117 PyObject *r = PyFunction_GetModule(f->f_funcobj);
118 if (!r) {
119 PyErr_Clear();
120 Py_RETURN_NONE;
121 }
122 return Py_NewRef(r);
123 }
124
125 static PyObject *
126 typevartuple_unpack(PyObject *tvt)
127 {
128 PyObject *typing = PyImport_ImportModule("typing");
129 if (typing == NULL) {
130 return NULL;
131 }
132 PyObject *unpack = PyObject_GetAttrString(typing, "Unpack");
133 if (unpack == NULL) {
134 Py_DECREF(typing);
135 return NULL;
136 }
137 PyObject *unpacked = PyObject_GetItem(unpack, tvt);
138 Py_DECREF(typing);
139 Py_DECREF(unpack);
140 return unpacked;
141 }
142
143 static int
144 contains_typevartuple(PyTupleObject *params)
145 {
146 Py_ssize_t n = PyTuple_GET_SIZE(params);
147 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type;
148 for (Py_ssize_t i = 0; i < n; i++) {
149 PyObject *param = PyTuple_GET_ITEM(params, i);
150 if (Py_IS_TYPE(param, tp)) {
151 return 1;
152 }
153 }
154 return 0;
155 }
156
157 static PyObject *
158 unpack_typevartuples(PyObject *params)
159 {
160 assert(PyTuple_Check(params));
161 // TypeVarTuple must be unpacked when passed to Generic, so we do that here.
162 if (contains_typevartuple((PyTupleObject *)params)) {
163 Py_ssize_t n = PyTuple_GET_SIZE(params);
164 PyObject *new_params = PyTuple_New(n);
165 if (new_params == NULL) {
166 return NULL;
167 }
168 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type;
169 for (Py_ssize_t i = 0; i < n; i++) {
170 PyObject *param = PyTuple_GET_ITEM(params, i);
171 if (Py_IS_TYPE(param, tp)) {
172 PyObject *unpacked = typevartuple_unpack(param);
173 if (unpacked == NULL) {
174 Py_DECREF(new_params);
175 return NULL;
176 }
177 PyTuple_SET_ITEM(new_params, i, unpacked);
178 }
179 else {
180 PyTuple_SET_ITEM(new_params, i, Py_NewRef(param));
181 }
182 }
183 return new_params;
184 }
185 else {
186 return Py_NewRef(params);
187 }
188 }
189
190 static void
191 typevar_dealloc(PyObject *self)
192 {
193 PyTypeObject *tp = Py_TYPE(self);
194 typevarobject *tv = (typevarobject *)self;
195
196 _PyObject_GC_UNTRACK(self);
197
198 Py_DECREF(tv->name);
199 Py_XDECREF(tv->bound);
200 Py_XDECREF(tv->evaluate_bound);
201 Py_XDECREF(tv->constraints);
202 Py_XDECREF(tv->evaluate_constraints);
203 _PyObject_ClearManagedDict(self);
204 PyObject_ClearWeakRefs(self);
205
206 Py_TYPE(self)->tp_free(self);
207 Py_DECREF(tp);
208 }
209
210 static int
211 typevar_traverse(PyObject *self, visitproc visit, void *arg)
212 {
213 Py_VISIT(Py_TYPE(self));
214 typevarobject *tv = (typevarobject *)self;
215 Py_VISIT(tv->bound);
216 Py_VISIT(tv->evaluate_bound);
217 Py_VISIT(tv->constraints);
218 Py_VISIT(tv->evaluate_constraints);
219 _PyObject_VisitManagedDict(self, visit, arg);
220 return 0;
221 }
222
223 static int
224 typevar_clear(typevarobject *self)
225 {
226 Py_CLEAR(self->bound);
227 Py_CLEAR(self->evaluate_bound);
228 Py_CLEAR(self->constraints);
229 Py_CLEAR(self->evaluate_constraints);
230 _PyObject_ClearManagedDict((PyObject *)self);
231 return 0;
232 }
233
234 static PyObject *
235 typevar_repr(PyObject *self)
236 {
237 typevarobject *tv = (typevarobject *)self;
238
239 if (tv->infer_variance) {
240 return Py_NewRef(tv->name);
241 }
242
243 char variance = tv->covariant ? '+' : tv->contravariant ? '-' : '~';
244 return PyUnicode_FromFormat("%c%U", variance, tv->name);
245 }
246
247 static PyMemberDef typevar_members[] = {
248 {"__name__", T_OBJECT, offsetof(typevarobject, name), READONLY},
249 {"__covariant__", T_BOOL, offsetof(typevarobject, covariant), READONLY},
250 {"__contravariant__", T_BOOL, offsetof(typevarobject, contravariant), READONLY},
251 {"__infer_variance__", T_BOOL, offsetof(typevarobject, infer_variance), READONLY},
252 {0}
253 };
254
255 static PyObject *
256 typevar_bound(typevarobject *self, void *Py_UNUSED(ignored))
257 {
258 if (self->bound != NULL) {
259 return Py_NewRef(self->bound);
260 }
261 if (self->evaluate_bound == NULL) {
262 Py_RETURN_NONE;
263 }
264 PyObject *bound = PyObject_CallNoArgs(self->evaluate_bound);
265 self->bound = Py_XNewRef(bound);
266 return bound;
267 }
268
269 static PyObject *
270 typevar_constraints(typevarobject *self, void *Py_UNUSED(ignored))
271 {
272 if (self->constraints != NULL) {
273 return Py_NewRef(self->constraints);
274 }
275 if (self->evaluate_constraints == NULL) {
276 return PyTuple_New(0);
277 }
278 PyObject *constraints = PyObject_CallNoArgs(self->evaluate_constraints);
279 self->constraints = Py_XNewRef(constraints);
280 return constraints;
281 }
282
283 static PyGetSetDef typevar_getset[] = {
284 {"__bound__", (getter)typevar_bound, NULL, NULL, NULL},
285 {"__constraints__", (getter)typevar_constraints, NULL, NULL, NULL},
286 {0}
287 };
288
289 static typevarobject *
290 typevar_alloc(PyObject *name, PyObject *bound, PyObject *evaluate_bound,
291 PyObject *constraints, PyObject *evaluate_constraints,
292 bool covariant, bool contravariant, bool infer_variance,
293 PyObject *module)
294 {
295 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevar_type;
296 assert(tp != NULL);
297 typevarobject *tv = PyObject_GC_New(typevarobject, tp);
298 if (tv == NULL) {
299 return NULL;
300 }
301
302 tv->name = Py_NewRef(name);
303
304 tv->bound = Py_XNewRef(bound);
305 tv->evaluate_bound = Py_XNewRef(evaluate_bound);
306 tv->constraints = Py_XNewRef(constraints);
307 tv->evaluate_constraints = Py_XNewRef(evaluate_constraints);
308
309 tv->covariant = covariant;
310 tv->contravariant = contravariant;
311 tv->infer_variance = infer_variance;
312 _PyObject_GC_TRACK(tv);
313
314 if (module != NULL) {
315 if (PyObject_SetAttrString((PyObject *)tv, "__module__", module) < 0) {
316 Py_DECREF(tv);
317 return NULL;
318 }
319 }
320
321 return tv;
322 }
323
324 /*[clinic input]
325 @classmethod
326 typevar.__new__ as typevar_new
327
328 name: object(subclass_of="&PyUnicode_Type")
329 *constraints: object
330 *
331 bound: object = None
332 covariant: bool = False
333 contravariant: bool = False
334 infer_variance: bool = False
335
336 Create a TypeVar.
337 [clinic start generated code]*/
338
339 static PyObject *
340 typevar_new_impl(PyTypeObject *type, PyObject *name, PyObject *constraints,
341 PyObject *bound, int covariant, int contravariant,
342 int infer_variance)
343 /*[clinic end generated code: output=1d200450ee99226d input=2c07ab87c94f462b]*/
344 {
345 if (covariant && contravariant) {
346 PyErr_SetString(PyExc_ValueError,
347 "Bivariant types are not supported.");
348 return NULL;
349 }
350
351 if (infer_variance && (covariant || contravariant)) {
352 PyErr_SetString(PyExc_ValueError,
353 "Variance cannot be specified with infer_variance.");
354 return NULL;
355 }
356
357 if (Py_IsNone(bound)) {
358 bound = NULL;
359 }
360 if (bound != NULL) {
361 bound = type_check(bound, "Bound must be a type.");
362 if (bound == NULL) {
363 return NULL;
364 }
365 }
366
367 if (!PyTuple_CheckExact(constraints)) {
368 PyErr_SetString(PyExc_TypeError,
369 "constraints must be a tuple");
370 return NULL;
371 }
372 Py_ssize_t n_constraints = PyTuple_GET_SIZE(constraints);
373 if (n_constraints == 1) {
374 PyErr_SetString(PyExc_TypeError,
375 "A single constraint is not allowed");
376 Py_XDECREF(bound);
377 return NULL;
378 } else if (n_constraints == 0) {
379 constraints = NULL;
380 } else if (bound != NULL) {
381 PyErr_SetString(PyExc_TypeError,
382 "Constraints cannot be combined with bound=...");
383 Py_XDECREF(bound);
384 return NULL;
385 }
386 PyObject *module = caller();
387 if (module == NULL) {
388 Py_XDECREF(bound);
389 return NULL;
390 }
391
392 PyObject *tv = (PyObject *)typevar_alloc(name, bound, NULL,
393 constraints, NULL,
394 covariant, contravariant,
395 infer_variance, module);
396 Py_XDECREF(bound);
397 Py_XDECREF(module);
398 return tv;
399 }
400
401 /*[clinic input]
402 typevar.__typing_subst__ as typevar_typing_subst
403
404 arg: object
405
406 [clinic start generated code]*/
407
408 static PyObject *
409 typevar_typing_subst_impl(typevarobject *self, PyObject *arg)
410 /*[clinic end generated code: output=c76ced134ed8f4e1 input=6b70a4bb2da838de]*/
411 {
412 PyObject *args[2] = {(PyObject *)self, arg};
413 PyObject *result = call_typing_func_object("_typevar_subst", args, 2);
414 return result;
415 }
416
417 /*[clinic input]
418 typevar.__reduce__ as typevar_reduce
419
420 [clinic start generated code]*/
421
422 static PyObject *
423 typevar_reduce_impl(typevarobject *self)
424 /*[clinic end generated code: output=02e5c55d7cf8a08f input=de76bc95f04fb9ff]*/
425 {
426 return Py_NewRef(self->name);
427 }
428
429 static PyObject *
430 typevar_mro_entries(PyObject *self, PyObject *args)
431 {
432 PyErr_SetString(PyExc_TypeError,
433 "Cannot subclass an instance of TypeVar");
434 return NULL;
435 }
436
437 static PyMethodDef typevar_methods[] = {
438 TYPEVAR_TYPING_SUBST_METHODDEF
439 TYPEVAR_REDUCE_METHODDEF
440 {"__mro_entries__", typevar_mro_entries, METH_O},
441 {0}
442 };
443
444 PyDoc_STRVAR(typevar_doc,
445 "Type variable.\n\
446 \n\
447 The preferred way to construct a type variable is via the dedicated\n\
448 syntax for generic functions, classes, and type aliases::\n\
449 \n\
450 class Sequence[T]: # T is a TypeVar\n\
451 ...\n\
452 \n\
453 This syntax can also be used to create bound and constrained type\n\
454 variables::\n\
455 \n\
456 # S is a TypeVar bound to str\n\
457 class StrSequence[S: str]:\n\
458 ...\n\
459 \n\
460 # A is a TypeVar constrained to str or bytes\n\
461 class StrOrBytesSequence[A: (str, bytes)]:\n\
462 ...\n\
463 \n\
464 However, if desired, reusable type variables can also be constructed\n\
465 manually, like so::\n\
466 \n\
467 T = TypeVar('T') # Can be anything\n\
468 S = TypeVar('S', bound=str) # Can be any subtype of str\n\
469 A = TypeVar('A', str, bytes) # Must be exactly str or bytes\n\
470 \n\
471 Type variables exist primarily for the benefit of static type\n\
472 checkers. They serve as the parameters for generic types as well\n\
473 as for generic function and type alias definitions.\n\
474 \n\
475 The variance of type variables is inferred by type checkers when they\n\
476 are created through the type parameter syntax and when\n\
477 ``infer_variance=True`` is passed. Manually created type variables may\n\
478 be explicitly marked covariant or contravariant by passing\n\
479 ``covariant=True`` or ``contravariant=True``. By default, manually\n\
480 created type variables are invariant. See PEP 484 and PEP 695 for more\n\
481 details.\n\
482 ");
483
484 static PyType_Slot typevar_slots[] = {
485 {Py_tp_doc, (void *)typevar_doc},
486 {Py_tp_methods, typevar_methods},
487 {Py_nb_or, make_union},
488 {Py_tp_new, typevar_new},
489 {Py_tp_dealloc, typevar_dealloc},
490 {Py_tp_alloc, PyType_GenericAlloc},
491 {Py_tp_free, PyObject_GC_Del},
492 {Py_tp_traverse, typevar_traverse},
493 {Py_tp_clear, typevar_clear},
494 {Py_tp_repr, typevar_repr},
495 {Py_tp_members, typevar_members},
496 {Py_tp_getset, typevar_getset},
497 {0, NULL},
498 };
499
500 PyType_Spec typevar_spec = {
501 .name = "typing.TypeVar",
502 .basicsize = sizeof(typevarobject),
503 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
504 | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF,
505 .slots = typevar_slots,
506 };
507
508 typedef struct {
509 PyObject_HEAD
510 PyObject *__origin__;
511 } paramspecattrobject;
512
513 static void
514 paramspecattr_dealloc(PyObject *self)
515 {
516 PyTypeObject *tp = Py_TYPE(self);
517 paramspecattrobject *psa = (paramspecattrobject *)self;
518
519 _PyObject_GC_UNTRACK(self);
520
521 Py_XDECREF(psa->__origin__);
522
523 Py_TYPE(self)->tp_free(self);
524 Py_DECREF(tp);
525 }
526
527 static int
528 paramspecattr_traverse(PyObject *self, visitproc visit, void *arg)
529 {
530 paramspecattrobject *psa = (paramspecattrobject *)self;
531 Py_VISIT(psa->__origin__);
532 return 0;
533 }
534
535 static int
536 paramspecattr_clear(paramspecattrobject *self)
537 {
538 Py_CLEAR(self->__origin__);
539 return 0;
540 }
541
542 static PyObject *
543 paramspecattr_richcompare(PyObject *a, PyObject *b, int op)
544 {
545 if (!Py_IS_TYPE(a, Py_TYPE(b))) {
546 Py_RETURN_NOTIMPLEMENTED;
547 }
548 if (op != Py_EQ && op != Py_NE) {
549 Py_RETURN_NOTIMPLEMENTED;
550 }
551 return PyObject_RichCompare(
552 ((paramspecattrobject *)a)->__origin__,
553 ((paramspecattrobject *)b)->__origin__,
554 op
555 );
556 }
557
558 static PyMemberDef paramspecattr_members[] = {
559 {"__origin__", T_OBJECT, offsetof(paramspecattrobject, __origin__), READONLY},
560 {0}
561 };
562
563 static paramspecattrobject *
564 paramspecattr_new(PyTypeObject *tp, PyObject *origin)
565 {
566 paramspecattrobject *psa = PyObject_GC_New(paramspecattrobject, tp);
567 if (psa == NULL) {
568 return NULL;
569 }
570 psa->__origin__ = Py_NewRef(origin);
571 _PyObject_GC_TRACK(psa);
572 return psa;
573 }
574
575 static PyObject *
576 paramspecargs_repr(PyObject *self)
577 {
578 paramspecattrobject *psa = (paramspecattrobject *)self;
579
580 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type;
581 if (Py_IS_TYPE(psa->__origin__, tp)) {
582 return PyUnicode_FromFormat("%U.args",
583 ((paramspecobject *)psa->__origin__)->name);
584 }
585 return PyUnicode_FromFormat("%R.args", psa->__origin__);
586 }
587
588
589 /*[clinic input]
590 @classmethod
591 paramspecargs.__new__ as paramspecargs_new
592
593 origin: object
594
595 Create a ParamSpecArgs object.
596 [clinic start generated code]*/
597
598 static PyObject *
599 paramspecargs_new_impl(PyTypeObject *type, PyObject *origin)
600 /*[clinic end generated code: output=9a1463dc8942fe4e input=3596a0bb6183c208]*/
601 {
602 return (PyObject *)paramspecattr_new(type, origin);
603 }
604
605 static PyObject *
606 paramspecargs_mro_entries(PyObject *self, PyObject *args)
607 {
608 PyErr_SetString(PyExc_TypeError,
609 "Cannot subclass an instance of ParamSpecArgs");
610 return NULL;
611 }
612
613 static PyMethodDef paramspecargs_methods[] = {
614 {"__mro_entries__", paramspecargs_mro_entries, METH_O},
615 {0}
616 };
617
618 PyDoc_STRVAR(paramspecargs_doc,
619 "The args for a ParamSpec object.\n\
620 \n\
621 Given a ParamSpec object P, P.args is an instance of ParamSpecArgs.\n\
622 \n\
623 ParamSpecArgs objects have a reference back to their ParamSpec::\n\
624 \n\
625 >>> P = ParamSpec(\"P\")\n\
626 >>> P.args.__origin__ is P\n\
627 True\n\
628 \n\
629 This type is meant for runtime introspection and has no special meaning\n\
630 to static type checkers.\n\
631 ");
632
633 static PyType_Slot paramspecargs_slots[] = {
634 {Py_tp_doc, (void *)paramspecargs_doc},
635 {Py_tp_methods, paramspecargs_methods},
636 {Py_tp_new, paramspecargs_new},
637 {Py_tp_dealloc, paramspecattr_dealloc},
638 {Py_tp_alloc, PyType_GenericAlloc},
639 {Py_tp_free, PyObject_GC_Del},
640 {Py_tp_traverse, paramspecattr_traverse},
641 {Py_tp_clear, (inquiry)paramspecattr_clear},
642 {Py_tp_repr, paramspecargs_repr},
643 {Py_tp_members, paramspecattr_members},
644 {Py_tp_richcompare, paramspecattr_richcompare},
645 {0, NULL},
646 };
647
648 PyType_Spec paramspecargs_spec = {
649 .name = "typing.ParamSpecArgs",
650 .basicsize = sizeof(paramspecattrobject),
651 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
652 | Py_TPFLAGS_MANAGED_WEAKREF,
653 .slots = paramspecargs_slots,
654 };
655
656 static PyObject *
657 paramspeckwargs_repr(PyObject *self)
658 {
659 paramspecattrobject *psk = (paramspecattrobject *)self;
660
661 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type;
662 if (Py_IS_TYPE(psk->__origin__, tp)) {
663 return PyUnicode_FromFormat("%U.kwargs",
664 ((paramspecobject *)psk->__origin__)->name);
665 }
666 return PyUnicode_FromFormat("%R.kwargs", psk->__origin__);
667 }
668
669 /*[clinic input]
670 @classmethod
671 paramspeckwargs.__new__ as paramspeckwargs_new
672
673 origin: object
674
675 Create a ParamSpecKwargs object.
676 [clinic start generated code]*/
677
678 static PyObject *
679 paramspeckwargs_new_impl(PyTypeObject *type, PyObject *origin)
680 /*[clinic end generated code: output=277b11967ebaf4ab input=981bca9b0cf9e40a]*/
681 {
682 return (PyObject *)paramspecattr_new(type, origin);
683 }
684
685 static PyObject *
686 paramspeckwargs_mro_entries(PyObject *self, PyObject *args)
687 {
688 PyErr_SetString(PyExc_TypeError,
689 "Cannot subclass an instance of ParamSpecKwargs");
690 return NULL;
691 }
692
693 static PyMethodDef paramspeckwargs_methods[] = {
694 {"__mro_entries__", paramspeckwargs_mro_entries, METH_O},
695 {0}
696 };
697
698 PyDoc_STRVAR(paramspeckwargs_doc,
699 "The kwargs for a ParamSpec object.\n\
700 \n\
701 Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs.\n\
702 \n\
703 ParamSpecKwargs objects have a reference back to their ParamSpec::\n\
704 \n\
705 >>> P = ParamSpec(\"P\")\n\
706 >>> P.kwargs.__origin__ is P\n\
707 True\n\
708 \n\
709 This type is meant for runtime introspection and has no special meaning\n\
710 to static type checkers.\n\
711 ");
712
713 static PyType_Slot paramspeckwargs_slots[] = {
714 {Py_tp_doc, (void *)paramspeckwargs_doc},
715 {Py_tp_methods, paramspeckwargs_methods},
716 {Py_tp_new, paramspeckwargs_new},
717 {Py_tp_dealloc, paramspecattr_dealloc},
718 {Py_tp_alloc, PyType_GenericAlloc},
719 {Py_tp_free, PyObject_GC_Del},
720 {Py_tp_traverse, paramspecattr_traverse},
721 {Py_tp_clear, (inquiry)paramspecattr_clear},
722 {Py_tp_repr, paramspeckwargs_repr},
723 {Py_tp_members, paramspecattr_members},
724 {Py_tp_richcompare, paramspecattr_richcompare},
725 {0, NULL},
726 };
727
728 PyType_Spec paramspeckwargs_spec = {
729 .name = "typing.ParamSpecKwargs",
730 .basicsize = sizeof(paramspecattrobject),
731 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
732 | Py_TPFLAGS_MANAGED_WEAKREF,
733 .slots = paramspeckwargs_slots,
734 };
735
736 static void
737 paramspec_dealloc(PyObject *self)
738 {
739 PyTypeObject *tp = Py_TYPE(self);
740 paramspecobject *ps = (paramspecobject *)self;
741
742 _PyObject_GC_UNTRACK(self);
743
744 Py_DECREF(ps->name);
745 Py_XDECREF(ps->bound);
746 _PyObject_ClearManagedDict(self);
747 PyObject_ClearWeakRefs(self);
748
749 Py_TYPE(self)->tp_free(self);
750 Py_DECREF(tp);
751 }
752
753 static int
754 paramspec_traverse(PyObject *self, visitproc visit, void *arg)
755 {
756 Py_VISIT(Py_TYPE(self));
757 paramspecobject *ps = (paramspecobject *)self;
758 Py_VISIT(ps->bound);
759 _PyObject_VisitManagedDict(self, visit, arg);
760 return 0;
761 }
762
763 static int
764 paramspec_clear(paramspecobject *self)
765 {
766 Py_CLEAR(self->bound);
767 _PyObject_ClearManagedDict((PyObject *)self);
768 return 0;
769 }
770
771 static PyObject *
772 paramspec_repr(PyObject *self)
773 {
774 paramspecobject *ps = (paramspecobject *)self;
775
776 if (ps->infer_variance) {
777 return Py_NewRef(ps->name);
778 }
779
780 char variance = ps->covariant ? '+' : ps->contravariant ? '-' : '~';
781 return PyUnicode_FromFormat("%c%U", variance, ps->name);
782 }
783
784 static PyMemberDef paramspec_members[] = {
785 {"__name__", T_OBJECT, offsetof(paramspecobject, name), READONLY},
786 {"__bound__", T_OBJECT, offsetof(paramspecobject, bound), READONLY},
787 {"__covariant__", T_BOOL, offsetof(paramspecobject, covariant), READONLY},
788 {"__contravariant__", T_BOOL, offsetof(paramspecobject, contravariant), READONLY},
789 {"__infer_variance__", T_BOOL, offsetof(paramspecobject, infer_variance), READONLY},
790 {0}
791 };
792
793 static PyObject *
794 paramspec_args(PyObject *self, void *unused)
795 {
796 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspecargs_type;
797 return (PyObject *)paramspecattr_new(tp, self);
798 }
799
800 static PyObject *
801 paramspec_kwargs(PyObject *self, void *unused)
802 {
803 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspeckwargs_type;
804 return (PyObject *)paramspecattr_new(tp, self);
805 }
806
807 static PyGetSetDef paramspec_getset[] = {
808 {"args", (getter)paramspec_args, NULL, "Represents positional arguments.", NULL},
809 {"kwargs", (getter)paramspec_kwargs, NULL, "Represents keyword arguments.", NULL},
810 {0},
811 };
812
813 static paramspecobject *
814 paramspec_alloc(PyObject *name, PyObject *bound, bool covariant,
815 bool contravariant, bool infer_variance, PyObject *module)
816 {
817 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.paramspec_type;
818 paramspecobject *ps = PyObject_GC_New(paramspecobject, tp);
819 if (ps == NULL) {
820 return NULL;
821 }
822 ps->name = Py_NewRef(name);
823 ps->bound = Py_XNewRef(bound);
824 ps->covariant = covariant;
825 ps->contravariant = contravariant;
826 ps->infer_variance = infer_variance;
827 _PyObject_GC_TRACK(ps);
828 if (module != NULL) {
829 if (PyObject_SetAttrString((PyObject *)ps, "__module__", module) < 0) {
830 Py_DECREF(ps);
831 return NULL;
832 }
833 }
834 return ps;
835 }
836
837 /*[clinic input]
838 @classmethod
839 paramspec.__new__ as paramspec_new
840
841 name: object(subclass_of="&PyUnicode_Type")
842 *
843 bound: object = None
844 covariant: bool = False
845 contravariant: bool = False
846 infer_variance: bool = False
847
848 Create a ParamSpec object.
849 [clinic start generated code]*/
850
851 static PyObject *
852 paramspec_new_impl(PyTypeObject *type, PyObject *name, PyObject *bound,
853 int covariant, int contravariant, int infer_variance)
854 /*[clinic end generated code: output=fd2daab79cba62da input=57c49c581979b952]*/
855 {
856 if (covariant && contravariant) {
857 PyErr_SetString(PyExc_ValueError, "Bivariant types are not supported.");
858 return NULL;
859 }
860 if (infer_variance && (covariant || contravariant)) {
861 PyErr_SetString(PyExc_ValueError, "Variance cannot be specified with infer_variance.");
862 return NULL;
863 }
864 if (bound != NULL) {
865 bound = type_check(bound, "Bound must be a type.");
866 if (bound == NULL) {
867 return NULL;
868 }
869 }
870 PyObject *module = caller();
871 if (module == NULL) {
872 Py_XDECREF(bound);
873 return NULL;
874 }
875 PyObject *ps = (PyObject *)paramspec_alloc(
876 name, bound, covariant, contravariant, infer_variance, module);
877 Py_XDECREF(bound);
878 Py_DECREF(module);
879 return ps;
880 }
881
882
883 /*[clinic input]
884 paramspec.__typing_subst__ as paramspec_typing_subst
885
886 arg: object
887
888 [clinic start generated code]*/
889
890 static PyObject *
891 paramspec_typing_subst_impl(paramspecobject *self, PyObject *arg)
892 /*[clinic end generated code: output=803e1ade3f13b57d input=4e0005d24023e896]*/
893 {
894 PyObject *args[2] = {(PyObject *)self, arg};
895 PyObject *result = call_typing_func_object("_paramspec_subst", args, 2);
896 return result;
897 }
898
899 /*[clinic input]
900 paramspec.__typing_prepare_subst__ as paramspec_typing_prepare_subst
901
902 alias: object
903 args: object
904
905 [clinic start generated code]*/
906
907 static PyObject *
908 paramspec_typing_prepare_subst_impl(paramspecobject *self, PyObject *alias,
909 PyObject *args)
910 /*[clinic end generated code: output=95449d630a2adb9a input=4375e2ffcb2ad635]*/
911 {
912 PyObject *args_array[3] = {(PyObject *)self, alias, args};
913 PyObject *result = call_typing_func_object(
914 "_paramspec_prepare_subst", args_array, 3);
915 return result;
916 }
917
918 /*[clinic input]
919 paramspec.__reduce__ as paramspec_reduce
920
921 [clinic start generated code]*/
922
923 static PyObject *
924 paramspec_reduce_impl(paramspecobject *self)
925 /*[clinic end generated code: output=b83398674416db27 input=5bf349f0d5dd426c]*/
926 {
927 return Py_NewRef(self->name);
928 }
929
930 static PyObject *
931 paramspec_mro_entries(PyObject *self, PyObject *args)
932 {
933 PyErr_SetString(PyExc_TypeError,
934 "Cannot subclass an instance of ParamSpec");
935 return NULL;
936 }
937
938 static PyMethodDef paramspec_methods[] = {
939 PARAMSPEC_TYPING_SUBST_METHODDEF
940 PARAMSPEC_TYPING_PREPARE_SUBST_METHODDEF
941 PARAMSPEC_REDUCE_METHODDEF
942 {"__mro_entries__", paramspec_mro_entries, METH_O},
943 {0}
944 };
945
946 PyDoc_STRVAR(paramspec_doc,
947 "Parameter specification variable.\n\
948 \n\
949 The preferred way to construct a parameter specification is via the\n\
950 dedicated syntax for generic functions, classes, and type aliases,\n\
951 where the use of '**' creates a parameter specification::\n\
952 \n\
953 type IntFunc[**P] = Callable[P, int]\n\
954 \n\
955 For compatibility with Python 3.11 and earlier, ParamSpec objects\n\
956 can also be created as follows::\n\
957 \n\
958 P = ParamSpec('P')\n\
959 \n\
960 Parameter specification variables exist primarily for the benefit of\n\
961 static type checkers. They are used to forward the parameter types of\n\
962 one callable to another callable, a pattern commonly found in\n\
963 higher-order functions and decorators. They are only valid when used\n\
964 in ``Concatenate``, or as the first argument to ``Callable``, or as\n\
965 parameters for user-defined Generics. See class Generic for more\n\
966 information on generic types.\n\
967 \n\
968 An example for annotating a decorator::\n\
969 \n\
970 def add_logging[**P, T](f: Callable[P, T]) -> Callable[P, T]:\n\
971 '''A type-safe decorator to add logging to a function.'''\n\
972 def inner(*args: P.args, **kwargs: P.kwargs) -> T:\n\
973 logging.info(f'{f.__name__} was called')\n\
974 return f(*args, **kwargs)\n\
975 return inner\n\
976 \n\
977 @add_logging\n\
978 def add_two(x: float, y: float) -> float:\n\
979 '''Add two numbers together.'''\n\
980 return x + y\n\
981 \n\
982 Parameter specification variables can be introspected. e.g.::\n\
983 \n\
984 >>> P = ParamSpec(\"P\")\n\
985 >>> P.__name__\n\
986 'P'\n\
987 \n\
988 Note that only parameter specification variables defined in the global\n\
989 scope can be pickled.\n\
990 ");
991
992 static PyType_Slot paramspec_slots[] = {
993 {Py_tp_doc, (void *)paramspec_doc},
994 {Py_tp_members, paramspec_members},
995 {Py_tp_methods, paramspec_methods},
996 {Py_tp_getset, paramspec_getset},
997 // Unions of ParamSpecs have no defined meaning, but they were allowed
998 // by the Python implementation, so we allow them here too.
999 {Py_nb_or, make_union},
1000 {Py_tp_new, paramspec_new},
1001 {Py_tp_dealloc, paramspec_dealloc},
1002 {Py_tp_alloc, PyType_GenericAlloc},
1003 {Py_tp_free, PyObject_GC_Del},
1004 {Py_tp_traverse, paramspec_traverse},
1005 {Py_tp_clear, paramspec_clear},
1006 {Py_tp_repr, paramspec_repr},
1007 {0, 0},
1008 };
1009
1010 PyType_Spec paramspec_spec = {
1011 .name = "typing.ParamSpec",
1012 .basicsize = sizeof(paramspecobject),
1013 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE
1014 | Py_TPFLAGS_MANAGED_DICT | Py_TPFLAGS_MANAGED_WEAKREF,
1015 .slots = paramspec_slots,
1016 };
1017
1018 static void
1019 typevartuple_dealloc(PyObject *self)
1020 {
1021 PyTypeObject *tp = Py_TYPE(self);
1022 _PyObject_GC_UNTRACK(self);
1023 typevartupleobject *tvt = (typevartupleobject *)self;
1024
1025 Py_DECREF(tvt->name);
1026 _PyObject_ClearManagedDict(self);
1027 PyObject_ClearWeakRefs(self);
1028
1029 Py_TYPE(self)->tp_free(self);
1030 Py_DECREF(tp);
1031 }
1032
1033 static PyObject *
1034 typevartuple_iter(PyObject *self)
1035 {
1036 PyObject *unpacked = typevartuple_unpack(self);
1037 if (unpacked == NULL) {
1038 return NULL;
1039 }
1040 PyObject *tuple = PyTuple_Pack(1, unpacked);
1041 if (tuple == NULL) {
1042 Py_DECREF(unpacked);
1043 return NULL;
1044 }
1045 PyObject *result = PyObject_GetIter(tuple);
1046 Py_DECREF(unpacked);
1047 Py_DECREF(tuple);
1048 return result;
1049 }
1050
1051 static PyObject *
1052 typevartuple_repr(PyObject *self)
1053 {
1054 typevartupleobject *tvt = (typevartupleobject *)self;
1055
1056 return Py_NewRef(tvt->name);
1057 }
1058
1059 static PyMemberDef typevartuple_members[] = {
1060 {"__name__", T_OBJECT, offsetof(typevartupleobject, name), READONLY},
1061 {0}
1062 };
1063
1064 static typevartupleobject *
1065 typevartuple_alloc(PyObject *name, PyObject *module)
1066 {
1067 PyTypeObject *tp = PyInterpreterState_Get()->cached_objects.typevartuple_type;
1068 typevartupleobject *tvt = PyObject_GC_New(typevartupleobject, tp);
1069 if (tvt == NULL) {
1070 return NULL;
1071 }
1072 tvt->name = Py_NewRef(name);
1073 _PyObject_GC_TRACK(tvt);
1074 if (module != NULL) {
1075 if (PyObject_SetAttrString((PyObject *)tvt, "__module__", module) < 0) {
1076 Py_DECREF(tvt);
1077 return NULL;
1078 }
1079 }
1080 return tvt;
1081 }
1082
1083 /*[clinic input]
1084 @classmethod
1085 typevartuple.__new__
1086
1087 name: object(subclass_of="&PyUnicode_Type")
1088
1089 Create a new TypeVarTuple with the given name.
1090 [clinic start generated code]*/
1091
1092 static PyObject *
1093 typevartuple_impl(PyTypeObject *type, PyObject *name)
1094 /*[clinic end generated code: output=09d417a28f976202 input=00d28abcf1fc96bb]*/
1095 {
1096 PyObject *module = caller();
1097 if (module == NULL) {
1098 return NULL;
1099 }
1100 PyObject *result = (PyObject *)typevartuple_alloc(name, module);
1101 Py_DECREF(module);
1102 return result;
1103 }
1104
1105 /*[clinic input]
1106 typevartuple.__typing_subst__ as typevartuple_typing_subst
1107
1108 arg: object
1109
1110 [clinic start generated code]*/
1111
1112 static PyObject *
1113 typevartuple_typing_subst_impl(typevartupleobject *self, PyObject *arg)
1114 /*[clinic end generated code: output=814316519441cd76 input=670c4e0a36e5d8c0]*/
1115 {
1116 PyErr_SetString(PyExc_TypeError, "Substitution of bare TypeVarTuple is not supported");
1117 return NULL;
1118 }
1119
1120 /*[clinic input]
1121 typevartuple.__typing_prepare_subst__ as typevartuple_typing_prepare_subst
1122
1123 alias: object
1124 args: object
1125
1126 [clinic start generated code]*/
1127
1128 static PyObject *
1129 typevartuple_typing_prepare_subst_impl(typevartupleobject *self,
1130 PyObject *alias, PyObject *args)
1131 /*[clinic end generated code: output=ff999bc5b02036c1 input=a211b05f2eeb4306]*/
1132 {
1133 PyObject *args_array[3] = {(PyObject *)self, alias, args};
1134 PyObject *result = call_typing_func_object(
1135 "_typevartuple_prepare_subst", args_array, 3);
1136 return result;
1137 }
1138
1139 /*[clinic input]
1140 typevartuple.__reduce__ as typevartuple_reduce
1141
1142 [clinic start generated code]*/
1143
1144 static PyObject *
1145 typevartuple_reduce_impl(typevartupleobject *self)
1146 /*[clinic end generated code: output=3215bc0477913d20 input=3018a4d66147e807]*/
1147 {
1148 return Py_NewRef(self->name);
1149 }
1150
1151 static PyObject *
1152 typevartuple_mro_entries(PyObject *self, PyObject *args)
1153 {
1154 PyErr_SetString(PyExc_TypeError,
1155 "Cannot subclass an instance of TypeVarTuple");
1156 return NULL;
1157 }
1158
1159 static int
1160 typevartuple_traverse(PyObject *self, visitproc visit, void *arg)
1161 {
1162 Py_VISIT(Py_TYPE(self));
1163 _PyObject_VisitManagedDict(self, visit, arg);
1164 return 0;
1165 }
1166
1167 static int
1168 typevartuple_clear(PyObject *self)
1169 {
1170 _PyObject_ClearManagedDict(self);
1171 return 0;
1172 }
1173
1174 static PyMethodDef typevartuple_methods[] = {
1175 TYPEVARTUPLE_TYPING_SUBST_METHODDEF
1176 TYPEVARTUPLE_TYPING_PREPARE_SUBST_METHODDEF
1177 TYPEVARTUPLE_REDUCE_METHODDEF
1178 {"__mro_entries__", typevartuple_mro_entries, METH_O},
1179 {0}
1180 };
1181
1182 PyDoc_STRVAR(typevartuple_doc,
1183 "Type variable tuple. A specialized form of type variable that enables\n\
1184 variadic generics.\n\
1185 \n\
1186 The preferred way to construct a type variable tuple is via the\n\
1187 dedicated syntax for generic functions, classes, and type aliases,\n\
1188 where a single '*' indicates a type variable tuple::\n\
1189 \n\
1190 def move_first_element_to_last[T, *Ts](tup: tuple[T, *Ts]) -> tuple[*Ts, T]:\n\
1191 return (*tup[1:], tup[0])\n\
1192 \n\
1193 For compatibility with Python 3.11 and earlier, TypeVarTuple objects\n\
1194 can also be created as follows::\n\
1195 \n\
1196 Ts = TypeVarTuple('Ts') # Can be given any name\n\
1197 \n\
1198 Just as a TypeVar (type variable) is a placeholder for a single type,\n\
1199 a TypeVarTuple is a placeholder for an *arbitrary* number of types. For\n\
1200 example, if we define a generic class using a TypeVarTuple::\n\
1201 \n\
1202 class C[*Ts]: ...\n\
1203 \n\
1204 Then we can parameterize that class with an arbitrary number of type\n\
1205 arguments::\n\
1206 \n\
1207 C[int] # Fine\n\
1208 C[int, str] # Also fine\n\
1209 C[()] # Even this is fine\n\
1210 \n\
1211 For more details, see PEP 646.\n\
1212 \n\
1213 Note that only TypeVarTuples defined in the global scope can be\n\
1214 pickled.\n\
1215 ");
1216
1217 PyType_Slot typevartuple_slots[] = {
1218 {Py_tp_doc, (void *)typevartuple_doc},
1219 {Py_tp_members, typevartuple_members},
1220 {Py_tp_methods, typevartuple_methods},
1221 {Py_tp_new, typevartuple},
1222 {Py_tp_iter, typevartuple_iter},
1223 {Py_tp_repr, typevartuple_repr},
1224 {Py_tp_dealloc, typevartuple_dealloc},
1225 {Py_tp_alloc, PyType_GenericAlloc},
1226 {Py_tp_free, PyObject_GC_Del},
1227 {Py_tp_traverse, typevartuple_traverse},
1228 {Py_tp_clear, typevartuple_clear},
1229 {0, 0},
1230 };
1231
1232 PyType_Spec typevartuple_spec = {
1233 .name = "typing.TypeVarTuple",
1234 .basicsize = sizeof(typevartupleobject),
1235 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_MANAGED_DICT
1236 | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_MANAGED_WEAKREF,
1237 .slots = typevartuple_slots,
1238 };
1239
1240 PyObject *
1241 _Py_make_typevar(PyObject *name, PyObject *evaluate_bound, PyObject *evaluate_constraints)
1242 {
1243 return (PyObject *)typevar_alloc(name, NULL, evaluate_bound, NULL, evaluate_constraints,
1244 false, false, true, NULL);
1245 }
1246
1247 PyObject *
1248 _Py_make_paramspec(PyThreadState *Py_UNUSED(ignored), PyObject *v)
1249 {
1250 assert(PyUnicode_Check(v));
1251 return (PyObject *)paramspec_alloc(v, NULL, false, false, true, NULL);
1252 }
1253
1254 PyObject *
1255 _Py_make_typevartuple(PyThreadState *Py_UNUSED(ignored), PyObject *v)
1256 {
1257 assert(PyUnicode_Check(v));
1258 return (PyObject *)typevartuple_alloc(v, NULL);
1259 }
1260
1261 static void
1262 typealias_dealloc(PyObject *self)
1263 {
1264 PyTypeObject *tp = Py_TYPE(self);
1265 _PyObject_GC_UNTRACK(self);
1266 typealiasobject *ta = (typealiasobject *)self;
1267 Py_DECREF(ta->name);
1268 Py_XDECREF(ta->type_params);
1269 Py_XDECREF(ta->compute_value);
1270 Py_XDECREF(ta->value);
1271 Py_XDECREF(ta->module);
1272 Py_TYPE(self)->tp_free(self);
1273 Py_DECREF(tp);
1274 }
1275
1276 static PyObject *
1277 typealias_get_value(typealiasobject *ta)
1278 {
1279 if (ta->value != NULL) {
1280 return Py_NewRef(ta->value);
1281 }
1282 PyObject *result = PyObject_CallNoArgs(ta->compute_value);
1283 if (result == NULL) {
1284 return NULL;
1285 }
1286 ta->value = Py_NewRef(result);
1287 return result;
1288 }
1289
1290 static PyObject *
1291 typealias_repr(PyObject *self)
1292 {
1293 typealiasobject *ta = (typealiasobject *)self;
1294 return Py_NewRef(ta->name);
1295 }
1296
1297 static PyMemberDef typealias_members[] = {
1298 {"__name__", T_OBJECT, offsetof(typealiasobject, name), READONLY},
1299 {0}
1300 };
1301
1302 static PyObject *
1303 typealias_value(PyObject *self, void *unused)
1304 {
1305 typealiasobject *ta = (typealiasobject *)self;
1306 return typealias_get_value(ta);
1307 }
1308
1309 static PyObject *
1310 typealias_parameters(PyObject *self, void *unused)
1311 {
1312 typealiasobject *ta = (typealiasobject *)self;
1313 if (ta->type_params == NULL) {
1314 return PyTuple_New(0);
1315 }
1316 return unpack_typevartuples(ta->type_params);
1317 }
1318
1319 static PyObject *
1320 typealias_type_params(PyObject *self, void *unused)
1321 {
1322 typealiasobject *ta = (typealiasobject *)self;
1323 if (ta->type_params == NULL) {
1324 return PyTuple_New(0);
1325 }
1326 return Py_NewRef(ta->type_params);
1327 }
1328
1329 static PyObject *
1330 typealias_module(PyObject *self, void *unused)
1331 {
1332 typealiasobject *ta = (typealiasobject *)self;
1333 if (ta->module != NULL) {
1334 return Py_NewRef(ta->module);
1335 }
1336 if (ta->compute_value != NULL) {
1337 PyObject* mod = PyFunction_GetModule(ta->compute_value);
1338 if (mod != NULL) {
1339 // PyFunction_GetModule() returns a borrowed reference,
1340 // and it may return NULL (e.g., for functions defined
1341 // in an exec()'ed block).
1342 return Py_NewRef(mod);
1343 }
1344 }
1345 Py_RETURN_NONE;
1346 }
1347
1348 static PyGetSetDef typealias_getset[] = {
1349 {"__parameters__", typealias_parameters, (setter)NULL, NULL, NULL},
1350 {"__type_params__", typealias_type_params, (setter)NULL, NULL, NULL},
1351 {"__value__", typealias_value, (setter)NULL, NULL, NULL},
1352 {"__module__", typealias_module, (setter)NULL, NULL, NULL},
1353 {0}
1354 };
1355
1356 static typealiasobject *
1357 typealias_alloc(PyObject *name, PyObject *type_params, PyObject *compute_value,
1358 PyObject *value, PyObject *module)
1359 {
1360 typealiasobject *ta = PyObject_GC_New(typealiasobject, &_PyTypeAlias_Type);
1361 if (ta == NULL) {
1362 return NULL;
1363 }
1364 ta->name = Py_NewRef(name);
1365 ta->type_params = Py_IsNone(type_params) ? NULL : Py_XNewRef(type_params);
1366 ta->compute_value = Py_XNewRef(compute_value);
1367 ta->value = Py_XNewRef(value);
1368 ta->module = Py_XNewRef(module);
1369 _PyObject_GC_TRACK(ta);
1370 return ta;
1371 }
1372
1373 static int
1374 typealias_traverse(typealiasobject *self, visitproc visit, void *arg)
1375 {
1376 Py_VISIT(self->type_params);
1377 Py_VISIT(self->compute_value);
1378 Py_VISIT(self->value);
1379 Py_VISIT(self->module);
1380 return 0;
1381 }
1382
1383 static int
1384 typealias_clear(typealiasobject *self)
1385 {
1386 Py_CLEAR(self->type_params);
1387 Py_CLEAR(self->compute_value);
1388 Py_CLEAR(self->value);
1389 Py_CLEAR(self->module);
1390 return 0;
1391 }
1392
1393 /*[clinic input]
1394 typealias.__reduce__ as typealias_reduce
1395
1396 [clinic start generated code]*/
1397
1398 static PyObject *
1399 typealias_reduce_impl(typealiasobject *self)
1400 /*[clinic end generated code: output=913724f92ad3b39b input=4f06fbd9472ec0f1]*/
1401 {
1402 return Py_NewRef(self->name);
1403 }
1404
1405 static PyObject *
1406 typealias_subscript(PyObject *self, PyObject *args)
1407 {
1408 if (((typealiasobject *)self)->type_params == NULL) {
1409 PyErr_SetString(PyExc_TypeError,
1410 "Only generic type aliases are subscriptable");
1411 return NULL;
1412 }
1413 return Py_GenericAlias(self, args);
1414 }
1415
1416 static PyMethodDef typealias_methods[] = {
1417 TYPEALIAS_REDUCE_METHODDEF
1418 {0}
1419 };
1420
1421
1422 /*[clinic input]
1423 @classmethod
1424 typealias.__new__ as typealias_new
1425
1426 name: object(subclass_of="&PyUnicode_Type")
1427 value: object
1428 *
1429 type_params: object = NULL
1430
1431 Create a TypeAliasType.
1432 [clinic start generated code]*/
1433
1434 static PyObject *
1435 typealias_new_impl(PyTypeObject *type, PyObject *name, PyObject *value,
1436 PyObject *type_params)
1437 /*[clinic end generated code: output=8920ce6bdff86f00 input=df163c34e17e1a35]*/
1438 {
1439 if (type_params != NULL && !PyTuple_Check(type_params)) {
1440 PyErr_SetString(PyExc_TypeError, "type_params must be a tuple");
1441 return NULL;
1442 }
1443 PyObject *module = caller();
1444 if (module == NULL) {
1445 return NULL;
1446 }
1447 PyObject *ta = (PyObject *)typealias_alloc(name, type_params, NULL, value,
1448 module);
1449 Py_DECREF(module);
1450 return ta;
1451 }
1452
1453 PyDoc_STRVAR(typealias_doc,
1454 "Type alias.\n\
1455 \n\
1456 Type aliases are created through the type statement::\n\
1457 \n\
1458 type Alias = int\n\
1459 \n\
1460 In this example, Alias and int will be treated equivalently by static\n\
1461 type checkers.\n\
1462 \n\
1463 At runtime, Alias is an instance of TypeAliasType. The __name__\n\
1464 attribute holds the name of the type alias. The value of the type alias\n\
1465 is stored in the __value__ attribute. It is evaluated lazily, so the\n\
1466 value is computed only if the attribute is accessed.\n\
1467 \n\
1468 Type aliases can also be generic::\n\
1469 \n\
1470 type ListOrSet[T] = list[T] | set[T]\n\
1471 \n\
1472 In this case, the type parameters of the alias are stored in the\n\
1473 __type_params__ attribute.\n\
1474 \n\
1475 See PEP 695 for more information.\n\
1476 ");
1477
1478 static PyNumberMethods typealias_as_number = {
1479 .nb_or = _Py_union_type_or,
1480 };
1481
1482 static PyMappingMethods typealias_as_mapping = {
1483 .mp_subscript = typealias_subscript,
1484 };
1485
1486 PyTypeObject _PyTypeAlias_Type = {
1487 PyVarObject_HEAD_INIT(&PyType_Type, 0)
1488 .tp_name = "typing.TypeAliasType",
1489 .tp_basicsize = sizeof(typealiasobject),
1490 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_HAVE_GC,
1491 .tp_doc = typealias_doc,
1492 .tp_members = typealias_members,
1493 .tp_methods = typealias_methods,
1494 .tp_getset = typealias_getset,
1495 .tp_alloc = PyType_GenericAlloc,
1496 .tp_dealloc = typealias_dealloc,
1497 .tp_new = typealias_new,
1498 .tp_free = PyObject_GC_Del,
1499 .tp_traverse = (traverseproc)typealias_traverse,
1500 .tp_clear = (inquiry)typealias_clear,
1501 .tp_repr = typealias_repr,
1502 .tp_as_number = &typealias_as_number,
1503 .tp_as_mapping = &typealias_as_mapping,
1504 };
1505
1506 PyObject *
1507 _Py_make_typealias(PyThreadState* unused, PyObject *args)
1508 {
1509 assert(PyTuple_Check(args));
1510 assert(PyTuple_GET_SIZE(args) == 3);
1511 PyObject *name = PyTuple_GET_ITEM(args, 0);
1512 assert(PyUnicode_Check(name));
1513 PyObject *type_params = PyTuple_GET_ITEM(args, 1);
1514 PyObject *compute_value = PyTuple_GET_ITEM(args, 2);
1515 assert(PyFunction_Check(compute_value));
1516 return (PyObject *)typealias_alloc(name, type_params, compute_value, NULL, NULL);
1517 }
1518
1519 PyDoc_STRVAR(generic_doc,
1520 "Abstract base class for generic types.\n\
1521 \n\
1522 On Python 3.12 and newer, generic classes implicitly inherit from\n\
1523 Generic when they declare a parameter list after the class's name::\n\
1524 \n\
1525 class Mapping[KT, VT]:\n\
1526 def __getitem__(self, key: KT) -> VT:\n\
1527 ...\n\
1528 # Etc.\n\
1529 \n\
1530 On older versions of Python, however, generic classes have to\n\
1531 explicitly inherit from Generic.\n\
1532 \n\
1533 After a class has been declared to be generic, it can then be used as\n\
1534 follows::\n\
1535 \n\
1536 def lookup_name[KT, VT](mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:\n\
1537 try:\n\
1538 return mapping[key]\n\
1539 except KeyError:\n\
1540 return default\n\
1541 ");
1542
1543 PyDoc_STRVAR(generic_class_getitem_doc,
1544 "Parameterizes a generic class.\n\
1545 \n\
1546 At least, parameterizing a generic class is the *main* thing this\n\
1547 method does. For example, for some generic class `Foo`, this is called\n\
1548 when we do `Foo[int]` - there, with `cls=Foo` and `params=int`.\n\
1549 \n\
1550 However, note that this method is also called when defining generic\n\
1551 classes in the first place with `class Foo[T]: ...`.\n\
1552 ");
1553
1554 static PyObject *
1555 call_typing_args_kwargs(const char *name, PyTypeObject *cls, PyObject *args, PyObject *kwargs)
1556 {
1557 PyObject *typing = NULL, *func = NULL, *new_args = NULL;
1558 typing = PyImport_ImportModule("typing");
1559 if (typing == NULL) {
1560 goto error;
1561 }
1562 func = PyObject_GetAttrString(typing, name);
1563 if (func == NULL) {
1564 goto error;
1565 }
1566 assert(PyTuple_Check(args));
1567 Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1568 new_args = PyTuple_New(nargs + 1);
1569 if (new_args == NULL) {
1570 goto error;
1571 }
1572 PyTuple_SET_ITEM(new_args, 0, Py_NewRef((PyObject *)cls));
1573 for (Py_ssize_t i = 0; i < nargs; i++) {
1574 PyObject *arg = PyTuple_GET_ITEM(args, i);
1575 PyTuple_SET_ITEM(new_args, i + 1, Py_NewRef(arg));
1576 }
1577 PyObject *result = PyObject_Call(func, new_args, kwargs);
1578 Py_DECREF(typing);
1579 Py_DECREF(func);
1580 Py_DECREF(new_args);
1581 return result;
1582 error:
1583 Py_XDECREF(typing);
1584 Py_XDECREF(func);
1585 Py_XDECREF(new_args);
1586 return NULL;
1587 }
1588
1589 static PyObject *
1590 generic_init_subclass(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
1591 {
1592 return call_typing_args_kwargs("_generic_init_subclass", cls, args, kwargs);
1593 }
1594
1595 static PyObject *
1596 generic_class_getitem(PyTypeObject *cls, PyObject *args, PyObject *kwargs)
1597 {
1598 return call_typing_args_kwargs("_generic_class_getitem", cls, args, kwargs);
1599 }
1600
1601 PyObject *
1602 _Py_subscript_generic(PyThreadState* unused, PyObject *params)
1603 {
1604 params = unpack_typevartuples(params);
1605
1606 PyInterpreterState *interp = PyInterpreterState_Get();
1607 if (interp->cached_objects.generic_type == NULL) {
1608 PyErr_SetString(PyExc_SystemError, "Cannot find Generic type");
1609 return NULL;
1610 }
1611 PyObject *args[2] = {(PyObject *)interp->cached_objects.generic_type, params};
1612 PyObject *result = call_typing_func_object("_GenericAlias", args, 2);
1613 Py_DECREF(params);
1614 return result;
1615 }
1616
1617 static PyMethodDef generic_methods[] = {
1618 {"__class_getitem__", (PyCFunction)(void (*)(void))generic_class_getitem,
1619 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
1620 generic_class_getitem_doc},
1621 {"__init_subclass__", (PyCFunction)(void (*)(void))generic_init_subclass,
1622 METH_VARARGS | METH_KEYWORDS | METH_CLASS,
1623 PyDoc_STR("Function to initialize subclasses.")},
1624 {NULL} /* Sentinel */
1625 };
1626
1627 static void
1628 generic_dealloc(PyObject *self)
1629 {
1630 PyTypeObject *tp = Py_TYPE(self);
1631 _PyObject_GC_UNTRACK(self);
1632 Py_TYPE(self)->tp_free(self);
1633 Py_DECREF(tp);
1634 }
1635
1636 static int
1637 generic_traverse(PyObject *self, visitproc visit, void *arg)
1638 {
1639 Py_VISIT(Py_TYPE(self));
1640 return 0;
1641 }
1642
1643 static PyType_Slot generic_slots[] = {
1644 {Py_tp_doc, (void *)generic_doc},
1645 {Py_tp_methods, generic_methods},
1646 {Py_tp_dealloc, generic_dealloc},
1647 {Py_tp_alloc, PyType_GenericAlloc},
1648 {Py_tp_free, PyObject_GC_Del},
1649 {Py_tp_traverse, generic_traverse},
1650 {0, NULL},
1651 };
1652
1653 PyType_Spec generic_spec = {
1654 .name = "typing.Generic",
1655 .basicsize = sizeof(PyObject),
1656 .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC,
1657 .slots = generic_slots,
1658 };
1659
1660 int _Py_initialize_generic(PyInterpreterState *interp)
1661 {
1662 #define MAKE_TYPE(name) \
1663 do { \
1664 PyTypeObject *name ## _type = (PyTypeObject *)PyType_FromSpec(&name ## _spec); \
1665 if (name ## _type == NULL) { \
1666 return -1; \
1667 } \
1668 interp->cached_objects.name ## _type = name ## _type; \
1669 } while(0)
1670
1671 MAKE_TYPE(generic);
1672 MAKE_TYPE(typevar);
1673 MAKE_TYPE(typevartuple);
1674 MAKE_TYPE(paramspec);
1675 MAKE_TYPE(paramspecargs);
1676 MAKE_TYPE(paramspeckwargs);
1677 #undef MAKE_TYPE
1678 return 0;
1679 }
1680
1681 void _Py_clear_generic_types(PyInterpreterState *interp)
1682 {
1683 Py_CLEAR(interp->cached_objects.generic_type);
1684 Py_CLEAR(interp->cached_objects.typevar_type);
1685 Py_CLEAR(interp->cached_objects.typevartuple_type);
1686 Py_CLEAR(interp->cached_objects.paramspec_type);
1687 Py_CLEAR(interp->cached_objects.paramspecargs_type);
1688 Py_CLEAR(interp->cached_objects.paramspeckwargs_type);
1689 }