https://github.com/python/cpython/commit/7a9437d98641e3c3749ab2fd9fb54eac7614f9af
commit: 7a9437d98641e3c3749ab2fd9fb54eac7614f9af
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2025-11-03T06:50:37-08:00
summary:

gh-140348: Fix using | on unusual objects plus Unions (#140383)

files:
A Misc/NEWS.d/next/Library/2025-10-20-12-33-49.gh-issue-140348.SAKnQZ.rst
M Lib/test/test_typing.py
M Objects/unionobject.c

diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 4076004bc13c85..e896df518447c5 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -2283,6 +2283,15 @@ class Ints(enum.IntEnum):
         self.assertEqual(Union[Literal[1], Literal[Ints.B], 
Literal[True]].__args__,
                          (Literal[1], Literal[Ints.B], Literal[True]))
 
+    def test_allow_non_types_in_or(self):
+        # gh-140348: Test that using | with a Union object allows things that 
are
+        # not allowed by is_unionable().
+        U1 = Union[int, str]
+        self.assertEqual(U1 | float, Union[int, str, float])
+        self.assertEqual(U1 | "float", Union[int, str, "float"])
+        self.assertEqual(float | U1, Union[float, int, str])
+        self.assertEqual("float" | U1, Union["float", int, str])
+
 
 class TupleTests(BaseTestCase):
 
diff --git 
a/Misc/NEWS.d/next/Library/2025-10-20-12-33-49.gh-issue-140348.SAKnQZ.rst 
b/Misc/NEWS.d/next/Library/2025-10-20-12-33-49.gh-issue-140348.SAKnQZ.rst
new file mode 100644
index 00000000000000..16d5b2a8bf03d0
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2025-10-20-12-33-49.gh-issue-140348.SAKnQZ.rst
@@ -0,0 +1,3 @@
+Fix regression in Python 3.14.0 where using the ``|`` operator on a
+:class:`typing.Union` object combined with an object that is not a type
+would raise an error.
diff --git a/Objects/unionobject.c b/Objects/unionobject.c
index c4ece0fe09f018..a47d6193d70889 100644
--- a/Objects/unionobject.c
+++ b/Objects/unionobject.c
@@ -393,8 +393,23 @@ static PyGetSetDef union_properties[] = {
     {0}
 };
 
+static PyObject *
+union_nb_or(PyObject *a, PyObject *b)
+{
+    unionbuilder ub;
+    if (!unionbuilder_init(&ub, true)) {
+        return NULL;
+    }
+    if (!unionbuilder_add_single(&ub, a) ||
+        !unionbuilder_add_single(&ub, b)) {
+        unionbuilder_finalize(&ub);
+        return NULL;
+    }
+    return make_union(&ub);
+}
+
 static PyNumberMethods union_as_number = {
-        .nb_or = _Py_union_type_or, // Add __or__ function
+        .nb_or = union_nb_or, // Add __or__ function
 };
 
 static const char* const cls_attrs[] = {

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to