Skip to content

Commit 7881046

Browse files
[3.14] gh-140348: Fix using | on unusual objects plus Unions (GH-140383) (#140948)
gh-140348: Fix using | on unusual objects plus Unions (GH-140383) (cherry picked from commit 7a9437d) Co-authored-by: Jelle Zijlstra <[email protected]>
1 parent 1b376b8 commit 7881046

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

Lib/test/test_typing.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,15 @@ class Ints(enum.IntEnum):
22772277
self.assertEqual(Union[Literal[1], Literal[Ints.B], Literal[True]].__args__,
22782278
(Literal[1], Literal[Ints.B], Literal[True]))
22792279

2280+
def test_allow_non_types_in_or(self):
2281+
# gh-140348: Test that using | with a Union object allows things that are
2282+
# not allowed by is_unionable().
2283+
U1 = Union[int, str]
2284+
self.assertEqual(U1 | float, Union[int, str, float])
2285+
self.assertEqual(U1 | "float", Union[int, str, "float"])
2286+
self.assertEqual(float | U1, Union[float, int, str])
2287+
self.assertEqual("float" | U1, Union["float", int, str])
2288+
22802289

22812290
class TupleTests(BaseTestCase):
22822291

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix regression in Python 3.14.0 where using the ``|`` operator on a
2+
:class:`typing.Union` object combined with an object that is not a type
3+
would raise an error.

Objects/unionobject.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,23 @@ static PyGetSetDef union_properties[] = {
393393
{0}
394394
};
395395

396+
static PyObject *
397+
union_nb_or(PyObject *a, PyObject *b)
398+
{
399+
unionbuilder ub;
400+
if (!unionbuilder_init(&ub, true)) {
401+
return NULL;
402+
}
403+
if (!unionbuilder_add_single(&ub, a) ||
404+
!unionbuilder_add_single(&ub, b)) {
405+
unionbuilder_finalize(&ub);
406+
return NULL;
407+
}
408+
return make_union(&ub);
409+
}
410+
396411
static PyNumberMethods union_as_number = {
397-
.nb_or = _Py_union_type_or, // Add __or__ function
412+
.nb_or = union_nb_or, // Add __or__ function
398413
};
399414

400415
static const char* const cls_attrs[] = {

0 commit comments

Comments
 (0)