# Test cases for tuples (compile and run) [case testTuple] from typing import List, Optional, Tuple from typing import Tuple def f(x: Tuple[int, int]) -> Tuple[int,int]: return x def lurr(x: List[Optional[Tuple[int, str]]]) -> object: return x[0] def asdf(x: Tuple[int, str]) -> None: pass [file driver.py] from testutil import assertRaises from native import f, lurr, asdf assert f((1,2)) == (1, 2) assert lurr([(1, '2')]) == (1, '2') with assertRaises(TypeError): print(lurr([(1, 2)])) with assertRaises(TypeError): asdf((1, 2)) [case testTupleGet] from typing import Tuple def f(x: Tuple[Tuple[int, bool], int]) -> int: return x[0][0] [file driver.py] from native import f print(f(((1,True),2))) big_number = pow(2, 80) print(f(((big_number,True),2))) [out] 1 1208925819614629174706176 [case testSequenceTupleArg] from typing import Tuple def f(x: Tuple[int, ...]) -> int: return x[1] [file driver.py] from native import f print(f((1,2,3,4))) [out] 2 [case testTupleAttr] from typing import Tuple class C: b: Tuple[Tuple[Tuple[int, int], int], int, str, object] c: Tuple[()] def f() -> None: c = C() c.b = (((1, 2), 2), 1, 'hi', 'hi2') print(c.b) def g() -> None: try: h() except Exception: print('caught the exception') def h() -> Tuple[Tuple[Tuple[int, int], int], int, str, object]: raise Exception('Intentional exception') [file driver.py] from native import f, g, C f() g() assert not hasattr(C(), 'c') [out] (((1, 2), 2), 1, 'hi', 'hi2') caught the exception [case testNamedTupleAttributeRun] from typing import NamedTuple NT = NamedTuple('NT', [('x', int), ('y', int)]) def f(nt: NT) -> int: if nt.x > nt.y: return nt.x return nt.y nt = NT(1, 2) [file driver.py] from native import NT, nt, f assert f(nt) == 2 assert f(NT(3, 2)) == 3 class Sub(NT): pass assert f(Sub(3, 2)) == 3 -- Ref: https://github.com/mypyc/mypyc/issues/924 [case testNamedTupleClassSyntax] from typing import Dict, List, NamedTuple, Optional, Tuple, Union from typing_extensions import final class FuncIR: pass StealsDescription = Union[bool, List[bool]] class Record(NamedTuple): st_mtime: float st_size: int is_borrowed: bool hash: str python_path: Tuple[str, ...] type: 'ClassIR' method: FuncIR shadow_method: Optional[FuncIR] classes: Dict[str, 'ClassIR'] steals: StealsDescription ordering: Optional[List[int]] extra_int_constants: List[Tuple[int]] # Make sure mypyc loads the annotation string for this forward reference. # Ref: https://github.com/mypyc/mypyc/issues/938 class ClassIR: pass # Ref: https://github.com/mypyc/mypyc/issues/927 @final class Inextensible(NamedTuple): x: int [file driver.py] from typing import ForwardRef, Optional from native import ClassIR, FuncIR, Record assert Record.__annotations__ == { 'st_mtime': float, 'st_size': int, 'is_borrowed': bool, 'hash': str, 'python_path': tuple, 'type': ForwardRef('ClassIR'), 'method': FuncIR, 'shadow_method': type, 'classes': dict, 'steals': type, 'ordering': type, 'extra_int_constants': list, }, Record.__annotations__ [case testTupleOps] from typing import Tuple, List, Any, Optional from typing_extensions import Final def f() -> Tuple[()]: return () def test_empty_tuple() -> None: assert f() == () def f2() -> Any: return () def test_empty_tuple_with_any_type(): assert f2() == () def f3() -> int: x = (False, 1) return x[1] def test_new_tuple() -> None: assert f3() == 1 def f4(y: int) -> int: x = (False, y) return x[1] def test_new_tuple_boxed_int() -> None: big_number = 1208925819614629174706176 assert f4(big_number) == big_number def f5(x: List[int]) -> int: return tuple(x)[1] def test_sequence_tuple() -> None: assert f5([1,2,3,4]) == 2 def f6(x: List[int]) -> int: return len(tuple(x)) def test_sequence_tuple_len() -> None: assert f6([1,2,3,4]) == 4 def f7(x: List[Tuple[int, int]]) -> int: a, b = x[0] return a + b def test_unbox_tuple() -> None: assert f7([(5, 6)]) == 11 # Test that order is irrelevant to unions. Really I only care that this builds. class A: pass def lol() -> A: return A() def foo(x: bool, y: bool) -> Tuple[Optional[A], bool]: z = lol() return None if y else z, x def test_slicing() -> None: # Use dummy adds to avoid constant folding zero = int() two = zero + 2 s: Tuple[str, ...] = ("f", "o", "o", "b", "a", "r") assert s[two:] == ("o", "b", "a", "r") assert s[:two] == ("f", "o") assert s[two:-two] == ("o", "b") assert s[two:two] == () assert s[two:two + 1] == ("o",) assert s[-two:] == ("a", "r") assert s[:-two] == ("f", "o", "o", "b") assert s[:] == ("f", "o", "o", "b", "a", "r") assert s[two:333] == ("o", "b", "a", "r") assert s[333:two] == () assert s[two:-333] == () assert s[-333:two] == ("f", "o") long_int: int = 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 assert s[1:long_int] == ("o", "o", "b", "a", "r") assert s[long_int:] == () assert s[-long_int:-1] == ("f", "o", "o", "b", "a") def f8(val: int) -> bool: return val % 2 == 0 def test_sequence_generator() -> None: source_list = [1, 2, 3] a = tuple(f8(x) for x in source_list) assert a == (False, True, False) source_tuple: Tuple[int, ...] = (1, 2, 3) a = tuple(f8(x) for x in source_tuple) assert a == (False, True, False) source_fixed_length_tuple = (1, 2, 3, 4) a = tuple(f8(x) for x in source_fixed_length_tuple) assert a == (False, True, False, True) source_str = 'abbc' b = tuple('s:' + x for x in source_str) assert b == ('s:a', 's:b', 's:b', 's:c') TUPLE: Final[Tuple[str, ...]] = ('x', 'y') def test_final_boxed_tuple() -> None: t = TUPLE assert t == ('x', 'y')