mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
[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 c45fa1a5d9
)
Co-authored-by: Yurii Karabas <1998uriyyo@gmail.com>
Co-authored-by: Ken Jin <28750310+Fidget-Spinner@users.noreply.github.com>
This commit is contained in:
parent
e22e8641dd
commit
2d055ce132
5 changed files with 102 additions and 19 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue