[3.10] bpo-44636: Collapse union of equal types (GH-27178) (GH-27181)

The result of `int | int` is now `int`.

Fix comparison of the union type with non-hashable objects.
`int | str == {}` no longer raises a TypeError.
(cherry picked from commit d9f923280f204204f8703756aef4f655b579b4b8)
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index 762df5d..f3e0aa6 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -184,9 +184,9 @@ union_richcompare(PyObject *a, PyObject *b, int op)
             }
         }
     } else {
-        if (PySet_Add(b_set, b) == -1) {
-            goto exit;
-        }
+        Py_DECREF(a_set);
+        Py_DECREF(b_set);
+        Py_RETURN_NOTIMPLEMENTED;
     }
     result = PyObject_RichCompare(a_set, b_set, op);
 exit:
@@ -499,16 +499,24 @@ _Py_Union(PyObject *args)
         }
     }
 
+    args = dedup_and_flatten_args(args);
+    if (args == NULL) {
+        return NULL;
+    }
+    if (PyTuple_GET_SIZE(args) == 1) {
+        PyObject *result1 = PyTuple_GET_ITEM(args, 0);
+        Py_INCREF(result1);
+        Py_DECREF(args);
+        return result1;
+    }
+
     result = PyObject_GC_New(unionobject, &_Py_UnionType);
     if (result == NULL) {
+        Py_DECREF(args);
         return NULL;
     }
 
-    result->args = dedup_and_flatten_args(args);
+    result->args = args;
     _PyObject_GC_TRACK(result);
-    if (result->args == NULL) {
-        Py_DECREF(result);
-        return NULL;
-    }
     return (PyObject*)result;
 }