diff options
| author | Pablo Galindo Salgado <Pablogsal@gmail.com> | 2021-07-24 14:08:53 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-07-24 14:08:53 (GMT) |
| commit | 9356d1e47de583fd794e9d29abc448759f7a4109 (patch) | |
| tree | dd61cac33c0eba84bf94a22a9c63a97f6c4e5041 /Objects/unionobject.c | |
| parent | e8c01749c02a97a2f5b01086951bb564121c5113 (diff) | |
| download | cpython-9356d1e47de583fd794e9d29abc448759f7a4109.zip cpython-9356d1e47de583fd794e9d29abc448759f7a4109.tar.gz cpython-9356d1e47de583fd794e9d29abc448759f7a4109.tar.bz2 | |
[3.10] bpo-44676: Add ability to serialize types.Union (GH-27244) (GH-27333)
(cherry picked from commit fe13f0b0f696464dd6f283576668dbf57cb11399)
Co-authored-by: Yurii Karabas <1998uriyyo@gmail.com>
Diffstat (limited to 'Objects/unionobject.c')
| -rw-r--r-- | Objects/unionobject.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/Objects/unionobject.c b/Objects/unionobject.c index 659346a..54cdeda 100644 --- a/Objects/unionobject.c +++ b/Objects/unionobject.c @@ -299,6 +299,24 @@ is_unionable(PyObject *obj) return 0; } +static int +is_args_unionable(PyObject *args) +{ + Py_ssize_t nargs = PyTuple_GET_SIZE(args); + for (Py_ssize_t iarg = 0; iarg < nargs; iarg++) { + PyObject *arg = PyTuple_GET_ITEM(args, iarg); + int is_arg_unionable = is_unionable(arg); + if (is_arg_unionable <= 0) { + if (is_arg_unionable == 0) { + PyErr_Format(PyExc_TypeError, + "Each union argument must be a type, got %.100R", arg); + } + return 0; + } + } + return 1; +} + PyObject * _Py_union_type_or(PyObject* self, PyObject* other) { @@ -418,14 +436,47 @@ error: return NULL; } +static PyObject * +union_reduce(PyObject *self, PyObject *Py_UNUSED(ignored)) +{ + unionobject *alias = (unionobject *)self; + PyObject* from_args = PyObject_GetAttrString(self, "_from_args"); + if (from_args == NULL) { + return NULL; + } + + return Py_BuildValue("N(O)", from_args, alias->args); +} + static PyMemberDef union_members[] = { {"__args__", T_OBJECT, offsetof(unionobject, args), READONLY}, {0} }; +static PyObject * +union_from_args(PyObject *cls, PyObject *args) +{ + if (!PyTuple_CheckExact(args)) { + _PyArg_BadArgument("Union._from_args", "argument 'args'", "tuple", args); + return NULL; + } + if (!PyTuple_GET_SIZE(args)) { + PyErr_SetString(PyExc_ValueError, "args must be not empty"); + return NULL; + } + + if (is_args_unionable(args) <= 0) { + return NULL; + } + + return make_union(args); +} + static PyMethodDef union_methods[] = { + {"_from_args", union_from_args, METH_O | METH_CLASS}, {"__instancecheck__", union_instancecheck, METH_O}, {"__subclasscheck__", union_subclasscheck, METH_O}, + {"__reduce__", union_reduce, METH_NOARGS}, {0}}; |
