@@ -273,6 +273,12 @@ is_new_type(PyObject *obj)
273273 return is_typing_module (obj );
274274}
275275
276+ static int
277+ is_typing_union (PyObject * obj )
278+ {
279+ return is_typing_name (obj , "_UnionGenericAlias" );
280+ }
281+
276282// Emulates short-circuiting behavior of the ``||`` operator
277283// while also checking negative values.
278284#define CHECK_RES (res ) { \
@@ -429,6 +435,19 @@ static PyMethodDef union_methods[] = {
429435 {0 }};
430436
431437
438+ static PyObject *
439+ from_typing_union (PyObject * obj )
440+ {
441+ _Py_IDENTIFIER (__args__ );
442+ PyObject * args = _PyObject_GetAttrId (obj , & PyId___args__ );
443+ if (args == NULL ) {
444+ return NULL ;
445+ }
446+ PyObject * result = make_union (args );
447+ Py_DECREF (args );
448+ return result ;
449+ }
450+
432451static PyObject *
433452union_getitem (PyObject * self , PyObject * item )
434453{
@@ -447,16 +466,34 @@ union_getitem(PyObject *self, PyObject *item)
447466 }
448467
449468 // Check arguments are unionable.
469+ assert (Py_REFCNT (newargs ) == 1 );
450470 Py_ssize_t nargs = PyTuple_GET_SIZE (newargs );
451471 for (Py_ssize_t iarg = 0 ; iarg < nargs ; iarg ++ ) {
452472 PyObject * arg = PyTuple_GET_ITEM (newargs , iarg );
453- int is_arg_unionable = is_unionable (arg );
454- if (is_arg_unionable < = 0 ) {
455- Py_DECREF ( newargs );
456- if (is_arg_unionable == 0 ) {
473+ int r = is_unionable (arg );
474+ if (r = = 0 ) {
475+ r = is_typing_union ( arg );
476+ if (r == 0 ) {
457477 PyErr_Format (PyExc_TypeError ,
458478 "Each union argument must be a type, got %.100R" , arg );
479+ Py_DECREF (newargs );
480+ return NULL ;
481+ }
482+ if (r > 0 ) {
483+ // Replace typing.Union with types.Union.
484+ PyObject * newarg = from_typing_union (arg );
485+ if (newarg == NULL ) {
486+ Py_DECREF (newargs );
487+ return NULL ;
488+ }
489+ assert (Py_REFCNT (newargs ) == 1 );
490+ assert (PyTuple_GET_ITEM (newargs , iarg ) == arg );
491+ PyTuple_SET_ITEM (newargs , iarg , newarg );
492+ Py_DECREF (arg );
459493 }
494+ }
495+ if (r < 0 ) {
496+ Py_DECREF (newargs );
460497 return NULL ;
461498 }
462499 }
0 commit comments