bpo-41428: Implementation for PEP 604 (GH-21515)
See https://www.python.org/dev/peps/pep-0604/ for more information.
Co-authored-by: Pablo Galindo <pablogsal@gmail.com>
diff --git a/Objects/abstract.c b/Objects/abstract.c
index 7bd72c9..c471f18 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -1,6 +1,7 @@
/* Abstract Object Interface (many thanks to Jim Fulton) */
#include "Python.h"
+#include "pycore_unionobject.h" // _Py_UnionType && _Py_Union()
#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
#include "pycore_pyerrors.h" // _PyErr_Occurred()
@@ -839,7 +840,6 @@
Py_TYPE(w)->tp_name);
return NULL;
}
-
return binop_type_error(v, w, op_name);
}
return result;
@@ -2412,7 +2412,6 @@
PyObject *icls;
int retval;
_Py_IDENTIFIER(__class__);
-
if (PyType_Check(cls)) {
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
if (retval == 0) {
@@ -2432,7 +2431,7 @@
}
else {
if (!check_class(cls,
- "isinstance() arg 2 must be a type or tuple of types"))
+ "isinstance() arg 2 must be a type, a tuple of types or a union"))
return -1;
retval = _PyObject_LookupAttrId(inst, &PyId___class__, &icls);
if (icls != NULL) {
@@ -2525,10 +2524,14 @@
if (!check_class(derived,
"issubclass() arg 1 must be a class"))
return -1;
- if (!check_class(cls,
- "issubclass() arg 2 must be a class"
- " or tuple of classes"))
+
+ PyTypeObject *type = Py_TYPE(cls);
+ int is_union = (PyType_Check(type) && type == &_Py_UnionType);
+ if (!is_union && !check_class(cls,
+ "issubclass() arg 2 must be a class,"
+ " a tuple of classes, or a union.")) {
return -1;
+ }
return abstract_issubclass(derived, cls);
}