@@ -299,6 +299,24 @@ is_unionable(PyObject *obj)
299299 return 0 ;
300300}
301301
302+ static int
303+ is_args_unionable (PyObject * args )
304+ {
305+ Py_ssize_t nargs = PyTuple_GET_SIZE (args );
306+ for (Py_ssize_t iarg = 0 ; iarg < nargs ; iarg ++ ) {
307+ PyObject * arg = PyTuple_GET_ITEM (args , iarg );
308+ int is_arg_unionable = is_unionable (arg );
309+ if (is_arg_unionable <= 0 ) {
310+ if (is_arg_unionable == 0 ) {
311+ PyErr_Format (PyExc_TypeError ,
312+ "Each union argument must be a type, got %.100R" , arg );
313+ }
314+ return 0 ;
315+ }
316+ }
317+ return 1 ;
318+ }
319+
302320PyObject *
303321_Py_union_type_or (PyObject * self , PyObject * other )
304322{
@@ -418,14 +436,47 @@ union_repr(PyObject *self)
418436 return NULL ;
419437}
420438
439+ static PyObject *
440+ union_reduce (PyObject * self , PyObject * Py_UNUSED (ignored ))
441+ {
442+ unionobject * alias = (unionobject * )self ;
443+ PyObject * from_args = PyObject_GetAttrString (self , "_from_args" );
444+ if (from_args == NULL ) {
445+ return NULL ;
446+ }
447+
448+ return Py_BuildValue ("O(O)" , from_args , alias -> args );
449+ }
450+
421451static PyMemberDef union_members [] = {
422452 {"__args__" , T_OBJECT , offsetof(unionobject , args ), READONLY },
423453 {0 }
424454};
425455
456+ static PyObject *
457+ union_from_args (PyObject * cls , PyObject * args )
458+ {
459+ if (!PyTuple_CheckExact (args )) {
460+ _PyArg_BadArgument ("Union._from_args" , "argument 'args'" , "tuple" , args );
461+ return NULL ;
462+ }
463+ if (!PyTuple_GET_SIZE (args )) {
464+ PyErr_SetString (PyExc_ValueError , "args must be not empty" );
465+ return NULL ;
466+ }
467+
468+ if (is_args_unionable (args ) <= 0 ) {
469+ return NULL ;
470+ }
471+
472+ return make_union (args );
473+ }
474+
426475static PyMethodDef union_methods [] = {
476+ {"_from_args" , union_from_args , METH_O | METH_CLASS },
427477 {"__instancecheck__" , union_instancecheck , METH_O },
428478 {"__subclasscheck__" , union_subclasscheck , METH_O },
479+ {"__reduce__" , union_reduce , METH_NOARGS },
429480 {0 }};
430481
431482
0 commit comments