genericaliasobject.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  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. ((gaobject *)res)->starred = alias->starred;
  527. Py_DECREF(newargs);
  528. return res;
  529. }
  530. static PyMappingMethods ga_as_mapping = {
  531. .mp_subscript = ga_getitem,
  532. };
  533. static Py_hash_t
  534. ga_hash(PyObject *self)
  535. {
  536. gaobject *alias = (gaobject *)self;
  537. // TODO: Hash in the hash for the origin
  538. Py_hash_t h0 = PyObject_Hash(alias->origin);
  539. if (h0 == -1) {
  540. return -1;
  541. }
  542. Py_hash_t h1 = PyObject_Hash(alias->args);
  543. if (h1 == -1) {
  544. return -1;
  545. }
  546. return h0 ^ h1;
  547. }
  548. static inline PyObject *
  549. set_orig_class(PyObject *obj, PyObject *self)
  550. {
  551. if (obj != NULL) {
  552. if (PyObject_SetAttr(obj, &_Py_ID(__orig_class__), self) < 0) {
  553. if (!PyErr_ExceptionMatches(PyExc_AttributeError) &&
  554. !PyErr_ExceptionMatches(PyExc_TypeError))
  555. {
  556. Py_DECREF(obj);
  557. return NULL;
  558. }
  559. PyErr_Clear();
  560. }
  561. }
  562. return obj;
  563. }
  564. static PyObject *
  565. ga_call(PyObject *self, PyObject *args, PyObject *kwds)
  566. {
  567. gaobject *alias = (gaobject *)self;
  568. PyObject *obj = PyObject_Call(alias->origin, args, kwds);
  569. return set_orig_class(obj, self);
  570. }
  571. static PyObject *
  572. ga_vectorcall(PyObject *self, PyObject *const *args,
  573. size_t nargsf, PyObject *kwnames)
  574. {
  575. gaobject *alias = (gaobject *) self;
  576. PyObject *obj = PyVectorcall_Function(alias->origin)(alias->origin, args, nargsf, kwnames);
  577. return set_orig_class(obj, self);
  578. }
  579. static const char* const attr_exceptions[] = {
  580. "__class__",
  581. "__origin__",
  582. "__args__",
  583. "__unpacked__",
  584. "__parameters__",
  585. "__typing_unpacked_tuple_args__",
  586. "__mro_entries__",
  587. "__reduce_ex__", // needed so we don't look up object.__reduce_ex__
  588. "__reduce__",
  589. "__copy__",
  590. "__deepcopy__",
  591. NULL,
  592. };
  593. static PyObject *
  594. ga_getattro(PyObject *self, PyObject *name)
  595. {
  596. gaobject *alias = (gaobject *)self;
  597. if (PyUnicode_Check(name)) {
  598. for (const char * const *p = attr_exceptions; ; p++) {
  599. if (*p == NULL) {
  600. return PyObject_GetAttr(alias->origin, name);
  601. }
  602. if (_PyUnicode_EqualToASCIIString(name, *p)) {
  603. break;
  604. }
  605. }
  606. }
  607. return PyObject_GenericGetAttr(self, name);
  608. }
  609. static PyObject *
  610. ga_richcompare(PyObject *a, PyObject *b, int op)
  611. {
  612. if (!_PyGenericAlias_Check(b) ||
  613. (op != Py_EQ && op != Py_NE))
  614. {
  615. Py_RETURN_NOTIMPLEMENTED;
  616. }
  617. if (op == Py_NE) {
  618. PyObject *eq = ga_richcompare(a, b, Py_EQ);
  619. if (eq == NULL)
  620. return NULL;
  621. Py_DECREF(eq);
  622. if (eq == Py_True) {
  623. Py_RETURN_FALSE;
  624. }
  625. else {
  626. Py_RETURN_TRUE;
  627. }
  628. }
  629. gaobject *aa = (gaobject *)a;
  630. gaobject *bb = (gaobject *)b;
  631. if (aa->starred != bb->starred) {
  632. Py_RETURN_FALSE;
  633. }
  634. int eq = PyObject_RichCompareBool(aa->origin, bb->origin, Py_EQ);
  635. if (eq < 0) {
  636. return NULL;
  637. }
  638. if (!eq) {
  639. Py_RETURN_FALSE;
  640. }
  641. return PyObject_RichCompare(aa->args, bb->args, Py_EQ);
  642. }
  643. static PyObject *
  644. ga_mro_entries(PyObject *self, PyObject *args)
  645. {
  646. gaobject *alias = (gaobject *)self;
  647. return PyTuple_Pack(1, alias->origin);
  648. }
  649. static PyObject *
  650. ga_instancecheck(PyObject *self, PyObject *Py_UNUSED(ignored))
  651. {
  652. PyErr_SetString(PyExc_TypeError,
  653. "isinstance() argument 2 cannot be a parameterized generic");
  654. return NULL;
  655. }
  656. static PyObject *
  657. ga_subclasscheck(PyObject *self, PyObject *Py_UNUSED(ignored))
  658. {
  659. PyErr_SetString(PyExc_TypeError,
  660. "issubclass() argument 2 cannot be a parameterized generic");
  661. return NULL;
  662. }
  663. static PyObject *
  664. ga_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
  665. {
  666. gaobject *alias = (gaobject *)self;
  667. if (alias->starred) {
  668. PyObject *tmp = Py_GenericAlias(alias->origin, alias->args);
  669. if (tmp != NULL) {
  670. Py_SETREF(tmp, PyObject_GetIter(tmp));
  671. }
  672. if (tmp == NULL) {
  673. return NULL;
  674. }
  675. return Py_BuildValue("N(N)", _PyEval_GetBuiltin(&_Py_ID(next)), tmp);
  676. }
  677. return Py_BuildValue("O(OO)", Py_TYPE(alias),
  678. alias->origin, alias->args);
  679. }
  680. static PyObject *
  681. ga_dir(PyObject *self, PyObject *Py_UNUSED(ignored))
  682. {
  683. gaobject *alias = (gaobject *)self;
  684. PyObject *dir = PyObject_Dir(alias->origin);
  685. if (dir == NULL) {
  686. return NULL;
  687. }
  688. PyObject *dir_entry = NULL;
  689. for (const char * const *p = attr_exceptions; ; p++) {
  690. if (*p == NULL) {
  691. break;
  692. }
  693. else {
  694. dir_entry = PyUnicode_FromString(*p);
  695. if (dir_entry == NULL) {
  696. goto error;
  697. }
  698. int contains = PySequence_Contains(dir, dir_entry);
  699. if (contains < 0) {
  700. goto error;
  701. }
  702. if (contains == 0 && PyList_Append(dir, dir_entry) < 0) {
  703. goto error;
  704. }
  705. Py_CLEAR(dir_entry);
  706. }
  707. }
  708. return dir;
  709. error:
  710. Py_DECREF(dir);
  711. Py_XDECREF(dir_entry);
  712. return NULL;
  713. }
  714. static PyMethodDef ga_methods[] = {
  715. {"__mro_entries__", ga_mro_entries, METH_O},
  716. {"__instancecheck__", ga_instancecheck, METH_O},
  717. {"__subclasscheck__", ga_subclasscheck, METH_O},
  718. {"__reduce__", ga_reduce, METH_NOARGS},
  719. {"__dir__", ga_dir, METH_NOARGS},
  720. {0}
  721. };
  722. static PyMemberDef ga_members[] = {
  723. {"__origin__", T_OBJECT, offsetof(gaobject, origin), READONLY},
  724. {"__args__", T_OBJECT, offsetof(gaobject, args), READONLY},
  725. {"__unpacked__", T_BOOL, offsetof(gaobject, starred), READONLY},
  726. {0}
  727. };
  728. static PyObject *
  729. ga_parameters(PyObject *self, void *unused)
  730. {
  731. gaobject *alias = (gaobject *)self;
  732. if (alias->parameters == NULL) {
  733. alias->parameters = _Py_make_parameters(alias->args);
  734. if (alias->parameters == NULL) {
  735. return NULL;
  736. }
  737. }
  738. return Py_NewRef(alias->parameters);
  739. }
  740. static PyObject *
  741. ga_unpacked_tuple_args(PyObject *self, void *unused)
  742. {
  743. gaobject *alias = (gaobject *)self;
  744. if (alias->starred && alias->origin == (PyObject *)&PyTuple_Type) {
  745. return Py_NewRef(alias->args);
  746. }
  747. Py_RETURN_NONE;
  748. }
  749. static PyGetSetDef ga_properties[] = {
  750. {"__parameters__", ga_parameters, (setter)NULL, "Type variables in the GenericAlias.", NULL},
  751. {"__typing_unpacked_tuple_args__", ga_unpacked_tuple_args, (setter)NULL, NULL},
  752. {0}
  753. };
  754. /* A helper function to create GenericAlias' args tuple and set its attributes.
  755. * Returns 1 on success, 0 on failure.
  756. */
  757. static inline int
  758. setup_ga(gaobject *alias, PyObject *origin, PyObject *args) {
  759. if (!PyTuple_Check(args)) {
  760. args = PyTuple_Pack(1, args);
  761. if (args == NULL) {
  762. return 0;
  763. }
  764. }
  765. else {
  766. Py_INCREF(args);
  767. }
  768. alias->origin = Py_NewRef(origin);
  769. alias->args = args;
  770. alias->parameters = NULL;
  771. alias->weakreflist = NULL;
  772. if (PyVectorcall_Function(origin) != NULL) {
  773. alias->vectorcall = ga_vectorcall;
  774. }
  775. else {
  776. alias->vectorcall = NULL;
  777. }
  778. return 1;
  779. }
  780. static PyObject *
  781. ga_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
  782. {
  783. if (!_PyArg_NoKeywords("GenericAlias", kwds)) {
  784. return NULL;
  785. }
  786. if (!_PyArg_CheckPositional("GenericAlias", PyTuple_GET_SIZE(args), 2, 2)) {
  787. return NULL;
  788. }
  789. PyObject *origin = PyTuple_GET_ITEM(args, 0);
  790. PyObject *arguments = PyTuple_GET_ITEM(args, 1);
  791. gaobject *self = (gaobject *)type->tp_alloc(type, 0);
  792. if (self == NULL) {
  793. return NULL;
  794. }
  795. if (!setup_ga(self, origin, arguments)) {
  796. Py_DECREF(self);
  797. return NULL;
  798. }
  799. return (PyObject *)self;
  800. }
  801. static PyNumberMethods ga_as_number = {
  802. .nb_or = _Py_union_type_or, // Add __or__ function
  803. };
  804. static PyObject *
  805. ga_iternext(gaiterobject *gi) {
  806. if (gi->obj == NULL) {
  807. PyErr_SetNone(PyExc_StopIteration);
  808. return NULL;
  809. }
  810. gaobject *alias = (gaobject *)gi->obj;
  811. PyObject *starred_alias = Py_GenericAlias(alias->origin, alias->args);
  812. if (starred_alias == NULL) {
  813. return NULL;
  814. }
  815. ((gaobject *)starred_alias)->starred = true;
  816. Py_SETREF(gi->obj, NULL);
  817. return starred_alias;
  818. }
  819. static void
  820. ga_iter_dealloc(gaiterobject *gi) {
  821. PyObject_GC_UnTrack(gi);
  822. Py_XDECREF(gi->obj);
  823. PyObject_GC_Del(gi);
  824. }
  825. static int
  826. ga_iter_traverse(gaiterobject *gi, visitproc visit, void *arg)
  827. {
  828. Py_VISIT(gi->obj);
  829. return 0;
  830. }
  831. static int
  832. ga_iter_clear(PyObject *self) {
  833. gaiterobject *gi = (gaiterobject *)self;
  834. Py_CLEAR(gi->obj);
  835. return 0;
  836. }
  837. static PyObject *
  838. ga_iter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
  839. {
  840. PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
  841. gaiterobject *gi = (gaiterobject *)self;
  842. /* _PyEval_GetBuiltin can invoke arbitrary code,
  843. * call must be before access of iterator pointers.
  844. * see issue #101765 */
  845. if (gi->obj)
  846. return Py_BuildValue("N(O)", iter, gi->obj);
  847. else
  848. return Py_BuildValue("N(())", iter);
  849. }
  850. static PyMethodDef ga_iter_methods[] = {
  851. {"__reduce__", ga_iter_reduce, METH_NOARGS},
  852. {0}
  853. };
  854. // gh-91632: _Py_GenericAliasIterType is exported to be cleared
  855. // in _PyTypes_FiniTypes.
  856. PyTypeObject _Py_GenericAliasIterType = {
  857. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  858. .tp_name = "generic_alias_iterator",
  859. .tp_basicsize = sizeof(gaiterobject),
  860. .tp_iter = PyObject_SelfIter,
  861. .tp_iternext = (iternextfunc)ga_iternext,
  862. .tp_traverse = (traverseproc)ga_iter_traverse,
  863. .tp_methods = ga_iter_methods,
  864. .tp_dealloc = (destructor)ga_iter_dealloc,
  865. .tp_clear = (inquiry)ga_iter_clear,
  866. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
  867. };
  868. static PyObject *
  869. ga_iter(PyObject *self) {
  870. gaiterobject *gi = PyObject_GC_New(gaiterobject, &_Py_GenericAliasIterType);
  871. if (gi == NULL) {
  872. return NULL;
  873. }
  874. gi->obj = Py_NewRef(self);
  875. PyObject_GC_Track(gi);
  876. return (PyObject *)gi;
  877. }
  878. // TODO:
  879. // - argument clinic?
  880. // - cache?
  881. PyTypeObject Py_GenericAliasType = {
  882. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  883. .tp_name = "types.GenericAlias",
  884. .tp_doc = genericalias__doc__,
  885. .tp_basicsize = sizeof(gaobject),
  886. .tp_dealloc = ga_dealloc,
  887. .tp_repr = ga_repr,
  888. .tp_as_number = &ga_as_number, // allow X | Y of GenericAlias objs
  889. .tp_as_mapping = &ga_as_mapping,
  890. .tp_hash = ga_hash,
  891. .tp_call = ga_call,
  892. .tp_getattro = ga_getattro,
  893. .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_VECTORCALL,
  894. .tp_traverse = ga_traverse,
  895. .tp_richcompare = ga_richcompare,
  896. .tp_weaklistoffset = offsetof(gaobject, weakreflist),
  897. .tp_methods = ga_methods,
  898. .tp_members = ga_members,
  899. .tp_alloc = PyType_GenericAlloc,
  900. .tp_new = ga_new,
  901. .tp_free = PyObject_GC_Del,
  902. .tp_getset = ga_properties,
  903. .tp_iter = (getiterfunc)ga_iter,
  904. .tp_vectorcall_offset = offsetof(gaobject, vectorcall),
  905. };
  906. PyObject *
  907. Py_GenericAlias(PyObject *origin, PyObject *args)
  908. {
  909. gaobject *alias = (gaobject*) PyType_GenericAlloc(
  910. (PyTypeObject *)&Py_GenericAliasType, 0);
  911. if (alias == NULL) {
  912. return NULL;
  913. }
  914. if (!setup_ga(alias, origin, args)) {
  915. Py_DECREF(alias);
  916. return NULL;
  917. }
  918. return (PyObject *)alias;
  919. }