17db96d56Sopenharmony_ci// types.GenericAlias -- used to represent e.g. list[int]. 27db96d56Sopenharmony_ci 37db96d56Sopenharmony_ci#include "Python.h" 47db96d56Sopenharmony_ci#include "pycore_object.h" 57db96d56Sopenharmony_ci#include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check 67db96d56Sopenharmony_ci#include "structmember.h" // PyMemberDef 77db96d56Sopenharmony_ci 87db96d56Sopenharmony_ci#include <stdbool.h> 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_citypedef struct { 117db96d56Sopenharmony_ci PyObject_HEAD 127db96d56Sopenharmony_ci PyObject *origin; 137db96d56Sopenharmony_ci PyObject *args; 147db96d56Sopenharmony_ci PyObject *parameters; 157db96d56Sopenharmony_ci PyObject *weakreflist; 167db96d56Sopenharmony_ci // Whether we're a starred type, e.g. *tuple[int]. 177db96d56Sopenharmony_ci bool starred; 187db96d56Sopenharmony_ci vectorcallfunc vectorcall; 197db96d56Sopenharmony_ci} gaobject; 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_citypedef struct { 227db96d56Sopenharmony_ci PyObject_HEAD 237db96d56Sopenharmony_ci PyObject *obj; /* Set to NULL when iterator is exhausted */ 247db96d56Sopenharmony_ci} gaiterobject; 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_cistatic void 277db96d56Sopenharmony_ciga_dealloc(PyObject *self) 287db96d56Sopenharmony_ci{ 297db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 307db96d56Sopenharmony_ci 317db96d56Sopenharmony_ci _PyObject_GC_UNTRACK(self); 327db96d56Sopenharmony_ci if (alias->weakreflist != NULL) { 337db96d56Sopenharmony_ci PyObject_ClearWeakRefs((PyObject *)alias); 347db96d56Sopenharmony_ci } 357db96d56Sopenharmony_ci Py_XDECREF(alias->origin); 367db96d56Sopenharmony_ci Py_XDECREF(alias->args); 377db96d56Sopenharmony_ci Py_XDECREF(alias->parameters); 387db96d56Sopenharmony_ci Py_TYPE(self)->tp_free(self); 397db96d56Sopenharmony_ci} 407db96d56Sopenharmony_ci 417db96d56Sopenharmony_cistatic int 427db96d56Sopenharmony_ciga_traverse(PyObject *self, visitproc visit, void *arg) 437db96d56Sopenharmony_ci{ 447db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 457db96d56Sopenharmony_ci Py_VISIT(alias->origin); 467db96d56Sopenharmony_ci Py_VISIT(alias->args); 477db96d56Sopenharmony_ci Py_VISIT(alias->parameters); 487db96d56Sopenharmony_ci return 0; 497db96d56Sopenharmony_ci} 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_cistatic int 527db96d56Sopenharmony_ciga_repr_item(_PyUnicodeWriter *writer, PyObject *p) 537db96d56Sopenharmony_ci{ 547db96d56Sopenharmony_ci PyObject *qualname = NULL; 557db96d56Sopenharmony_ci PyObject *module = NULL; 567db96d56Sopenharmony_ci PyObject *r = NULL; 577db96d56Sopenharmony_ci PyObject *tmp; 587db96d56Sopenharmony_ci int err; 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci if (p == Py_Ellipsis) { 617db96d56Sopenharmony_ci // The Ellipsis object 627db96d56Sopenharmony_ci r = PyUnicode_FromString("..."); 637db96d56Sopenharmony_ci goto done; 647db96d56Sopenharmony_ci } 657db96d56Sopenharmony_ci 667db96d56Sopenharmony_ci if (_PyObject_LookupAttr(p, &_Py_ID(__origin__), &tmp) < 0) { 677db96d56Sopenharmony_ci goto done; 687db96d56Sopenharmony_ci } 697db96d56Sopenharmony_ci if (tmp != NULL) { 707db96d56Sopenharmony_ci Py_DECREF(tmp); 717db96d56Sopenharmony_ci if (_PyObject_LookupAttr(p, &_Py_ID(__args__), &tmp) < 0) { 727db96d56Sopenharmony_ci goto done; 737db96d56Sopenharmony_ci } 747db96d56Sopenharmony_ci if (tmp != NULL) { 757db96d56Sopenharmony_ci Py_DECREF(tmp); 767db96d56Sopenharmony_ci // It looks like a GenericAlias 777db96d56Sopenharmony_ci goto use_repr; 787db96d56Sopenharmony_ci } 797db96d56Sopenharmony_ci } 807db96d56Sopenharmony_ci 817db96d56Sopenharmony_ci if (_PyObject_LookupAttr(p, &_Py_ID(__qualname__), &qualname) < 0) { 827db96d56Sopenharmony_ci goto done; 837db96d56Sopenharmony_ci } 847db96d56Sopenharmony_ci if (qualname == NULL) { 857db96d56Sopenharmony_ci goto use_repr; 867db96d56Sopenharmony_ci } 877db96d56Sopenharmony_ci if (_PyObject_LookupAttr(p, &_Py_ID(__module__), &module) < 0) { 887db96d56Sopenharmony_ci goto done; 897db96d56Sopenharmony_ci } 907db96d56Sopenharmony_ci if (module == NULL || module == Py_None) { 917db96d56Sopenharmony_ci goto use_repr; 927db96d56Sopenharmony_ci } 937db96d56Sopenharmony_ci 947db96d56Sopenharmony_ci // Looks like a class 957db96d56Sopenharmony_ci if (PyUnicode_Check(module) && 967db96d56Sopenharmony_ci _PyUnicode_EqualToASCIIString(module, "builtins")) 977db96d56Sopenharmony_ci { 987db96d56Sopenharmony_ci // builtins don't need a module name 997db96d56Sopenharmony_ci r = PyObject_Str(qualname); 1007db96d56Sopenharmony_ci goto done; 1017db96d56Sopenharmony_ci } 1027db96d56Sopenharmony_ci else { 1037db96d56Sopenharmony_ci r = PyUnicode_FromFormat("%S.%S", module, qualname); 1047db96d56Sopenharmony_ci goto done; 1057db96d56Sopenharmony_ci } 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ciuse_repr: 1087db96d56Sopenharmony_ci r = PyObject_Repr(p); 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_cidone: 1117db96d56Sopenharmony_ci Py_XDECREF(qualname); 1127db96d56Sopenharmony_ci Py_XDECREF(module); 1137db96d56Sopenharmony_ci if (r == NULL) { 1147db96d56Sopenharmony_ci // error if any of the above PyObject_Repr/PyUnicode_From* fail 1157db96d56Sopenharmony_ci err = -1; 1167db96d56Sopenharmony_ci } 1177db96d56Sopenharmony_ci else { 1187db96d56Sopenharmony_ci err = _PyUnicodeWriter_WriteStr(writer, r); 1197db96d56Sopenharmony_ci Py_DECREF(r); 1207db96d56Sopenharmony_ci } 1217db96d56Sopenharmony_ci return err; 1227db96d56Sopenharmony_ci} 1237db96d56Sopenharmony_ci 1247db96d56Sopenharmony_cistatic PyObject * 1257db96d56Sopenharmony_ciga_repr(PyObject *self) 1267db96d56Sopenharmony_ci{ 1277db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 1287db96d56Sopenharmony_ci Py_ssize_t len = PyTuple_GET_SIZE(alias->args); 1297db96d56Sopenharmony_ci 1307db96d56Sopenharmony_ci _PyUnicodeWriter writer; 1317db96d56Sopenharmony_ci _PyUnicodeWriter_Init(&writer); 1327db96d56Sopenharmony_ci 1337db96d56Sopenharmony_ci if (alias->starred) { 1347db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteASCIIString(&writer, "*", 1) < 0) { 1357db96d56Sopenharmony_ci goto error; 1367db96d56Sopenharmony_ci } 1377db96d56Sopenharmony_ci } 1387db96d56Sopenharmony_ci if (ga_repr_item(&writer, alias->origin) < 0) { 1397db96d56Sopenharmony_ci goto error; 1407db96d56Sopenharmony_ci } 1417db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteASCIIString(&writer, "[", 1) < 0) { 1427db96d56Sopenharmony_ci goto error; 1437db96d56Sopenharmony_ci } 1447db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < len; i++) { 1457db96d56Sopenharmony_ci if (i > 0) { 1467db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) { 1477db96d56Sopenharmony_ci goto error; 1487db96d56Sopenharmony_ci } 1497db96d56Sopenharmony_ci } 1507db96d56Sopenharmony_ci PyObject *p = PyTuple_GET_ITEM(alias->args, i); 1517db96d56Sopenharmony_ci if (ga_repr_item(&writer, p) < 0) { 1527db96d56Sopenharmony_ci goto error; 1537db96d56Sopenharmony_ci } 1547db96d56Sopenharmony_ci } 1557db96d56Sopenharmony_ci if (len == 0) { 1567db96d56Sopenharmony_ci // for something like tuple[()] we should print a "()" 1577db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteASCIIString(&writer, "()", 2) < 0) { 1587db96d56Sopenharmony_ci goto error; 1597db96d56Sopenharmony_ci } 1607db96d56Sopenharmony_ci } 1617db96d56Sopenharmony_ci if (_PyUnicodeWriter_WriteASCIIString(&writer, "]", 1) < 0) { 1627db96d56Sopenharmony_ci goto error; 1637db96d56Sopenharmony_ci } 1647db96d56Sopenharmony_ci return _PyUnicodeWriter_Finish(&writer); 1657db96d56Sopenharmony_cierror: 1667db96d56Sopenharmony_ci _PyUnicodeWriter_Dealloc(&writer); 1677db96d56Sopenharmony_ci return NULL; 1687db96d56Sopenharmony_ci} 1697db96d56Sopenharmony_ci 1707db96d56Sopenharmony_ci// Index of item in self[:len], or -1 if not found (self is a tuple) 1717db96d56Sopenharmony_cistatic Py_ssize_t 1727db96d56Sopenharmony_cituple_index(PyObject *self, Py_ssize_t len, PyObject *item) 1737db96d56Sopenharmony_ci{ 1747db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < len; i++) { 1757db96d56Sopenharmony_ci if (PyTuple_GET_ITEM(self, i) == item) { 1767db96d56Sopenharmony_ci return i; 1777db96d56Sopenharmony_ci } 1787db96d56Sopenharmony_ci } 1797db96d56Sopenharmony_ci return -1; 1807db96d56Sopenharmony_ci} 1817db96d56Sopenharmony_ci 1827db96d56Sopenharmony_cistatic int 1837db96d56Sopenharmony_cituple_add(PyObject *self, Py_ssize_t len, PyObject *item) 1847db96d56Sopenharmony_ci{ 1857db96d56Sopenharmony_ci if (tuple_index(self, len, item) < 0) { 1867db96d56Sopenharmony_ci Py_INCREF(item); 1877db96d56Sopenharmony_ci PyTuple_SET_ITEM(self, len, item); 1887db96d56Sopenharmony_ci return 1; 1897db96d56Sopenharmony_ci } 1907db96d56Sopenharmony_ci return 0; 1917db96d56Sopenharmony_ci} 1927db96d56Sopenharmony_ci 1937db96d56Sopenharmony_cistatic Py_ssize_t 1947db96d56Sopenharmony_cituple_extend(PyObject **dst, Py_ssize_t dstindex, 1957db96d56Sopenharmony_ci PyObject **src, Py_ssize_t count) 1967db96d56Sopenharmony_ci{ 1977db96d56Sopenharmony_ci assert(count >= 0); 1987db96d56Sopenharmony_ci if (_PyTuple_Resize(dst, PyTuple_GET_SIZE(*dst) + count - 1) != 0) { 1997db96d56Sopenharmony_ci return -1; 2007db96d56Sopenharmony_ci } 2017db96d56Sopenharmony_ci assert(dstindex + count <= PyTuple_GET_SIZE(*dst)); 2027db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < count; ++i) { 2037db96d56Sopenharmony_ci PyObject *item = src[i]; 2047db96d56Sopenharmony_ci Py_INCREF(item); 2057db96d56Sopenharmony_ci PyTuple_SET_ITEM(*dst, dstindex + i, item); 2067db96d56Sopenharmony_ci } 2077db96d56Sopenharmony_ci return dstindex + count; 2087db96d56Sopenharmony_ci} 2097db96d56Sopenharmony_ci 2107db96d56Sopenharmony_ciPyObject * 2117db96d56Sopenharmony_ci_Py_make_parameters(PyObject *args) 2127db96d56Sopenharmony_ci{ 2137db96d56Sopenharmony_ci Py_ssize_t nargs = PyTuple_GET_SIZE(args); 2147db96d56Sopenharmony_ci Py_ssize_t len = nargs; 2157db96d56Sopenharmony_ci PyObject *parameters = PyTuple_New(len); 2167db96d56Sopenharmony_ci if (parameters == NULL) 2177db96d56Sopenharmony_ci return NULL; 2187db96d56Sopenharmony_ci Py_ssize_t iparam = 0; 2197db96d56Sopenharmony_ci for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { 2207db96d56Sopenharmony_ci PyObject *t = PyTuple_GET_ITEM(args, iarg); 2217db96d56Sopenharmony_ci PyObject *subst; 2227db96d56Sopenharmony_ci // We don't want __parameters__ descriptor of a bare Python class. 2237db96d56Sopenharmony_ci if (PyType_Check(t)) { 2247db96d56Sopenharmony_ci continue; 2257db96d56Sopenharmony_ci } 2267db96d56Sopenharmony_ci if (_PyObject_LookupAttr(t, &_Py_ID(__typing_subst__), &subst) < 0) { 2277db96d56Sopenharmony_ci Py_DECREF(parameters); 2287db96d56Sopenharmony_ci return NULL; 2297db96d56Sopenharmony_ci } 2307db96d56Sopenharmony_ci if (subst) { 2317db96d56Sopenharmony_ci iparam += tuple_add(parameters, iparam, t); 2327db96d56Sopenharmony_ci Py_DECREF(subst); 2337db96d56Sopenharmony_ci } 2347db96d56Sopenharmony_ci else { 2357db96d56Sopenharmony_ci PyObject *subparams; 2367db96d56Sopenharmony_ci if (_PyObject_LookupAttr(t, &_Py_ID(__parameters__), 2377db96d56Sopenharmony_ci &subparams) < 0) { 2387db96d56Sopenharmony_ci Py_DECREF(parameters); 2397db96d56Sopenharmony_ci return NULL; 2407db96d56Sopenharmony_ci } 2417db96d56Sopenharmony_ci if (subparams && PyTuple_Check(subparams)) { 2427db96d56Sopenharmony_ci Py_ssize_t len2 = PyTuple_GET_SIZE(subparams); 2437db96d56Sopenharmony_ci Py_ssize_t needed = len2 - 1 - (iarg - iparam); 2447db96d56Sopenharmony_ci if (needed > 0) { 2457db96d56Sopenharmony_ci len += needed; 2467db96d56Sopenharmony_ci if (_PyTuple_Resize(¶meters, len) < 0) { 2477db96d56Sopenharmony_ci Py_DECREF(subparams); 2487db96d56Sopenharmony_ci Py_DECREF(parameters); 2497db96d56Sopenharmony_ci return NULL; 2507db96d56Sopenharmony_ci } 2517db96d56Sopenharmony_ci } 2527db96d56Sopenharmony_ci for (Py_ssize_t j = 0; j < len2; j++) { 2537db96d56Sopenharmony_ci PyObject *t2 = PyTuple_GET_ITEM(subparams, j); 2547db96d56Sopenharmony_ci iparam += tuple_add(parameters, iparam, t2); 2557db96d56Sopenharmony_ci } 2567db96d56Sopenharmony_ci } 2577db96d56Sopenharmony_ci Py_XDECREF(subparams); 2587db96d56Sopenharmony_ci } 2597db96d56Sopenharmony_ci } 2607db96d56Sopenharmony_ci if (iparam < len) { 2617db96d56Sopenharmony_ci if (_PyTuple_Resize(¶meters, iparam) < 0) { 2627db96d56Sopenharmony_ci Py_XDECREF(parameters); 2637db96d56Sopenharmony_ci return NULL; 2647db96d56Sopenharmony_ci } 2657db96d56Sopenharmony_ci } 2667db96d56Sopenharmony_ci return parameters; 2677db96d56Sopenharmony_ci} 2687db96d56Sopenharmony_ci 2697db96d56Sopenharmony_ci/* If obj is a generic alias, substitute type variables params 2707db96d56Sopenharmony_ci with substitutions argitems. For example, if obj is list[T], 2717db96d56Sopenharmony_ci params is (T, S), and argitems is (str, int), return list[str]. 2727db96d56Sopenharmony_ci If obj doesn't have a __parameters__ attribute or that's not 2737db96d56Sopenharmony_ci a non-empty tuple, return a new reference to obj. */ 2747db96d56Sopenharmony_cistatic PyObject * 2757db96d56Sopenharmony_cisubs_tvars(PyObject *obj, PyObject *params, 2767db96d56Sopenharmony_ci PyObject **argitems, Py_ssize_t nargs) 2777db96d56Sopenharmony_ci{ 2787db96d56Sopenharmony_ci PyObject *subparams; 2797db96d56Sopenharmony_ci if (_PyObject_LookupAttr(obj, &_Py_ID(__parameters__), &subparams) < 0) { 2807db96d56Sopenharmony_ci return NULL; 2817db96d56Sopenharmony_ci } 2827db96d56Sopenharmony_ci if (subparams && PyTuple_Check(subparams) && PyTuple_GET_SIZE(subparams)) { 2837db96d56Sopenharmony_ci Py_ssize_t nparams = PyTuple_GET_SIZE(params); 2847db96d56Sopenharmony_ci Py_ssize_t nsubargs = PyTuple_GET_SIZE(subparams); 2857db96d56Sopenharmony_ci PyObject *subargs = PyTuple_New(nsubargs); 2867db96d56Sopenharmony_ci if (subargs == NULL) { 2877db96d56Sopenharmony_ci Py_DECREF(subparams); 2887db96d56Sopenharmony_ci return NULL; 2897db96d56Sopenharmony_ci } 2907db96d56Sopenharmony_ci Py_ssize_t j = 0; 2917db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < nsubargs; ++i) { 2927db96d56Sopenharmony_ci PyObject *arg = PyTuple_GET_ITEM(subparams, i); 2937db96d56Sopenharmony_ci Py_ssize_t iparam = tuple_index(params, nparams, arg); 2947db96d56Sopenharmony_ci if (iparam >= 0) { 2957db96d56Sopenharmony_ci PyObject *param = PyTuple_GET_ITEM(params, iparam); 2967db96d56Sopenharmony_ci arg = argitems[iparam]; 2977db96d56Sopenharmony_ci if (Py_TYPE(param)->tp_iter && PyTuple_Check(arg)) { // TypeVarTuple 2987db96d56Sopenharmony_ci j = tuple_extend(&subargs, j, 2997db96d56Sopenharmony_ci &PyTuple_GET_ITEM(arg, 0), 3007db96d56Sopenharmony_ci PyTuple_GET_SIZE(arg)); 3017db96d56Sopenharmony_ci if (j < 0) { 3027db96d56Sopenharmony_ci return NULL; 3037db96d56Sopenharmony_ci } 3047db96d56Sopenharmony_ci continue; 3057db96d56Sopenharmony_ci } 3067db96d56Sopenharmony_ci } 3077db96d56Sopenharmony_ci Py_INCREF(arg); 3087db96d56Sopenharmony_ci PyTuple_SET_ITEM(subargs, j, arg); 3097db96d56Sopenharmony_ci j++; 3107db96d56Sopenharmony_ci } 3117db96d56Sopenharmony_ci assert(j == PyTuple_GET_SIZE(subargs)); 3127db96d56Sopenharmony_ci 3137db96d56Sopenharmony_ci obj = PyObject_GetItem(obj, subargs); 3147db96d56Sopenharmony_ci 3157db96d56Sopenharmony_ci Py_DECREF(subargs); 3167db96d56Sopenharmony_ci } 3177db96d56Sopenharmony_ci else { 3187db96d56Sopenharmony_ci Py_INCREF(obj); 3197db96d56Sopenharmony_ci } 3207db96d56Sopenharmony_ci Py_XDECREF(subparams); 3217db96d56Sopenharmony_ci return obj; 3227db96d56Sopenharmony_ci} 3237db96d56Sopenharmony_ci 3247db96d56Sopenharmony_cistatic int 3257db96d56Sopenharmony_ci_is_unpacked_typevartuple(PyObject *arg) 3267db96d56Sopenharmony_ci{ 3277db96d56Sopenharmony_ci PyObject *tmp; 3287db96d56Sopenharmony_ci if (PyType_Check(arg)) { // TODO: Add test 3297db96d56Sopenharmony_ci return 0; 3307db96d56Sopenharmony_ci } 3317db96d56Sopenharmony_ci int res = _PyObject_LookupAttr(arg, &_Py_ID(__typing_is_unpacked_typevartuple__), &tmp); 3327db96d56Sopenharmony_ci if (res > 0) { 3337db96d56Sopenharmony_ci res = PyObject_IsTrue(tmp); 3347db96d56Sopenharmony_ci Py_DECREF(tmp); 3357db96d56Sopenharmony_ci } 3367db96d56Sopenharmony_ci return res; 3377db96d56Sopenharmony_ci} 3387db96d56Sopenharmony_ci 3397db96d56Sopenharmony_cistatic PyObject * 3407db96d56Sopenharmony_ci_unpacked_tuple_args(PyObject *arg) 3417db96d56Sopenharmony_ci{ 3427db96d56Sopenharmony_ci PyObject *result; 3437db96d56Sopenharmony_ci assert(!PyType_Check(arg)); 3447db96d56Sopenharmony_ci // Fast path 3457db96d56Sopenharmony_ci if (_PyGenericAlias_Check(arg) && 3467db96d56Sopenharmony_ci ((gaobject *)arg)->starred && 3477db96d56Sopenharmony_ci ((gaobject *)arg)->origin == (PyObject *)&PyTuple_Type) 3487db96d56Sopenharmony_ci { 3497db96d56Sopenharmony_ci result = ((gaobject *)arg)->args; 3507db96d56Sopenharmony_ci Py_INCREF(result); 3517db96d56Sopenharmony_ci return result; 3527db96d56Sopenharmony_ci } 3537db96d56Sopenharmony_ci 3547db96d56Sopenharmony_ci if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_unpacked_tuple_args__), &result) > 0) { 3557db96d56Sopenharmony_ci if (result == Py_None) { 3567db96d56Sopenharmony_ci Py_DECREF(result); 3577db96d56Sopenharmony_ci return NULL; 3587db96d56Sopenharmony_ci } 3597db96d56Sopenharmony_ci return result; 3607db96d56Sopenharmony_ci } 3617db96d56Sopenharmony_ci return NULL; 3627db96d56Sopenharmony_ci} 3637db96d56Sopenharmony_ci 3647db96d56Sopenharmony_cistatic PyObject * 3657db96d56Sopenharmony_ci_unpack_args(PyObject *item) 3667db96d56Sopenharmony_ci{ 3677db96d56Sopenharmony_ci PyObject *newargs = PyList_New(0); 3687db96d56Sopenharmony_ci if (newargs == NULL) { 3697db96d56Sopenharmony_ci return NULL; 3707db96d56Sopenharmony_ci } 3717db96d56Sopenharmony_ci int is_tuple = PyTuple_Check(item); 3727db96d56Sopenharmony_ci Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1; 3737db96d56Sopenharmony_ci PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item; 3747db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < nitems; i++) { 3757db96d56Sopenharmony_ci item = argitems[i]; 3767db96d56Sopenharmony_ci if (!PyType_Check(item)) { 3777db96d56Sopenharmony_ci PyObject *subargs = _unpacked_tuple_args(item); 3787db96d56Sopenharmony_ci if (subargs != NULL && 3797db96d56Sopenharmony_ci PyTuple_Check(subargs) && 3807db96d56Sopenharmony_ci !(PyTuple_GET_SIZE(subargs) && 3817db96d56Sopenharmony_ci PyTuple_GET_ITEM(subargs, PyTuple_GET_SIZE(subargs)-1) == Py_Ellipsis)) 3827db96d56Sopenharmony_ci { 3837db96d56Sopenharmony_ci if (PyList_SetSlice(newargs, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, subargs) < 0) { 3847db96d56Sopenharmony_ci Py_DECREF(subargs); 3857db96d56Sopenharmony_ci Py_DECREF(newargs); 3867db96d56Sopenharmony_ci return NULL; 3877db96d56Sopenharmony_ci } 3887db96d56Sopenharmony_ci Py_DECREF(subargs); 3897db96d56Sopenharmony_ci continue; 3907db96d56Sopenharmony_ci } 3917db96d56Sopenharmony_ci Py_XDECREF(subargs); 3927db96d56Sopenharmony_ci if (PyErr_Occurred()) { 3937db96d56Sopenharmony_ci Py_DECREF(newargs); 3947db96d56Sopenharmony_ci return NULL; 3957db96d56Sopenharmony_ci } 3967db96d56Sopenharmony_ci } 3977db96d56Sopenharmony_ci if (PyList_Append(newargs, item) < 0) { 3987db96d56Sopenharmony_ci Py_DECREF(newargs); 3997db96d56Sopenharmony_ci return NULL; 4007db96d56Sopenharmony_ci } 4017db96d56Sopenharmony_ci } 4027db96d56Sopenharmony_ci Py_SETREF(newargs, PySequence_Tuple(newargs)); 4037db96d56Sopenharmony_ci return newargs; 4047db96d56Sopenharmony_ci} 4057db96d56Sopenharmony_ci 4067db96d56Sopenharmony_ciPyObject * 4077db96d56Sopenharmony_ci_Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObject *item) 4087db96d56Sopenharmony_ci{ 4097db96d56Sopenharmony_ci Py_ssize_t nparams = PyTuple_GET_SIZE(parameters); 4107db96d56Sopenharmony_ci if (nparams == 0) { 4117db96d56Sopenharmony_ci return PyErr_Format(PyExc_TypeError, 4127db96d56Sopenharmony_ci "%R is not a generic class", 4137db96d56Sopenharmony_ci self); 4147db96d56Sopenharmony_ci } 4157db96d56Sopenharmony_ci item = _unpack_args(item); 4167db96d56Sopenharmony_ci for (Py_ssize_t i = 0; i < nparams; i++) { 4177db96d56Sopenharmony_ci PyObject *param = PyTuple_GET_ITEM(parameters, i); 4187db96d56Sopenharmony_ci PyObject *prepare, *tmp; 4197db96d56Sopenharmony_ci if (_PyObject_LookupAttr(param, &_Py_ID(__typing_prepare_subst__), &prepare) < 0) { 4207db96d56Sopenharmony_ci Py_DECREF(item); 4217db96d56Sopenharmony_ci return NULL; 4227db96d56Sopenharmony_ci } 4237db96d56Sopenharmony_ci if (prepare && prepare != Py_None) { 4247db96d56Sopenharmony_ci if (PyTuple_Check(item)) { 4257db96d56Sopenharmony_ci tmp = PyObject_CallFunction(prepare, "OO", self, item); 4267db96d56Sopenharmony_ci } 4277db96d56Sopenharmony_ci else { 4287db96d56Sopenharmony_ci tmp = PyObject_CallFunction(prepare, "O(O)", self, item); 4297db96d56Sopenharmony_ci } 4307db96d56Sopenharmony_ci Py_DECREF(prepare); 4317db96d56Sopenharmony_ci Py_SETREF(item, tmp); 4327db96d56Sopenharmony_ci if (item == NULL) { 4337db96d56Sopenharmony_ci return NULL; 4347db96d56Sopenharmony_ci } 4357db96d56Sopenharmony_ci } 4367db96d56Sopenharmony_ci } 4377db96d56Sopenharmony_ci int is_tuple = PyTuple_Check(item); 4387db96d56Sopenharmony_ci Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1; 4397db96d56Sopenharmony_ci PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item; 4407db96d56Sopenharmony_ci if (nitems != nparams) { 4417db96d56Sopenharmony_ci Py_DECREF(item); 4427db96d56Sopenharmony_ci return PyErr_Format(PyExc_TypeError, 4437db96d56Sopenharmony_ci "Too %s arguments for %R; actual %zd, expected %zd", 4447db96d56Sopenharmony_ci nitems > nparams ? "many" : "few", 4457db96d56Sopenharmony_ci self, nitems, nparams); 4467db96d56Sopenharmony_ci } 4477db96d56Sopenharmony_ci /* Replace all type variables (specified by parameters) 4487db96d56Sopenharmony_ci with corresponding values specified by argitems. 4497db96d56Sopenharmony_ci t = list[T]; t[int] -> newargs = [int] 4507db96d56Sopenharmony_ci t = dict[str, T]; t[int] -> newargs = [str, int] 4517db96d56Sopenharmony_ci t = dict[T, list[S]]; t[str, int] -> newargs = [str, list[int]] 4527db96d56Sopenharmony_ci */ 4537db96d56Sopenharmony_ci Py_ssize_t nargs = PyTuple_GET_SIZE(args); 4547db96d56Sopenharmony_ci PyObject *newargs = PyTuple_New(nargs); 4557db96d56Sopenharmony_ci if (newargs == NULL) { 4567db96d56Sopenharmony_ci Py_DECREF(item); 4577db96d56Sopenharmony_ci return NULL; 4587db96d56Sopenharmony_ci } 4597db96d56Sopenharmony_ci for (Py_ssize_t iarg = 0, jarg = 0; iarg < nargs; iarg++) { 4607db96d56Sopenharmony_ci PyObject *arg = PyTuple_GET_ITEM(args, iarg); 4617db96d56Sopenharmony_ci if (PyType_Check(arg)) { 4627db96d56Sopenharmony_ci Py_INCREF(arg); 4637db96d56Sopenharmony_ci PyTuple_SET_ITEM(newargs, jarg, arg); 4647db96d56Sopenharmony_ci jarg++; 4657db96d56Sopenharmony_ci continue; 4667db96d56Sopenharmony_ci } 4677db96d56Sopenharmony_ci 4687db96d56Sopenharmony_ci int unpack = _is_unpacked_typevartuple(arg); 4697db96d56Sopenharmony_ci if (unpack < 0) { 4707db96d56Sopenharmony_ci Py_DECREF(newargs); 4717db96d56Sopenharmony_ci Py_DECREF(item); 4727db96d56Sopenharmony_ci return NULL; 4737db96d56Sopenharmony_ci } 4747db96d56Sopenharmony_ci PyObject *subst; 4757db96d56Sopenharmony_ci if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_subst__), &subst) < 0) { 4767db96d56Sopenharmony_ci Py_DECREF(newargs); 4777db96d56Sopenharmony_ci Py_DECREF(item); 4787db96d56Sopenharmony_ci return NULL; 4797db96d56Sopenharmony_ci } 4807db96d56Sopenharmony_ci if (subst) { 4817db96d56Sopenharmony_ci Py_ssize_t iparam = tuple_index(parameters, nparams, arg); 4827db96d56Sopenharmony_ci assert(iparam >= 0); 4837db96d56Sopenharmony_ci arg = PyObject_CallOneArg(subst, argitems[iparam]); 4847db96d56Sopenharmony_ci Py_DECREF(subst); 4857db96d56Sopenharmony_ci } 4867db96d56Sopenharmony_ci else { 4877db96d56Sopenharmony_ci arg = subs_tvars(arg, parameters, argitems, nitems); 4887db96d56Sopenharmony_ci } 4897db96d56Sopenharmony_ci if (arg == NULL) { 4907db96d56Sopenharmony_ci Py_DECREF(newargs); 4917db96d56Sopenharmony_ci Py_DECREF(item); 4927db96d56Sopenharmony_ci return NULL; 4937db96d56Sopenharmony_ci } 4947db96d56Sopenharmony_ci if (unpack) { 4957db96d56Sopenharmony_ci jarg = tuple_extend(&newargs, jarg, 4967db96d56Sopenharmony_ci &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg)); 4977db96d56Sopenharmony_ci Py_DECREF(arg); 4987db96d56Sopenharmony_ci if (jarg < 0) { 4997db96d56Sopenharmony_ci Py_DECREF(item); 5007db96d56Sopenharmony_ci return NULL; 5017db96d56Sopenharmony_ci } 5027db96d56Sopenharmony_ci } 5037db96d56Sopenharmony_ci else { 5047db96d56Sopenharmony_ci PyTuple_SET_ITEM(newargs, jarg, arg); 5057db96d56Sopenharmony_ci jarg++; 5067db96d56Sopenharmony_ci } 5077db96d56Sopenharmony_ci } 5087db96d56Sopenharmony_ci 5097db96d56Sopenharmony_ci Py_DECREF(item); 5107db96d56Sopenharmony_ci return newargs; 5117db96d56Sopenharmony_ci} 5127db96d56Sopenharmony_ci 5137db96d56Sopenharmony_ciPyDoc_STRVAR(genericalias__doc__, 5147db96d56Sopenharmony_ci"Represent a PEP 585 generic type\n" 5157db96d56Sopenharmony_ci"\n" 5167db96d56Sopenharmony_ci"E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,)."); 5177db96d56Sopenharmony_ci 5187db96d56Sopenharmony_cistatic PyObject * 5197db96d56Sopenharmony_ciga_getitem(PyObject *self, PyObject *item) 5207db96d56Sopenharmony_ci{ 5217db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 5227db96d56Sopenharmony_ci // Populate __parameters__ if needed. 5237db96d56Sopenharmony_ci if (alias->parameters == NULL) { 5247db96d56Sopenharmony_ci alias->parameters = _Py_make_parameters(alias->args); 5257db96d56Sopenharmony_ci if (alias->parameters == NULL) { 5267db96d56Sopenharmony_ci return NULL; 5277db96d56Sopenharmony_ci } 5287db96d56Sopenharmony_ci } 5297db96d56Sopenharmony_ci 5307db96d56Sopenharmony_ci PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item); 5317db96d56Sopenharmony_ci if (newargs == NULL) { 5327db96d56Sopenharmony_ci return NULL; 5337db96d56Sopenharmony_ci } 5347db96d56Sopenharmony_ci 5357db96d56Sopenharmony_ci PyObject *res = Py_GenericAlias(alias->origin, newargs); 5367db96d56Sopenharmony_ci ((gaobject *)res)->starred = alias->starred; 5377db96d56Sopenharmony_ci 5387db96d56Sopenharmony_ci Py_DECREF(newargs); 5397db96d56Sopenharmony_ci return res; 5407db96d56Sopenharmony_ci} 5417db96d56Sopenharmony_ci 5427db96d56Sopenharmony_cistatic PyMappingMethods ga_as_mapping = { 5437db96d56Sopenharmony_ci .mp_subscript = ga_getitem, 5447db96d56Sopenharmony_ci}; 5457db96d56Sopenharmony_ci 5467db96d56Sopenharmony_cistatic Py_hash_t 5477db96d56Sopenharmony_ciga_hash(PyObject *self) 5487db96d56Sopenharmony_ci{ 5497db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 5507db96d56Sopenharmony_ci // TODO: Hash in the hash for the origin 5517db96d56Sopenharmony_ci Py_hash_t h0 = PyObject_Hash(alias->origin); 5527db96d56Sopenharmony_ci if (h0 == -1) { 5537db96d56Sopenharmony_ci return -1; 5547db96d56Sopenharmony_ci } 5557db96d56Sopenharmony_ci Py_hash_t h1 = PyObject_Hash(alias->args); 5567db96d56Sopenharmony_ci if (h1 == -1) { 5577db96d56Sopenharmony_ci return -1; 5587db96d56Sopenharmony_ci } 5597db96d56Sopenharmony_ci return h0 ^ h1; 5607db96d56Sopenharmony_ci} 5617db96d56Sopenharmony_ci 5627db96d56Sopenharmony_cistatic inline PyObject * 5637db96d56Sopenharmony_ciset_orig_class(PyObject *obj, PyObject *self) 5647db96d56Sopenharmony_ci{ 5657db96d56Sopenharmony_ci if (obj != NULL) { 5667db96d56Sopenharmony_ci if (PyObject_SetAttr(obj, &_Py_ID(__orig_class__), self) < 0) { 5677db96d56Sopenharmony_ci if (!PyErr_ExceptionMatches(PyExc_AttributeError) && 5687db96d56Sopenharmony_ci !PyErr_ExceptionMatches(PyExc_TypeError)) 5697db96d56Sopenharmony_ci { 5707db96d56Sopenharmony_ci Py_DECREF(obj); 5717db96d56Sopenharmony_ci return NULL; 5727db96d56Sopenharmony_ci } 5737db96d56Sopenharmony_ci PyErr_Clear(); 5747db96d56Sopenharmony_ci } 5757db96d56Sopenharmony_ci } 5767db96d56Sopenharmony_ci return obj; 5777db96d56Sopenharmony_ci} 5787db96d56Sopenharmony_ci 5797db96d56Sopenharmony_cistatic PyObject * 5807db96d56Sopenharmony_ciga_call(PyObject *self, PyObject *args, PyObject *kwds) 5817db96d56Sopenharmony_ci{ 5827db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 5837db96d56Sopenharmony_ci PyObject *obj = PyObject_Call(alias->origin, args, kwds); 5847db96d56Sopenharmony_ci return set_orig_class(obj, self); 5857db96d56Sopenharmony_ci} 5867db96d56Sopenharmony_ci 5877db96d56Sopenharmony_cistatic PyObject * 5887db96d56Sopenharmony_ciga_vectorcall(PyObject *self, PyObject *const *args, 5897db96d56Sopenharmony_ci size_t nargsf, PyObject *kwnames) 5907db96d56Sopenharmony_ci{ 5917db96d56Sopenharmony_ci gaobject *alias = (gaobject *) self; 5927db96d56Sopenharmony_ci PyObject *obj = PyVectorcall_Function(alias->origin)(alias->origin, args, nargsf, kwnames); 5937db96d56Sopenharmony_ci return set_orig_class(obj, self); 5947db96d56Sopenharmony_ci} 5957db96d56Sopenharmony_ci 5967db96d56Sopenharmony_cistatic const char* const attr_exceptions[] = { 5977db96d56Sopenharmony_ci "__class__", 5987db96d56Sopenharmony_ci "__origin__", 5997db96d56Sopenharmony_ci "__args__", 6007db96d56Sopenharmony_ci "__unpacked__", 6017db96d56Sopenharmony_ci "__parameters__", 6027db96d56Sopenharmony_ci "__typing_unpacked_tuple_args__", 6037db96d56Sopenharmony_ci "__mro_entries__", 6047db96d56Sopenharmony_ci "__reduce_ex__", // needed so we don't look up object.__reduce_ex__ 6057db96d56Sopenharmony_ci "__reduce__", 6067db96d56Sopenharmony_ci "__copy__", 6077db96d56Sopenharmony_ci "__deepcopy__", 6087db96d56Sopenharmony_ci NULL, 6097db96d56Sopenharmony_ci}; 6107db96d56Sopenharmony_ci 6117db96d56Sopenharmony_cistatic PyObject * 6127db96d56Sopenharmony_ciga_getattro(PyObject *self, PyObject *name) 6137db96d56Sopenharmony_ci{ 6147db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 6157db96d56Sopenharmony_ci if (PyUnicode_Check(name)) { 6167db96d56Sopenharmony_ci for (const char * const *p = attr_exceptions; ; p++) { 6177db96d56Sopenharmony_ci if (*p == NULL) { 6187db96d56Sopenharmony_ci return PyObject_GetAttr(alias->origin, name); 6197db96d56Sopenharmony_ci } 6207db96d56Sopenharmony_ci if (_PyUnicode_EqualToASCIIString(name, *p)) { 6217db96d56Sopenharmony_ci break; 6227db96d56Sopenharmony_ci } 6237db96d56Sopenharmony_ci } 6247db96d56Sopenharmony_ci } 6257db96d56Sopenharmony_ci return PyObject_GenericGetAttr(self, name); 6267db96d56Sopenharmony_ci} 6277db96d56Sopenharmony_ci 6287db96d56Sopenharmony_cistatic PyObject * 6297db96d56Sopenharmony_ciga_richcompare(PyObject *a, PyObject *b, int op) 6307db96d56Sopenharmony_ci{ 6317db96d56Sopenharmony_ci if (!_PyGenericAlias_Check(b) || 6327db96d56Sopenharmony_ci (op != Py_EQ && op != Py_NE)) 6337db96d56Sopenharmony_ci { 6347db96d56Sopenharmony_ci Py_RETURN_NOTIMPLEMENTED; 6357db96d56Sopenharmony_ci } 6367db96d56Sopenharmony_ci 6377db96d56Sopenharmony_ci if (op == Py_NE) { 6387db96d56Sopenharmony_ci PyObject *eq = ga_richcompare(a, b, Py_EQ); 6397db96d56Sopenharmony_ci if (eq == NULL) 6407db96d56Sopenharmony_ci return NULL; 6417db96d56Sopenharmony_ci Py_DECREF(eq); 6427db96d56Sopenharmony_ci if (eq == Py_True) { 6437db96d56Sopenharmony_ci Py_RETURN_FALSE; 6447db96d56Sopenharmony_ci } 6457db96d56Sopenharmony_ci else { 6467db96d56Sopenharmony_ci Py_RETURN_TRUE; 6477db96d56Sopenharmony_ci } 6487db96d56Sopenharmony_ci } 6497db96d56Sopenharmony_ci 6507db96d56Sopenharmony_ci gaobject *aa = (gaobject *)a; 6517db96d56Sopenharmony_ci gaobject *bb = (gaobject *)b; 6527db96d56Sopenharmony_ci if (aa->starred != bb->starred) { 6537db96d56Sopenharmony_ci Py_RETURN_FALSE; 6547db96d56Sopenharmony_ci } 6557db96d56Sopenharmony_ci int eq = PyObject_RichCompareBool(aa->origin, bb->origin, Py_EQ); 6567db96d56Sopenharmony_ci if (eq < 0) { 6577db96d56Sopenharmony_ci return NULL; 6587db96d56Sopenharmony_ci } 6597db96d56Sopenharmony_ci if (!eq) { 6607db96d56Sopenharmony_ci Py_RETURN_FALSE; 6617db96d56Sopenharmony_ci } 6627db96d56Sopenharmony_ci return PyObject_RichCompare(aa->args, bb->args, Py_EQ); 6637db96d56Sopenharmony_ci} 6647db96d56Sopenharmony_ci 6657db96d56Sopenharmony_cistatic PyObject * 6667db96d56Sopenharmony_ciga_mro_entries(PyObject *self, PyObject *args) 6677db96d56Sopenharmony_ci{ 6687db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 6697db96d56Sopenharmony_ci return PyTuple_Pack(1, alias->origin); 6707db96d56Sopenharmony_ci} 6717db96d56Sopenharmony_ci 6727db96d56Sopenharmony_cistatic PyObject * 6737db96d56Sopenharmony_ciga_instancecheck(PyObject *self, PyObject *Py_UNUSED(ignored)) 6747db96d56Sopenharmony_ci{ 6757db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 6767db96d56Sopenharmony_ci "isinstance() argument 2 cannot be a parameterized generic"); 6777db96d56Sopenharmony_ci return NULL; 6787db96d56Sopenharmony_ci} 6797db96d56Sopenharmony_ci 6807db96d56Sopenharmony_cistatic PyObject * 6817db96d56Sopenharmony_ciga_subclasscheck(PyObject *self, PyObject *Py_UNUSED(ignored)) 6827db96d56Sopenharmony_ci{ 6837db96d56Sopenharmony_ci PyErr_SetString(PyExc_TypeError, 6847db96d56Sopenharmony_ci "issubclass() argument 2 cannot be a parameterized generic"); 6857db96d56Sopenharmony_ci return NULL; 6867db96d56Sopenharmony_ci} 6877db96d56Sopenharmony_ci 6887db96d56Sopenharmony_cistatic PyObject * 6897db96d56Sopenharmony_ciga_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) 6907db96d56Sopenharmony_ci{ 6917db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 6927db96d56Sopenharmony_ci if (alias->starred) { 6937db96d56Sopenharmony_ci PyObject *tmp = Py_GenericAlias(alias->origin, alias->args); 6947db96d56Sopenharmony_ci if (tmp != NULL) { 6957db96d56Sopenharmony_ci Py_SETREF(tmp, PyObject_GetIter(tmp)); 6967db96d56Sopenharmony_ci } 6977db96d56Sopenharmony_ci if (tmp == NULL) { 6987db96d56Sopenharmony_ci return NULL; 6997db96d56Sopenharmony_ci } 7007db96d56Sopenharmony_ci return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(next)), tmp); 7017db96d56Sopenharmony_ci } 7027db96d56Sopenharmony_ci return Py_BuildValue("O(OO)", Py_TYPE(alias), 7037db96d56Sopenharmony_ci alias->origin, alias->args); 7047db96d56Sopenharmony_ci} 7057db96d56Sopenharmony_ci 7067db96d56Sopenharmony_cistatic PyObject * 7077db96d56Sopenharmony_ciga_dir(PyObject *self, PyObject *Py_UNUSED(ignored)) 7087db96d56Sopenharmony_ci{ 7097db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 7107db96d56Sopenharmony_ci PyObject *dir = PyObject_Dir(alias->origin); 7117db96d56Sopenharmony_ci if (dir == NULL) { 7127db96d56Sopenharmony_ci return NULL; 7137db96d56Sopenharmony_ci } 7147db96d56Sopenharmony_ci 7157db96d56Sopenharmony_ci PyObject *dir_entry = NULL; 7167db96d56Sopenharmony_ci for (const char * const *p = attr_exceptions; ; p++) { 7177db96d56Sopenharmony_ci if (*p == NULL) { 7187db96d56Sopenharmony_ci break; 7197db96d56Sopenharmony_ci } 7207db96d56Sopenharmony_ci else { 7217db96d56Sopenharmony_ci dir_entry = PyUnicode_FromString(*p); 7227db96d56Sopenharmony_ci if (dir_entry == NULL) { 7237db96d56Sopenharmony_ci goto error; 7247db96d56Sopenharmony_ci } 7257db96d56Sopenharmony_ci int contains = PySequence_Contains(dir, dir_entry); 7267db96d56Sopenharmony_ci if (contains < 0) { 7277db96d56Sopenharmony_ci goto error; 7287db96d56Sopenharmony_ci } 7297db96d56Sopenharmony_ci if (contains == 0 && PyList_Append(dir, dir_entry) < 0) { 7307db96d56Sopenharmony_ci goto error; 7317db96d56Sopenharmony_ci } 7327db96d56Sopenharmony_ci 7337db96d56Sopenharmony_ci Py_CLEAR(dir_entry); 7347db96d56Sopenharmony_ci } 7357db96d56Sopenharmony_ci } 7367db96d56Sopenharmony_ci return dir; 7377db96d56Sopenharmony_ci 7387db96d56Sopenharmony_cierror: 7397db96d56Sopenharmony_ci Py_DECREF(dir); 7407db96d56Sopenharmony_ci Py_XDECREF(dir_entry); 7417db96d56Sopenharmony_ci return NULL; 7427db96d56Sopenharmony_ci} 7437db96d56Sopenharmony_ci 7447db96d56Sopenharmony_cistatic PyMethodDef ga_methods[] = { 7457db96d56Sopenharmony_ci {"__mro_entries__", ga_mro_entries, METH_O}, 7467db96d56Sopenharmony_ci {"__instancecheck__", ga_instancecheck, METH_O}, 7477db96d56Sopenharmony_ci {"__subclasscheck__", ga_subclasscheck, METH_O}, 7487db96d56Sopenharmony_ci {"__reduce__", ga_reduce, METH_NOARGS}, 7497db96d56Sopenharmony_ci {"__dir__", ga_dir, METH_NOARGS}, 7507db96d56Sopenharmony_ci {0} 7517db96d56Sopenharmony_ci}; 7527db96d56Sopenharmony_ci 7537db96d56Sopenharmony_cistatic PyMemberDef ga_members[] = { 7547db96d56Sopenharmony_ci {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY}, 7557db96d56Sopenharmony_ci {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY}, 7567db96d56Sopenharmony_ci {"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY}, 7577db96d56Sopenharmony_ci {0} 7587db96d56Sopenharmony_ci}; 7597db96d56Sopenharmony_ci 7607db96d56Sopenharmony_cistatic PyObject * 7617db96d56Sopenharmony_ciga_parameters(PyObject *self, void *unused) 7627db96d56Sopenharmony_ci{ 7637db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 7647db96d56Sopenharmony_ci if (alias->parameters == NULL) { 7657db96d56Sopenharmony_ci alias->parameters = _Py_make_parameters(alias->args); 7667db96d56Sopenharmony_ci if (alias->parameters == NULL) { 7677db96d56Sopenharmony_ci return NULL; 7687db96d56Sopenharmony_ci } 7697db96d56Sopenharmony_ci } 7707db96d56Sopenharmony_ci Py_INCREF(alias->parameters); 7717db96d56Sopenharmony_ci return alias->parameters; 7727db96d56Sopenharmony_ci} 7737db96d56Sopenharmony_ci 7747db96d56Sopenharmony_cistatic PyObject * 7757db96d56Sopenharmony_ciga_unpacked_tuple_args(PyObject *self, void *unused) 7767db96d56Sopenharmony_ci{ 7777db96d56Sopenharmony_ci gaobject *alias = (gaobject *)self; 7787db96d56Sopenharmony_ci if (alias->starred && alias->origin == (PyObject *)&PyTuple_Type) { 7797db96d56Sopenharmony_ci Py_INCREF(alias->args); 7807db96d56Sopenharmony_ci return alias->args; 7817db96d56Sopenharmony_ci } 7827db96d56Sopenharmony_ci Py_RETURN_NONE; 7837db96d56Sopenharmony_ci} 7847db96d56Sopenharmony_ci 7857db96d56Sopenharmony_cistatic PyGetSetDef ga_properties[] = { 7867db96d56Sopenharmony_ci {"__parameters__", ga_parameters, (setter)NULL, "Type variables in the GenericAlias.", NULL}, 7877db96d56Sopenharmony_ci {"__typing_unpacked_tuple_args__", ga_unpacked_tuple_args, (setter)NULL, NULL}, 7887db96d56Sopenharmony_ci {0} 7897db96d56Sopenharmony_ci}; 7907db96d56Sopenharmony_ci 7917db96d56Sopenharmony_ci/* A helper function to create GenericAlias' args tuple and set its attributes. 7927db96d56Sopenharmony_ci * Returns 1 on success, 0 on failure. 7937db96d56Sopenharmony_ci */ 7947db96d56Sopenharmony_cistatic inline int 7957db96d56Sopenharmony_cisetup_ga(gaobject *alias, PyObject *origin, PyObject *args) { 7967db96d56Sopenharmony_ci if (!PyTuple_Check(args)) { 7977db96d56Sopenharmony_ci args = PyTuple_Pack(1, args); 7987db96d56Sopenharmony_ci if (args == NULL) { 7997db96d56Sopenharmony_ci return 0; 8007db96d56Sopenharmony_ci } 8017db96d56Sopenharmony_ci } 8027db96d56Sopenharmony_ci else { 8037db96d56Sopenharmony_ci Py_INCREF(args); 8047db96d56Sopenharmony_ci } 8057db96d56Sopenharmony_ci 8067db96d56Sopenharmony_ci Py_INCREF(origin); 8077db96d56Sopenharmony_ci alias->origin = origin; 8087db96d56Sopenharmony_ci alias->args = args; 8097db96d56Sopenharmony_ci alias->parameters = NULL; 8107db96d56Sopenharmony_ci alias->weakreflist = NULL; 8117db96d56Sopenharmony_ci 8127db96d56Sopenharmony_ci if (PyVectorcall_Function(origin) != NULL) { 8137db96d56Sopenharmony_ci alias->vectorcall = ga_vectorcall; 8147db96d56Sopenharmony_ci } 8157db96d56Sopenharmony_ci else { 8167db96d56Sopenharmony_ci alias->vectorcall = NULL; 8177db96d56Sopenharmony_ci } 8187db96d56Sopenharmony_ci 8197db96d56Sopenharmony_ci return 1; 8207db96d56Sopenharmony_ci} 8217db96d56Sopenharmony_ci 8227db96d56Sopenharmony_cistatic PyObject * 8237db96d56Sopenharmony_ciga_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 8247db96d56Sopenharmony_ci{ 8257db96d56Sopenharmony_ci if (!_PyArg_NoKeywords("GenericAlias", kwds)) { 8267db96d56Sopenharmony_ci return NULL; 8277db96d56Sopenharmony_ci } 8287db96d56Sopenharmony_ci if (!_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 2)) { 8297db96d56Sopenharmony_ci return NULL; 8307db96d56Sopenharmony_ci } 8317db96d56Sopenharmony_ci PyObject *origin = PyTuple_GET_ITEM(args, 0); 8327db96d56Sopenharmony_ci PyObject *arguments = PyTuple_GET_ITEM(args, 1); 8337db96d56Sopenharmony_ci gaobject *self = (gaobject *)type->tp_alloc(type, 0); 8347db96d56Sopenharmony_ci if (self == NULL) { 8357db96d56Sopenharmony_ci return NULL; 8367db96d56Sopenharmony_ci } 8377db96d56Sopenharmony_ci if (!setup_ga(self, origin, arguments)) { 8387db96d56Sopenharmony_ci Py_DECREF(self); 8397db96d56Sopenharmony_ci return NULL; 8407db96d56Sopenharmony_ci } 8417db96d56Sopenharmony_ci return (PyObject *)self; 8427db96d56Sopenharmony_ci} 8437db96d56Sopenharmony_ci 8447db96d56Sopenharmony_cistatic PyNumberMethods ga_as_number = { 8457db96d56Sopenharmony_ci .nb_or = _Py_union_type_or, // Add __or__ function 8467db96d56Sopenharmony_ci}; 8477db96d56Sopenharmony_ci 8487db96d56Sopenharmony_cistatic PyObject * 8497db96d56Sopenharmony_ciga_iternext(gaiterobject *gi) { 8507db96d56Sopenharmony_ci if (gi->obj == NULL) { 8517db96d56Sopenharmony_ci PyErr_SetNone(PyExc_StopIteration); 8527db96d56Sopenharmony_ci return NULL; 8537db96d56Sopenharmony_ci } 8547db96d56Sopenharmony_ci gaobject *alias = (gaobject *)gi->obj; 8557db96d56Sopenharmony_ci PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args); 8567db96d56Sopenharmony_ci if (starred_alias == NULL) { 8577db96d56Sopenharmony_ci return NULL; 8587db96d56Sopenharmony_ci } 8597db96d56Sopenharmony_ci ((gaobject *)starred_alias)->starred = true; 8607db96d56Sopenharmony_ci Py_SETREF(gi->obj, NULL); 8617db96d56Sopenharmony_ci return starred_alias; 8627db96d56Sopenharmony_ci} 8637db96d56Sopenharmony_ci 8647db96d56Sopenharmony_cistatic void 8657db96d56Sopenharmony_ciga_iter_dealloc(gaiterobject *gi) { 8667db96d56Sopenharmony_ci PyObject_GC_UnTrack(gi); 8677db96d56Sopenharmony_ci Py_XDECREF(gi->obj); 8687db96d56Sopenharmony_ci PyObject_GC_Del(gi); 8697db96d56Sopenharmony_ci} 8707db96d56Sopenharmony_ci 8717db96d56Sopenharmony_cistatic int 8727db96d56Sopenharmony_ciga_iter_traverse(gaiterobject *gi, visitproc visit, void *arg) 8737db96d56Sopenharmony_ci{ 8747db96d56Sopenharmony_ci Py_VISIT(gi->obj); 8757db96d56Sopenharmony_ci return 0; 8767db96d56Sopenharmony_ci} 8777db96d56Sopenharmony_ci 8787db96d56Sopenharmony_cistatic int 8797db96d56Sopenharmony_ciga_iter_clear(PyObject *self) { 8807db96d56Sopenharmony_ci gaiterobject *gi = (gaiterobject *)self; 8817db96d56Sopenharmony_ci Py_CLEAR(gi->obj); 8827db96d56Sopenharmony_ci return 0; 8837db96d56Sopenharmony_ci} 8847db96d56Sopenharmony_ci 8857db96d56Sopenharmony_cistatic PyObject * 8867db96d56Sopenharmony_ciga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) 8877db96d56Sopenharmony_ci{ 8887db96d56Sopenharmony_ci PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter)); 8897db96d56Sopenharmony_ci gaiterobject *gi = (gaiterobject *)self; 8907db96d56Sopenharmony_ci 8917db96d56Sopenharmony_ci /* _PyEval_GetBuiltin can invoke arbitrary code, 8927db96d56Sopenharmony_ci * call must be before access of iterator pointers. 8937db96d56Sopenharmony_ci * see issue #101765 */ 8947db96d56Sopenharmony_ci 8957db96d56Sopenharmony_ci if (gi->obj) 8967db96d56Sopenharmony_ci return Py_BuildValue("N(O)", iter, gi->obj); 8977db96d56Sopenharmony_ci else 8987db96d56Sopenharmony_ci return Py_BuildValue("N(())", iter); 8997db96d56Sopenharmony_ci} 9007db96d56Sopenharmony_ci 9017db96d56Sopenharmony_cistatic PyMethodDef ga_iter_methods[] = { 9027db96d56Sopenharmony_ci {"__reduce__", ga_iter_reduce, METH_NOARGS}, 9037db96d56Sopenharmony_ci {0} 9047db96d56Sopenharmony_ci}; 9057db96d56Sopenharmony_ci 9067db96d56Sopenharmony_ci// gh-91632: _Py_GenericAliasIterType is exported to be cleared 9077db96d56Sopenharmony_ci// in _PyTypes_FiniTypes. 9087db96d56Sopenharmony_ciPyTypeObject _Py_GenericAliasIterType = { 9097db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 9107db96d56Sopenharmony_ci .tp_name = "generic_alias_iterator", 9117db96d56Sopenharmony_ci .tp_basicsize = sizeof(gaiterobject), 9127db96d56Sopenharmony_ci .tp_iter = PyObject_SelfIter, 9137db96d56Sopenharmony_ci .tp_iternext = (iternextfunc)ga_iternext, 9147db96d56Sopenharmony_ci .tp_traverse = (traverseproc)ga_iter_traverse, 9157db96d56Sopenharmony_ci .tp_methods = ga_iter_methods, 9167db96d56Sopenharmony_ci .tp_dealloc = (destructor)ga_iter_dealloc, 9177db96d56Sopenharmony_ci .tp_clear = (inquiry)ga_iter_clear, 9187db96d56Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, 9197db96d56Sopenharmony_ci}; 9207db96d56Sopenharmony_ci 9217db96d56Sopenharmony_cistatic PyObject * 9227db96d56Sopenharmony_ciga_iter(PyObject *self) { 9237db96d56Sopenharmony_ci gaiterobject *gi = PyObject_GC_New(gaiterobject, &_Py_GenericAliasIterType); 9247db96d56Sopenharmony_ci if (gi == NULL) { 9257db96d56Sopenharmony_ci return NULL; 9267db96d56Sopenharmony_ci } 9277db96d56Sopenharmony_ci gi->obj = Py_NewRef(self); 9287db96d56Sopenharmony_ci PyObject_GC_Track(gi); 9297db96d56Sopenharmony_ci return (PyObject *)gi; 9307db96d56Sopenharmony_ci} 9317db96d56Sopenharmony_ci 9327db96d56Sopenharmony_ci// TODO: 9337db96d56Sopenharmony_ci// - argument clinic? 9347db96d56Sopenharmony_ci// - cache? 9357db96d56Sopenharmony_ciPyTypeObject Py_GenericAliasType = { 9367db96d56Sopenharmony_ci PyVarObject_HEAD_INIT(&PyType_Type, 0) 9377db96d56Sopenharmony_ci .tp_name = "types.GenericAlias", 9387db96d56Sopenharmony_ci .tp_doc = genericalias__doc__, 9397db96d56Sopenharmony_ci .tp_basicsize = sizeof(gaobject), 9407db96d56Sopenharmony_ci .tp_dealloc = ga_dealloc, 9417db96d56Sopenharmony_ci .tp_repr = ga_repr, 9427db96d56Sopenharmony_ci .tp_as_number = &ga_as_number, // allow X | Y of GenericAlias objs 9437db96d56Sopenharmony_ci .tp_as_mapping = &ga_as_mapping, 9447db96d56Sopenharmony_ci .tp_hash = ga_hash, 9457db96d56Sopenharmony_ci .tp_call = ga_call, 9467db96d56Sopenharmony_ci .tp_getattro = ga_getattro, 9477db96d56Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL, 9487db96d56Sopenharmony_ci .tp_traverse = ga_traverse, 9497db96d56Sopenharmony_ci .tp_richcompare = ga_richcompare, 9507db96d56Sopenharmony_ci .tp_weaklistoffset = offsetof(gaobject, weakreflist), 9517db96d56Sopenharmony_ci .tp_methods = ga_methods, 9527db96d56Sopenharmony_ci .tp_members = ga_members, 9537db96d56Sopenharmony_ci .tp_alloc = PyType_GenericAlloc, 9547db96d56Sopenharmony_ci .tp_new = ga_new, 9557db96d56Sopenharmony_ci .tp_free = PyObject_GC_Del, 9567db96d56Sopenharmony_ci .tp_getset = ga_properties, 9577db96d56Sopenharmony_ci .tp_iter = (getiterfunc)ga_iter, 9587db96d56Sopenharmony_ci .tp_vectorcall_offset = offsetof(gaobject, vectorcall), 9597db96d56Sopenharmony_ci}; 9607db96d56Sopenharmony_ci 9617db96d56Sopenharmony_ciPyObject * 9627db96d56Sopenharmony_ciPy_GenericAlias(PyObject *origin, PyObject *args) 9637db96d56Sopenharmony_ci{ 9647db96d56Sopenharmony_ci gaobject *alias = (gaobject*) PyType_GenericAlloc( 9657db96d56Sopenharmony_ci (PyTypeObject *)&Py_GenericAliasType, 0); 9667db96d56Sopenharmony_ci if (alias == NULL) { 9677db96d56Sopenharmony_ci return NULL; 9687db96d56Sopenharmony_ci } 9697db96d56Sopenharmony_ci if (!setup_ga(alias, origin, args)) { 9707db96d56Sopenharmony_ci Py_DECREF(alias); 9717db96d56Sopenharmony_ci return NULL; 9727db96d56Sopenharmony_ci } 9737db96d56Sopenharmony_ci return (PyObject *)alias; 9747db96d56Sopenharmony_ci} 975