diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2021-07-17 22:14:57 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-17 22:14:57 +0300 |
commit | 2d055ce13250a4074f66a945381a149a3cf8c46f (patch) | |
tree | 41260fe1f80398f1bfd84517755ac2480a4d409d /Objects/unionobject.c | |
parent | e22e8641dd277478b8df7a9fe792ea551adc6932 (diff) | |
download | cpython-git-2d055ce13250a4074f66a945381a149a3cf8c46f.tar.gz |
[3.10] bpo-44490: Add __parameters__ and __getitem__ to types.Union (GH-26980) (GH-27207)
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Co-authored-by: Guido van Rossum <gvanrossum@gmail.com>.
(cherry picked from commit c45fa1a5d9b419cf13ad4b5a7cb453956495b83e)
Co-authored-by: Yurii Karabas <1998uriyyo@gmail.com>
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
Diffstat (limited to 'Objects/unionobject.c')
-rw-r--r-- | Objects/unionobject.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 15cd6c5c74..b3a6506862 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -8,6 +8,7 @@ typedef struct { PyObject_HEAD PyObject *args; + PyObject *parameters; } unionobject; static void @@ -18,6 +19,7 @@ unionobject_dealloc(PyObject *self) _PyObject_GC_UNTRACK(self); Py_XDECREF(alias->args); + Py_XDECREF(alias->parameters); Py_TYPE(self)->tp_free(self); } @@ -26,6 +28,7 @@ union_traverse(PyObject *self, visitproc visit, void *arg) { unionobject *alias = (unionobject *)self; Py_VISIT(alias->args); + Py_VISIT(alias->parameters); return 0; } @@ -450,6 +453,53 @@ static PyMethodDef union_methods[] = { {"__subclasscheck__", union_subclasscheck, METH_O}, {0}}; + +static PyObject * +union_getitem(PyObject *self, PyObject *item) +{ + unionobject *alias = (unionobject *)self; + // Populate __parameters__ if needed. + if (alias->parameters == NULL) { + alias->parameters = _Py_make_parameters(alias->args); + if (alias->parameters == NULL) { + return NULL; + } + } + + PyObject *newargs = _Py_subs_parameters(self, alias->args, alias->parameters, item); + if (newargs == NULL) { + return NULL; + } + + PyObject *res = _Py_Union(newargs); + + Py_DECREF(newargs); + return res; +} + +static PyMappingMethods union_as_mapping = { + .mp_subscript = union_getitem, +}; + +static PyObject * +union_parameters(PyObject *self, void *Py_UNUSED(unused)) +{ + unionobject *alias = (unionobject *)self; + if (alias->parameters == NULL) { + alias->parameters = _Py_make_parameters(alias->args); + if (alias->parameters == NULL) { + return NULL; + } + } + Py_INCREF(alias->parameters); + return alias->parameters; +} + +static PyGetSetDef union_properties[] = { + {"__parameters__", union_parameters, (setter)NULL, "Type variables in the types.Union.", NULL}, + {0} +}; + static PyNumberMethods union_as_number = { .nb_or = _Py_union_type_or, // Add __or__ function }; @@ -471,8 +521,10 @@ PyTypeObject _Py_UnionType = { .tp_members = union_members, .tp_methods = union_methods, .tp_richcompare = union_richcompare, + .tp_as_mapping = &union_as_mapping, .tp_as_number = &union_as_number, .tp_repr = union_repr, + .tp_getset = union_properties, }; PyObject * @@ -516,6 +568,7 @@ _Py_Union(PyObject *args) return NULL; } + result->parameters = NULL; result->args = args; _PyObject_GC_TRACK(result); return (PyObject*)result; |