diff --git a/mypyc/irbuild/builder.py b/mypyc/irbuild/builder.py index 587be873a46d..39e2c6aa5181 100644 --- a/mypyc/irbuild/builder.py +++ b/mypyc/irbuild/builder.py @@ -62,6 +62,7 @@ BITMAP_BITS, EXT_SUFFIX, GENERATOR_ATTRIBUTE_PREFIX, + IS_FREE_THREADED, MODULE_PREFIX, SELF_NAME, TEMP_ATTR_NAME, @@ -146,7 +147,12 @@ from mypyc.options import CompilerOptions from mypyc.primitives.dict_ops import dict_get_item_op, dict_set_item_op from mypyc.primitives.generic_ops import iter_op, next_op, py_setattr_op -from mypyc.primitives.list_ops import list_get_item_unsafe_op, list_pop_last, to_list +from mypyc.primitives.list_ops import ( + list_get_item_int64_op, + list_get_item_unsafe_op, + list_pop_last, + to_list, +) from mypyc.primitives.misc_ops import ( check_unpack_count_op, get_module_dict_op, @@ -893,7 +899,10 @@ def process_sequence_assignment( index: Value if is_list_rprimitive(rvalue.type): index = Integer(i, c_pyssize_t_rprimitive) - item_value = self.primitive_op(list_get_item_unsafe_op, [rvalue, index], line) + if not IS_FREE_THREADED: + item_value = self.primitive_op(list_get_item_unsafe_op, [rvalue, index], line) + else: + item_value = self.primitive_op(list_get_item_int64_op, [rvalue, index], line) elif is_tuple_rprimitive(rvalue.type): index = Integer(i, c_pyssize_t_rprimitive) item_value = self.call_c(tuple_get_item_unsafe_op, [rvalue, index], line) diff --git a/mypyc/primitives/list_ops.py b/mypyc/primitives/list_ops.py index 25c9cd4b4c31..8af7e9e71df7 100644 --- a/mypyc/primitives/list_ops.py +++ b/mypyc/primitives/list_ops.py @@ -110,7 +110,7 @@ ) # Version with native int index -method_op( +list_get_item_int64_op = method_op( name="__getitem__", arg_types=[list_rprimitive, int64_rprimitive], return_type=object_rprimitive, diff --git a/mypyc/test-data/irbuild-statements.test b/mypyc/test-data/irbuild-statements.test index df7eb5fc7449..8199cfdaa699 100644 --- a/mypyc/test-data/irbuild-statements.test +++ b/mypyc/test-data/irbuild-statements.test @@ -575,7 +575,7 @@ L0: z = r6 return 1 -[case testMultipleAssignmentUnpackFromSequence] +[case testMultipleAssignmentUnpackFromSequence_withgil] from typing import List, Tuple def f(l: List[int], t: Tuple[int, ...]) -> None: @@ -612,6 +612,43 @@ L0: y = r9 return 1 +[case testMultipleAssignmentUnpackFromSequence_nogil] +from typing import List, Tuple + +def f(l: List[int], t: Tuple[int, ...]) -> None: + x: object + y: int + x, y = l + x, y = t +[out] +def f(l, t): + l :: list + t :: tuple + r0 :: i32 + r1 :: bit + r2, r3, x :: object + r4, y :: int + r5 :: i32 + r6 :: bit + r7, r8 :: object + r9 :: int +L0: + r0 = CPySequence_CheckUnpackCount(l, 2) + r1 = r0 >= 0 :: signed + r2 = CPyList_GetItemInt64(l, 0) + r3 = CPyList_GetItemInt64(l, 1) + x = r2 + r4 = unbox(int, r3) + y = r4 + r5 = CPySequence_CheckUnpackCount(t, 2) + r6 = r5 >= 0 :: signed + r7 = CPySequenceTuple_GetItemUnsafe(t, 0) + r8 = CPySequenceTuple_GetItemUnsafe(t, 1) + x = r7 + r9 = unbox(int, r8) + y = r9 + return 1 + [case testAssert] from typing import Optional