8000 bpo-44652: Preserve natural order of args in the union type. (GH-27185) · python/cpython@0cd2d51 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0cd2d51

Browse files
bpo-44652: Preserve natura 8000 l order of args in the union type. (GH-27185)
1 parent 6aab5f9 commit 0cd2d51

File tree

3 files changed

+39
-11
lines changed

3 files changed

+39
-11
lines changed

Lib/test/test_types.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ class Example:
1818

1919
class Forward: ...
2020

21+
def clear_typing_caches():
22+
for f in typing._cleanups:
23+
f()
24+
25+
2126
class TypesTests(unittest.TestCase):
2227

2328
def test_truth_values(self):
@@ -710,11 +715,34 @@ def test_or_type_operator_with_TypeVar(self):
710715
self.assertIs((TV | int)[int], int)
711716

712717
def test_union_args(self):
713-
self.assertEqual((int | str).__args__, (int, str))
714-
self.assertEqual(((int | str) | list).__args__, (int, str, list))
715-
self.assertEqual((int | (str | list)).__args__, (int, str, list))
716-
self.assertEqual((int | None).__args__, (int, type(None)))
717-
self.assertEqual((int | type(None)).__args__, (int, type(None)))
718+
def check(arg, expected):
719+
clear_typing_caches()
720+
self.assertEqual(arg.__args__, expected)
721+
722+
check(int | str, (int, str))
723+
check((int | str) | list, (int, str, list))
724+
check(int | (str | list), (int, str, list))
725+
check((int | str) | int, (int, str))
726+
check(int | (str | int), (int, str))
727+
check((int | str) | (str | int), (int, str))
728+
check(typing.Union[int, str] | list, (int, str, list))
729+
check(int | typing.Union[str, list], (int, str, list))
730+
check((int | str) | (list | int), (int, str, list))
731+
check((int | str) | typing.Union[list, int], (int, str, list))
732+
check(typing.Union[int, str] | (list | int), (int, str, list))
733+
check((str | int) | (int | list), (str, int, list))
734+
check((str | int) | typing.Union[int, list], (str, int, list))
735+
check(typing.Union[str, int] | (int | list), (str, int, list))
736+
check(int | type(None), (int, type(None)))
737+
check(type(None) | int, (type(None), int))
738+
739+
args = (int, list[int], typing.List[int],
740+
typing.Tuple[int, int], typing.Callable[[int], int],
741+
typing.Hashable, typing.TypeVar('T'))
742+
for x in args:
743+
with self.subTest(x):
744+
check(x | None, (x, type(None)))
745+
check(None | x, (type(None), x))
718746

719747
def test_union_parameter_chaining(self):
720748
T = typing.TypeVar("T")

Lib/typing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -988,8 +988,8 @@ def __hash__(self):
988988
def __or__(self, right):
989989
return Union[self, right]
990990

991-
def __ror__(self, right):
992-
return Union[self, right]
991+
def __ror__(self, left):
992+
return Union[left, self]
993993

994994
@_tp_cache
995995
def __getitem__(self, params):
@@ -1099,8 +1099,8 @@ def __reduce__(self):
10991099
def __or__(self, right):
11001100
return Union[self, right]
11011101

1102-
def __ror__(self, right):
1103-
return Union[self, right]
1102+
def __ror__(self, left):
1103+
return Union[left, self]
11041104

11051105
class _CallableGenericAlias(_GenericAlias, _root=True):
11061106
def __repr__(self):

Objects/unionobject.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ dedup_and_flatten_args(PyObject* args)
260260
for (Py_ssize_t i = 0; i < arg_length; i++) {
261261
int is_duplicate = 0;
262262
PyObject* i_element = PyTuple_GET_ITEM(args, i);
263-
for (Py_ssize_t j = i + 1; j < arg_length; j++) {
264-
PyObject* j_element = PyTuple_GET_ITEM(args, j);
263+
for (Py_ssize_t j = 0; j < added_items; j++) {
264+
PyObject* j_element = PyTuple_GET_ITEM(new_args, j);
265265
int is_ga = PyObject_TypeCheck(i_element, &Py_GenericAliasType) &&
266266
PyObject_TypeCheck(j_element, &Py_GenericAliasType);
267267
// RichCompare to also deduplicate GenericAlias types (slower)

0 commit comments

Comments
 (0)
0