genericaliasobject.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  1. // types.GenericAlias -- used to represent e.g. list[int].
  2. #include "Python.h"
  3. #include "pycore_object.h"
  4. #include "pycore_unionobject.h" // _Py_union_type_or, _PyGenericAlias_Check
  5. #include "structmember.h" // PyMemberDef
  6. #include <stdbool.h>
  7. typedef struct {
  8. PyObject_HEAD
  9. PyObject *origin;
  10. PyObject *args;
  11. PyObject *parameters;
  12. PyObject *weakreflist;
  13. // Whether we're a starred type, e.g. *tuple[int].
  14. bool starred;
  15. vectorcallfunc vectorcall;
  16. } gaobject;
  17. typedef struct {
  18. PyObject_HEAD
  19. PyObject *obj; /* Set to NULL when iterator is exhausted */
  20. } gaiterobject;
  21. static void
  22. ga_dealloc(PyObject *self)
  23. {
  24. gaobject *alias = (gaobject *)self;
  25. _PyObject_GC_UNTRACK(self);
  26. if (alias->weakreflist != NULL) {
  27. PyObject_ClearWeakRefs((PyObject *)alias);
  28. }
  29. Py_XDECREF(alias->origin);
  30. Py_XDECREF(alias->args);
  31. Py_XDECREF(alias->parameters);
  32. Py_TYPE(self)->tp_free(self);
  33. }
  34. static int
  35. ga_traverse(PyObject *self, visitproc visit, void *arg)
  36. {
  37. gaobject *alias = (gaobject *)self;
  38. Py_VISIT(alias->origin);
  39. Py_VISIT(alias->args);
  40. Py_VISIT(alias->parameters);
  41. return 0;
  42. }
  43. static int
  44. ga_repr_item(_PyUnicodeWriter *writer, PyObject *p)
  45. {
  46. PyObject *qualname = NULL;
  47. PyObject *module = NULL;
  48. PyObject *r = NULL;
  49. PyObject *tmp;
  50. int err;
  51. if (p == Py_Ellipsis) {
  52. // The Ellipsis object
  53. r = PyUnicode_FromString("...");
  54. goto done;
  55. }
  56. if (_PyObject_LookupAttr(p, &_Py_ID(__origin__), &tmp) < 0) {
  57. goto done;
  58. }
  59. if (tmp != NULL) {
  60. Py_DECREF(tmp);
  61. if (_PyObject_LookupAttr(p, &_Py_ID(__args__), &tmp) < 0) {
  62. goto done;
  63. }
  64. if (tmp != NULL) {
  65. Py_DECREF(tmp);
  66. // It looks like a GenericAlias
  67. goto use_repr;
  68. }
  69. }
  70. if (_PyObject_LookupAttr(p, &_Py_ID(__qualname__), &qualname) < 0) {
  71. goto done;
  72. }
  73. if (qualname == NULL) {
  74. goto use_repr;
  75. }
  76. if (_PyObject_LookupAttr(p, &_Py_ID(__module__), &module) < 0) {
  77. goto done;
  78. }
  79. if (module == NULL || module == Py_None) {
  80. goto use_repr;
  81. }
  82. // Looks like a class
  83. if (PyUnicode_Check(module) &&
  84. _PyUnicode_EqualToASCIIString(module, "builtins"))
  85. {
  86. // builtins don't need a module name
  87. r = PyObject_Str(qualname);
  88. goto done;
  89. }
  90. else {
  91. r = PyUnicode_FromFormat("%S.%S", module, qualname);
  92. goto done;
  93. }
  94. use_repr:
  95. r = PyObject_Repr(p);
  96. done:
  97. Py_XDECREF(qualname);
  98. Py_XDECREF(module);
  99. if (r == NULL) {
  100. // error if any of the above PyObject_Repr/PyUnicode_From* fail
  101. err = -1;
  102. }
  103. else {
  104. err = _PyUnicodeWriter_WriteStr(writer, r);
  105. Py_DECREF(r);
  106. }
  107. return err;
  108. }
  109. static int
  110. ga_repr_items_list(_PyUnicodeWriter *writer, PyObject *p)
  111. {
  112. assert(PyList_CheckExact(p));
  113. Py_ssize_t len = PyList_GET_SIZE(p);
  114. if (_PyUnicodeWriter_WriteASCIIString(writer, "[", 1) < 0) {
  115. return -1;
  116. }
  117. for (Py_ssize_t i = 0; i < len; i++) {
  118. if (i > 0) {
  119. if (_PyUnicodeWriter_WriteASCIIString(writer, ", ", 2) < 0) {
  120. return -1;
  121. }
  122. }
  123. PyObject *item = PyList_GET_ITEM(p, i);
  124. if (ga_repr_item(writer, item) < 0) {
  125. return -1;
  126. }
  127. }
  128. if (_PyUnicodeWriter_WriteASCIIString(writer, "]", 1) < 0) {
  129. return -1;
  130. }
  131. return 0;
  132. }
  133. static PyObject *
  134. ga_repr(PyObject *self)
  135. {
  136. gaobject *alias = (gaobject *)self;
  137. Py_ssize_t len = PyTuple_GET_SIZE(alias->args);
  138. _PyUnicodeWriter writer;
  139. _PyUnicodeWriter_Init(&writer);
  140. if (alias->starred) {
  141. if (_PyUnicodeWriter_WriteASCIIString(&writer, "*", 1) < 0) {
  142. goto error;
  143. }
  144. }
  145. if (ga_repr_item(&writer, alias->origin) < 0) {
  146. goto error;
  147. }
  148. if (_PyUnicodeWriter_WriteASCIIString(&writer, "[", 1) < 0) {
  149. goto error;
  150. }
  151. for (Py_ssize_t i = 0; i < len; i++) {
  152. if (i > 0) {
  153. if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0) {
  154. goto error;
  155. }
  156. }
  157. PyObject *p = PyTuple_GET_ITEM(alias->args, i);
  158. if (PyList_CheckExact(p)) {
  159. // Looks like we are working with ParamSpec's list of type args:
  160. if (ga_repr_items_list(&writer, p) < 0) {
  161. goto error;
  162. }
  163. }
  164. else if (ga_repr_item(&writer, p) < 0) {
  165. goto error;
  166. }
  167. }
  168. if (len == 0) {
  169. // for something like tuple[()] we should print a "()"
  170. if (_PyUnicodeWriter_WriteASCIIString(&writer, "()", 2) < 0) {
  171. goto error;
  172. }
  173. }
  174. if (_PyUnicodeWriter_WriteASCIIString(&writer, "]", 1) < 0) {
  175. goto error;
  176. }
  177. return _PyUnicodeWriter_Finish(&writer);
  178. error:
  179. _PyUnicodeWriter_Dealloc(&writer);
  180. return NULL;
  181. }
  182. // Index of item in self[:len], or -1 if not found (self is a tuple)
  183. static Py_ssize_t
  184. tuple_index(PyObject *self, Py_ssize_t len, PyObject *item)
  185. {
  186. for (Py_ssize_t i = 0; i < len; i++) {
  187. if (PyTuple_GET_ITEM(self, i) == item) {
  188. return i;
  189. }
  190. }
  191. return -1;
  192. }
  193. static int
  194. tuple_add(PyObject *self, Py_ssize_t len, PyObject *item)
  195. {
  196. if (tuple_index(self, len, item) < 0) {
  197. PyTuple_SET_ITEM(self, len, Py_NewRef(item));
  198. return 1;
  199. }
  200. return 0;
  201. }
  202. static Py_ssize_t
  203. tuple_extend(PyObject **dst, Py_ssize_t dstindex,
  204. PyObject **src, Py_ssize_t count)
  205. {
  206. assert(count >= 0);
  207. if (_PyTuple_Resize(dst, PyTuple_GET_SIZE(*dst) + count - 1) != 0) {
  208. return -1;
  209. }
  210. assert(dstindex + count <= PyTuple_GET_SIZE(*dst));
  211. for (Py_ssize_t i = 0; i < count; ++i) {
  212. PyObject *item = src[i];
  213. PyTuple_SET_ITEM(*dst, dstindex + i, Py_NewRef(item));
  214. }
  215. return dstindex + count;
  216. }
  217. PyObject *
  218. _Py_make_parameters(PyObject *args)
  219. {
  220. Py_ssize_t nargs = PyTuple_GET_SIZE(args);
  221. Py_ssize_t len = nargs;
  222. PyObject *parameters = PyTuple_New(len);
  223. if (parameters == NULL)
  224. return NULL;
  225. Py_ssize_t iparam = 0;
  226. for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) {
  227. PyObject *t = PyTuple_GET_ITEM(args, iarg);
  228. PyObject *subst;
  229. // We don't want __parameters__ descriptor of a bare Python class.
  230. if (PyType_Check(t)) {
  231. continue;
  232. }
  233. if (_PyObject_LookupAttr(t, &_Py_ID(__typing_subst__), &subst) < 0) {
  234. Py_DECREF(parameters);
  235. return NULL;
  236. }
  237. if (subst) {
  238. iparam += tuple_add(parameters, iparam, t);
  239. Py_DECREF(subst);
  240. }
  241. else {
  242. PyObject *subparams;
  243. if (_PyObject_LookupAttr(t, &_Py_ID(__parameters__),
  244. &subparams) < 0) {
  245. Py_DECREF(parameters);
  246. return NULL;
  247. }
  248. if (subparams && PyTuple_Check(subparams)) {
  249. Py_ssize_t len2 = PyTuple_GET_SIZE(subparams);
  250. Py_ssize_t needed = len2 - 1 - (iarg - iparam);
  251. if (needed > 0) {
  252. len += needed;
  253. if (_PyTuple_Resize(&parameters, len) < 0) {
  254. Py_DECREF(subparams);
  255. Py_DECREF(parameters);
  256. return NULL;
  257. }
  258. }
  259. for (Py_ssize_t j = 0; j < len2; j++) {
  260. PyObject *t2 = PyTuple_GET_ITEM(subparams, j);
  261. iparam += tuple_add(parameters, iparam, t2);
  262. }
  263. }
  264. Py_XDECREF(subparams);
  265. }
  266. }
  267. if (iparam < len) {
  268. if (_PyTuple_Resize(&parameters, iparam) < 0) {
  269. Py_XDECREF(parameters);
  270. return NULL;
  271. }
  272. }
  273. return parameters;
  274. }
  275. /* If obj is a generic alias, substitute type variables params
  276. with substitutions argitems. For example, if obj is list[T],
  277. params is (T, S), and argitems is (str, int), return list[str].
  278. If obj doesn't have a __parameters__ attribute or that's not
  279. a non-empty tuple, return a new reference to obj. */
  280. static PyObject *
  281. subs_tvars(PyObject *obj, PyObject *params,
  282. PyObject **argitems, Py_ssize_t nargs)
  283. {
  284. PyObject *subparams;
  285. if (_PyObject_LookupAttr(obj, &_Py_ID(__parameters__), &subparams) < 0) {
  286. return NULL;
  287. }
  288. if (subparams && PyTuple_Check(subparams) && PyTuple_GET_SIZE(subparams)) {
  289. Py_ssize_t nparams = PyTuple_GET_SIZE(params);
  290. Py_ssize_t nsubargs = PyTuple_GET_SIZE(subparams);
  291. PyObject *subargs = PyTuple_New(nsubargs);
  292. if (subargs == NULL) {
  293. Py_DECREF(subparams);
  294. return NULL;
  295. }
  296. Py_ssize_t j = 0;
  297. for (Py_ssize_t i = 0; i < nsubargs; ++i) {
  298. PyObject *arg = PyTuple_GET_ITEM(subparams, i);
  299. Py_ssize_t iparam = tuple_index(params, nparams, arg);
  300. if (iparam >= 0) {
  301. PyObject *param = PyTuple_GET_ITEM(params, iparam);
  302. arg = argitems[iparam];
  303. if (Py_TYPE(param)->tp_iter && PyTuple_Check(arg)) { // TypeVarTuple
  304. j = tuple_extend(&subargs, j,
  305. &PyTuple_GET_ITEM(arg, 0),
  306. PyTuple_GET_SIZE(arg));
  307. if (j < 0) {
  308. return NULL;
  309. }
  310. continue;
  311. }
  312. }
  313. PyTuple_SET_ITEM(subargs, j, Py_NewRef(arg));
  314. j++;
  315. }
  316. assert(j == PyTuple_GET_SIZE(subargs));
  317. obj = PyObject_GetItem(obj, subargs);
  318. Py_DECREF(subargs);
  319. }
  320. else {
  321. Py_INCREF(obj);
  322. }
  323. Py_XDECREF(subparams);
  324. return obj;
  325. }
  326. static int
  327. _is_unpacked_typevartuple(PyObject *arg)
  328. {
  329. PyObject *tmp;
  330. if (PyType_Check(arg)) { // TODO: Add test
  331. return 0;
  332. }
  333. int res = _PyObject_LookupAttr(arg, &_Py_ID(__typing_is_unpacked_typevartuple__), &tmp);
  334. if (res > 0) {
  335. res = PyObject_IsTrue(tmp);
  336. Py_DECREF(tmp);
  337. }
  338. return res;
  339. }
  340. static PyObject *
  341. _unpacked_tuple_args(PyObject *arg)
  342. {
  343. PyObject *result;
  344. assert(!PyType_Check(arg));
  345. // Fast path
  346. if (_PyGenericAlias_Check(arg) &&
  347. ((gaobject *)arg)->starred &&
  348. ((gaobject *)arg)->origin == (PyObject *)&PyTuple_Type)
  349. {
  350. result = ((gaobject *)arg)->args;
  351. return Py_NewRef(result);
  352. }
  353. if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_unpacked_tuple_args__), &result) > 0) {
  354. if (result == Py_None) {
  355. Py_DECREF(result);
  356. return NULL;
  357. }
  358. return result;
  359. }
  360. return NULL;
  361. }
  362. static PyObject *
  363. _unpack_args(PyObject *item)
  364. {
  365. PyObject *newargs = PyList_New(0);
  366. if (newargs == NULL) {
  367. return NULL;
  368. }
  369. int is_tuple = PyTuple_Check(item);
  370. Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1;
  371. PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item;
  372. for (Py_ssize_t i = 0; i < nitems; i++) {
  373. item = argitems[i];
  374. if (!PyType_Check(item)) {
  375. PyObject *subargs = _unpacked_tuple_args(item);
  376. if (subargs != NULL &&
  377. PyTuple_Check(subargs) &&
  378. !(PyTuple_GET_SIZE(subargs) &&
  379. PyTuple_GET_ITEM(subargs, PyTuple_GET_SIZE(subargs)-1) == Py_Ellipsis))
  380. {
  381. if (PyList_SetSlice(newargs, PY_SSIZE_T_MAX, PY_SSIZE_T_MAX, subargs) < 0) {
  382. Py_DECREF(subargs);
  383. Py_DECREF(newargs);
  384. return NULL;
  385. }
  386. Py_DECREF(subargs);
  387. continue;
  388. }
  389. Py_XDECREF(subargs);
  390. if (PyErr_Occurred()) {
  391. Py_DECREF(newargs);
  392. return NULL;
  393. }
  394. }
  395. if (PyList_Append(newargs, item) < 0) {
  396. Py_DECREF(newargs);
  397. return NULL;
  398. }
  399. }
  400. Py_SETREF(newargs, PySequence_Tuple(newargs));
  401. return newargs;
  402. }
  403. PyObject *
  404. _Py_subs_parameters(PyObject *self, PyObject *args, PyObject *parameters, PyObject *item)
  405. {
  406. Py_ssize_t nparams = PyTuple_GET_SIZE(parameters);
  407. if (nparams == 0) {
  408. return PyErr_Format(PyExc_TypeError,
  409. "%R is not a generic class",
  410. self);
  411. }
  412. item = _unpack_args(item);
  413. for (Py_ssize_t i = 0; i < nparams; i++) {
  414. PyObject *param = PyTuple_GET_ITEM(parameters, i);
  415. PyObject *prepare, *tmp;
  416. if (_PyObject_LookupAttr(param, &_Py_ID(__typing_prepare_subst__), &prepare) < 0) {
  417. Py_DECREF(item);
  418. return NULL;
  419. }
  420. if (prepare && prepare != Py_None) {
  421. if (PyTuple_Check(item)) {
  422. tmp = PyObject_CallFunction(prepare, "OO", self, item);
  423. }
  424. else {
  425. tmp = PyObject_CallFunction(prepare, "O(O)", self, item);
  426. }
  427. Py_DECREF(prepare);
  428. Py_SETREF(item, tmp);
  429. if (item == NULL) {
  430. return NULL;
  431. }
  432. }
  433. }
  434. int is_tuple = PyTuple_Check(item);
  435. Py_ssize_t nitems = is_tuple ? PyTuple_GET_SIZE(item) : 1;
  436. PyObject **argitems = is_tuple ? &PyTuple_GET_ITEM(item, 0) : &item;
  437. if (nitems != nparams) {
  438. Py_DECREF(item);
  439. return PyErr_Format(PyExc_TypeError,
  440. "Too %s arguments for %R; actual %zd, expected %zd",
  441. nitems > nparams ? "many" : "few",
  442. self, nitems, nparams);
  443. }
  444. /* Replace all type variables (specified by parameters)
  445. with corresponding values specified by argitems.
  446. t = list[T]; t[int] -> newargs = [int]
  447. t = dict[str, T]; t[int] -> newargs = [str, int]
  448. t = dict[T, list[S]]; t[str, int] -> newargs = [str, list[int]]
  449. */
  450. Py_ssize_t nargs = PyTuple_GET_SIZE(args);
  451. PyObject *newargs = PyTuple_New(nargs);
  452. if (newargs == NULL) {
  453. Py_DECREF(item);
  454. return NULL;
  455. }
  456. for (Py_ssize_t iarg = 0, jarg = 0; iarg < nargs; iarg++) {
  457. PyObject *arg = PyTuple_GET_ITEM(args, iarg);
  458. if (PyType_Check(arg)) {
  459. PyTuple_SET_ITEM(newargs, jarg, Py_NewRef(arg));
  460. jarg++;
  461. continue;
  462. }
  463. int unpack = _is_unpacked_typevartuple(arg);
  464. if (unpack < 0) {
  465. Py_DECREF(newargs);
  466. Py_DECREF(item);
  467. return NULL;
  468. }
  469. PyObject *subst;
  470. if (_PyObject_LookupAttr(arg, &_Py_ID(__typing_subst__), &subst) < 0) {
  471. Py_DECREF(newargs);
  472. Py_DECREF(item);
  473. return NULL;
  474. }
  475. if (subst) {
  476. Py_ssize_t iparam = tuple_index(parameters, nparams, arg);
  477. assert(iparam >= 0);
  478. arg = PyObject_CallOneArg(subst, argitems[iparam]);
  479. Py_DECREF(subst);
  480. }
  481. else {
  482. arg = subs_tvars(arg, parameters, argitems, nitems);
  483. }
  484. if (arg == NULL) {
  485. Py_DECREF(newargs);
  486. Py_DECREF(item);
  487. return NULL;
  488. }
  489. if (unpack) {
  490. jarg = tuple_extend(&newargs, jarg,
  491. &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg));
  492. Py_DECREF(arg);
  493. if (jarg < 0) {
  494. Py_DECREF(item);
  495. return NULL;
  496. }
  497. }
  498. else {
  499. PyTuple_SET_ITEM(newargs, jarg, arg);
  500. jarg++;
  501. }
  502. }
  503. Py_DECREF(item);
  504. return newargs;
  505. }
  506. PyDoc_STRVAR(genericalias__doc__,
  507. "Represent a PEP 585 generic type\n"
  508. "\n"
  509. "E.g. for t = list[int], t.__origin__ is list and t.__args__ is (int,).");
  510. static PyObject *
  511. ga_getitem(PyObject *self, PyObject *item)
  512. {
  513. gaobject *alias = (gaobject *)self;
  514. // Populate __parameters__ if needed.
  515. if (alias->parameters == NULL) {
  516. alias->parameters = _Py_make_parameters(alias->args);
  517. if (alias->parameters == NULL) {
  518. return NULL;
  519. }
  520. }
  521. PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item);
  522. if (newargs == NULL) {
  523. return NULL;
  524. }
  525. PyObject *res = Py_GenericAlias(alias->origin, newargs);
  526. if (res == NULL) {
  527. Py_DECREF(newargs);
  528. return NULL;
  529. }
  530. ((gaobject *)res)->starred = alias->starred;
  531. Py_DECREF(newargs);
  532. return res;
  533. }
  534. static PyMappingMethods ga_as_mapping = {
  535. .mp_subscript = ga_getitem,
  536. };
  537. static Py_hash_t
  538. ga_hash(PyObject *self)
  539. {
  540. gaobject *alias = (gaobject *)self;
  541. // TODO: Hash in the hash for the origin
  542. Py_hash_t h0 = PyObject_Hash(alias->origin);
  543. if (h0 == -1) {
  544. return -1;
  545. }
  546. Py_hash_t h1 = PyObject_Hash(alias->args);
  547. if (h1 == -1) {
  548. return -1;
  549. }
  550. return h0 ^ h1;
  551. }
  552. static inline PyObject *
  553. set_orig_class(PyObject *obj, PyObject *self)
  554. {
  555. if (obj != NULL) {
  556. if (PyObject_SetAttr(obj, &_Py_ID(__orig_class__), self) < 0) {
  557. if (!PyErr_ExceptionMatches(PyExc_AttributeError) &&
  558. !PyErr_ExceptionMatches(PyExc_TypeError))
  559. {
  560. Py_DECREF(obj);
  561. return NULL;
  562. }
  563. PyErr_Clear();
  564. }
  565. }
  566. return obj;
  567. }
  568. static PyObject *
  569. ga_call(PyObject *self, PyObject *args, PyObject *kwds)
  570. {
  571. gaobject *alias = (gaobject *)self;
  572. PyObject *obj = PyObject_Call(alias->origin, args, kwds);
  573. return set_orig_class(obj, self);
  574. }
  575. static PyObject *
  576. ga_vectorcall(PyObject *self, PyObject *const *args,
  577. size_t nargsf, PyObject *kwnames)
  578. {
  579. gaobject *alias = (gaobject *) self;
  580. PyObject *obj = PyVectorcall_Function(alias->origin)(alias->origin, args, nargsf, kwnames);
  581. return set_orig_class(obj, self);
  582. }
  583. static const char* const attr_exceptions[] = {
  584. "__class__",
  585. "__origin__",
  586. "__args__",
  587. "__unpacked__",
  588. "__parameters__",
  589. "__typing_unpacked_tuple_args__",
  590. "__mro_entries__",
  591. "__reduce_ex__", // needed so we don't look up object.__reduce_ex__
  592. "__reduce__",
  593. "__copy__",
  594. "__deepcopy__",
  595. NULL,
  596. };
  597. static PyObject *
  598. ga_getattro(PyObject *self, PyObject *name)
  599. {
  600. gaobject *alias = (gaobject *)self;
  601. if (PyUnicode_Check(name)) {
  602. for (const char * const *p = attr_exceptions; ; p++) {
  603. if (*p == NULL) {
  604. return PyObject_GetAttr(alias->origin, name);
  605. }
  606. if (_PyUnicode_EqualToASCIIString(name, *p)) {
  607. break;
  608. }
  609. }
  610. }
  611. return PyObject_GenericGetAttr(self, name);
  612. }
  613. static PyObject *
  614. ga_richcompare(PyObject *a, PyObject *b, int op)
  615. {
  616. if (!_PyGenericAlias_Check(b) ||
  617. (op != Py_EQ && op != Py_NE))
  618. {
  619. Py_RETURN_NOTIMPLEMENTED;
  620. }
  621. if (op == Py_NE) {
  622. PyObject *eq = ga_richcompare(a, b, Py_EQ);
  623. if (eq == NULL)
  624. return NULL;
  625. Py_DECREF(eq);
  626. if (eq == Py_True) {
  627. Py_RETURN_FALSE;
  628. }
  629. else {
  630. Py_RETURN_TRUE;
  631. }
  632. }
  633. gaobject *aa = (gaobject *)a;
  634. gaobject *bb = (gaobject *)b;
  635. if (aa->starred != bb->starred) {
  636. Py_RETURN_FALSE;
  637. }
  638. int eq = PyObject_RichCompareBool(aa->origin, bb->origin, Py_EQ);
  639. if (eq < 0) {
  640. return NULL;
  641. }
  642. if (!eq) {
  643. Py_RETURN_FALSE;
  644. }
  645. return PyObject_RichCompare(aa->args, bb->args, Py_EQ);
  646. }
  647. static PyObject *
  648. ga_mro_entries(PyObject *self, PyObject *args)
  649. {
  650. gaobject *alias = (gaobject *)self;
  651. return PyTuple_Pack(1, alias->origin);
  652. }
  653. static PyObject *
  654. ga_instancecheck(PyObject *self, PyObject *Py_UNUSED(ignored))
  655. {
  656. PyErr_SetString(PyExc_TypeError,
  657. "isinstance() argument 2 cannot be a parameterized generic");
  658. return NULL;
  659. }
  660. static PyObject *
  661. ga_subclasscheck(PyObject *self, PyObject *Py_UNUSED(ignored))
  662. {
  663. PyErr_SetString(PyExc_TypeError,
  664. "issubclass() argument 2 cannot be a parameterized generic");
  665. return NULL;
  666. }
  667. static PyObject *
  668. ga_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
  669. {
  670. gaobject *alias = (gaobject *)self;
  671. if (alias->starred) {
  672. PyObject *tmp = Py_GenericAlias(alias->origin, alias->args);
  673. if (tmp != NULL) {
  674. Py_SETREF(tmp, PyObject_GetIter(tmp));
  675. }
  676. if (tmp == NULL) {
  677. return NULL;
  678. }
  679. return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(next)), tmp);
  680. }
  681. return Py_BuildValue("O(OO)", Py_TYPE(alias),
  682. alias->origin, alias->args);
  683. }
  684. static PyObject *
  685. ga_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
  686. {
  687. gaobject *alias = (gaobject *)self;
  688. PyObject *dir = PyObject_Dir(alias->origin);
  689. if (dir == NULL) {
  690. return NULL;
  691. }
  692. PyObject *dir_entry = NULL;
  693. for (const char * const *p = attr_exceptions; ; p++) {
  694. if (*p == NULL) {
  695. break;
  696. }
  697. else {
  698. dir_entry = PyUnicode_FromString(*p);
  699. if (dir_entry == NULL) {
  700. goto error;
  701. }
  702. int contains = PySequence_Contains(dir, dir_entry);
  703. if (contains < 0) {
  704. goto error;
  705. }
  706. if (contains == 0 && PyList_Append(dir, dir_entry) < 0) {
  707. goto error;
  708. }
  709. Py_CLEAR(dir_entry);
  710. }
  711. }
  712. return dir;
  713. error:
  714. Py_DECREF(dir);
  715. Py_XDECREF(dir_entry);
  716. return NULL;
  717. }
  718. static PyMethodDef ga_methods[] = {
  719. {"__mro_entries__", ga_mro_entries, METH_O},
  720. {"__instancecheck__", ga_instancecheck, METH_O},
  721. {"__subclasscheck__", ga_subclasscheck, METH_O},
  722. {"__reduce__", ga_reduce, METH_NOARGS},
  723. {"__dir__", ga_dir, METH_NOARGS},
  724. {0}
  725. };
  726. static PyMemberDef ga_members[] = {
  727. {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},
  728. {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY},
  729. {"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY},
  730. {0}
  731. };
  732. static PyObject *
  733. ga_parameters(PyObject *self, void *unused)
  734. {
  735. gaobject *alias = (gaobject *)self;
  736. if (alias->parameters == NULL) {
  737. alias->parameters = _Py_make_parameters(alias->args);
  738. if (alias->parameters == NULL) {
  739. return NULL;
  740. }
  741. }
  742. return Py_NewRef(alias->parameters);
  743. }
  744. static PyObject *
  745. ga_unpacked_tuple_args(PyObject *self, void *unused)
  746. {
  747. gaobject *alias = (gaobject *)self;
  748. if (alias->starred && alias->origin == (PyObject *)&PyTuple_Type) {
  749. return Py_NewRef(alias->args);
  750. }
  751. Py_RETURN_NONE;
  752. }
  753. static PyGetSetDef ga_properties[] = {
  754. {"__parameters__", ga_parameters, (setter)NULL, "Type variables in the GenericAlias.", NULL},
  755. {"__typing_unpacked_tuple_args__", ga_unpacked_tuple_args, (setter)NULL, NULL},
  756. {0}
  757. };
  758. /* A helper function to create GenericAlias' args tuple and set its attributes.
  759. * Returns 1 on success, 0 on failure.
  760. */
  761. static inline int
  762. setup_ga(gaobject *alias, PyObject *origin, PyObject *args) {
  763. if (!PyTuple_Check(args)) {
  764. args = PyTuple_Pack(1, args);
  765. if (args == NULL) {
  766. return 0;
  767. }
  768. }
  769. else {
  770. Py_INCREF(args);
  771. }
  772. alias->origin = Py_NewRef(origin);
  773. alias->args = args;
  774. alias->parameters = NULL;
  775. alias->weakreflist = NULL;
  776. if (PyVectorcall_Function(origin) != NULL) {
  777. alias->vectorcall = ga_vectorcall;
  778. }
  779. else {
  780. alias->vectorcall = NULL;
  781. }
  782. return 1;
  783. }
  784. static PyObject *
  785. ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  786. {
  787. if (!_PyArg_NoKeywords("GenericAlias", kwds)) {
  788. return NULL;
  789. }
  790. if (!_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 2)) {
  791. return NULL;
  792. }
  793. PyObject *origin = PyTuple_GET_ITEM(args, 0);
  794. PyObject *arguments = PyTuple_GET_ITEM(args, 1);
  795. gaobject *self = (gaobject *)type->tp_alloc(type, 0);
  796. if (self == NULL) {
  797. return NULL;
  798. }
  799. if (!setup_ga(self, origin, arguments)) {
  800. Py_DECREF(self);
  801. return NULL;
  802. }
  803. return (PyObject *)self;
  804. }
  805. static PyNumberMethods ga_as_number = {
  806. .nb_or = _Py_union_type_or, // Add __or__ function
  807. };
  808. static PyObject *
  809. ga_iternext(gaiterobject *gi) {
  810. if (gi->obj == NULL) {
  811. PyErr_SetNone(PyExc_StopIteration);
  812. return NULL;
  813. }
  814. gaobject *alias = (gaobject *)gi->obj;
  815. PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args);
  816. if (starred_alias == NULL) {
  817. return NULL;
  818. }
  819. ((gaobject *)starred_alias)->starred = true;
  820. Py_SETREF(gi->obj, NULL);
  821. return starred_alias;
  822. }
  823. static void
  824. ga_iter_dealloc(gaiterobject *gi) {
  825. PyObject_GC_UnTrack(gi);
  826. Py_XDECREF(gi->obj);
  827. PyObject_GC_Del(gi);
  828. }
  829. static int
  830. ga_iter_traverse(gaiterobject *gi, visitproc visit, void *arg)
  831. {
  832. Py_VISIT(gi->obj);
  833. return 0;
  834. }
  835. static int
  836. ga_iter_clear(PyObject *self) {
  837. gaiterobject *gi = (gaiterobject *)self;
  838. Py_CLEAR(gi->obj);
  839. return 0;
  840. }
  841. static PyObject *
  842. ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
  843. {
  844. PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
  845. gaiterobject *gi = (gaiterobject *)self;
  846. /* _PyEval_GetBuiltin can invoke arbitrary code,
  847. * call must be before access of iterator pointers.
  848. * see issue #101765 */
  849. if (gi->obj)
  850. return Py_BuildValue("N(O)", iter, gi->obj);
  851. else
  852. return Py_BuildValue("N(())", iter);
  853. }
  854. static PyMethodDef ga_iter_methods[] = {
  855. {"__reduce__", ga_iter_reduce, METH_NOARGS},
  856. {0}
  857. };
  858. // gh-91632: _Py_GenericAliasIterType is exported to be cleared
  859. // in _PyTypes_FiniTypes.
  860. PyTypeObject _Py_GenericAliasIterType = {
  861. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  862. .tp_name = "generic_alias_iterator",
  863. .tp_basicsize = sizeof(gaiterobject),
  864. .tp_iter = PyObject_SelfIter,
  865. .tp_iternext = (iternextfunc)ga_iternext,
  866. .tp_traverse = (traverseproc)ga_iter_traverse,
  867. .tp_methods = ga_iter_methods,
  868. .tp_dealloc = (destructor)ga_iter_dealloc,
  869. .tp_clear = (inquiry)ga_iter_clear,
  870. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  871. };
  872. static PyObject *
  873. ga_iter(PyObject *self) {
  874. gaiterobject *gi = PyObject_GC_New(gaiterobject, &_Py_GenericAliasIterType);
  875. if (gi == NULL) {
  876. return NULL;
  877. }
  878. gi->obj = Py_NewRef(self);
  879. PyObject_GC_Track(gi);
  880. return (PyObject *)gi;
  881. }
  882. // TODO:
  883. // - argument clinic?
  884. // - cache?
  885. PyTypeObject Py_GenericAliasType = {
  886. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  887. .tp_name = "types.GenericAlias",
  888. .tp_doc = genericalias__doc__,
  889. .tp_basicsize = sizeof(gaobject),
  890. .tp_dealloc = ga_dealloc,
  891. .tp_repr = ga_repr,
  892. .tp_as_number = &ga_as_number, // allow X | Y of GenericAlias objs
  893. .tp_as_mapping = &ga_as_mapping,
  894. .tp_hash = ga_hash,
  895. .tp_call = ga_call,
  896. .tp_getattro = ga_getattro,
  897. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL,
  898. .tp_traverse = ga_traverse,
  899. .tp_richcompare = ga_richcompare,
  900. .tp_weaklistoffset = offsetof(gaobject, weakreflist),
  901. .tp_methods = ga_methods,
  902. .tp_members = ga_members,
  903. .tp_alloc = PyType_GenericAlloc,
  904. .tp_new = ga_new,
  905. .tp_free = PyObject_GC_Del,
  906. .tp_getset = ga_properties,
  907. .tp_iter = (getiterfunc)ga_iter,
  908. .tp_vectorcall_offset = offsetof(gaobject, vectorcall),
  909. };
  910. PyObject *
  911. Py_GenericAlias(PyObject *origin, PyObject *args)
  912. {
  913. gaobject *alias = (gaobject*) PyType_GenericAlloc(
  914. (PyTypeObject *)&Py_GenericAliasType, 0);
  915. if (alias == NULL) {
  916. return NULL;
  917. }
  918. if (!setup_ga(alias, origin, args)) {
  919. Py_DECREF(alias);
  920. return NULL;
  921. }
  922. return (PyObject *)alias;
  923. }