| # 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, 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] |
| import sys |
| from typing import Optional |
| from native import ClassIR, FuncIR, Record |
| |
| HAVE_TEST = False |
| if sys.version_info >= (3, 14): |
| try: |
| from test.support import EqualToForwardRef |
| type_forward_ref = EqualToForwardRef |
| HAVE_TEST = True |
| except ImportError as e: |
| # catch the case of a pymanager installed Python |
| # without the test module. It is excluded by default |
| # on Windows. |
| msg = 'Missing "test" module.' |
| if sys.platform == "win32": |
| msg += (' Please install a version of Python with the test module.' |
| ' If you are using pymanager, try running pymanager install --force PythonTest\\<version>') |
| raise ImportError(msg) from e |
| |
| if not HAVE_TEST: |
| from typing import ForwardRef |
| type_forward_ref = ForwardRef |
| |
| assert Record.__annotations__ == { |
| 'st_mtime': float, |
| 'st_size': int, |
| 'is_borrowed': bool, |
| 'hash': str, |
| 'python_path': tuple, |
| 'type': type_forward_ref('ClassIR'), |
| 'method': FuncIR, |
| 'shadow_method': type, |
| 'classes': dict, |
| 'steals': type, |
| 'ordering': type, |
| 'extra_int_constants': list, |
| }, Record.__annotations__ |
| |
| [case testTupleOps] |
| from typing import Tuple, Final, List, Any, Optional, cast |
| from testutil import assertRaises |
| |
| 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 |
| |
| def test_comparison() -> None: |
| assert ('x','y') == ('x','y') |
| assert not(('x','y') != ('x','y')) |
| |
| assert ('x','y') != ('x','y',1) |
| assert not(('x','y') == ('x','y',1)) |
| |
| assert ('x','y',1) != ('x','y') |
| assert not(('x','y',1) == ('x','y')) |
| |
| assert ('x','y') != () |
| assert not(('x','y') == ()) |
| |
| assert () != ('x','y') |
| assert not(() == ('x','y')) |
| |
| # 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 |
| |
| abc: Final = "abc" |
| |
| def known_length() -> tuple[str, ...]: |
| return tuple(str(x) for x in [*abc, *"def", *b"ghi", ("j", "k"), *("l", "m", "n")]) |
| |
| 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') |
| |
| assert known_length() == ('a', 'b', 'c', 'd', 'e', 'f', '103', '104', '105', "('j', 'k')", 'l', 'm', 'n') |
| |
| TUPLE: Final[Tuple[str, ...]] = ('x', 'y') |
| |
| def test_final_boxed_tuple() -> None: |
| t = TUPLE |
| assert t == ('x', 'y') |
| assert 'x' in TUPLE |
| assert 'y' in TUPLE |
| b: object = 'z' in TUPLE |
| assert not b |
| assert 'z' not in TUPLE |
| b2: object = 'x' not in TUPLE |
| assert not b2 |
| b3: object = 'y' not in TUPLE |
| assert not b3 |
| |
| TUP2: Final = ('x', 'y') |
| TUP1: Final = ('x',) |
| TUP0: Final = () |
| |
| def test_final_tuple_in() -> None: |
| assert 'x' + str() in TUP2 |
| assert 'y' + str() in TUP2 |
| b: object = 'z' + str() in TUP2 |
| assert not b |
| |
| assert 'x' + str() in TUP1 |
| b2: object = 'y' in TUP1 |
| assert not b2 |
| |
| b3: object = 'x' in TUP0 |
| assert not b3 |
| |
| def test_final_tuple_not_in() -> None: |
| assert 'z' + str() not in TUP2 |
| b: object = 'x' + str() not in TUP2 |
| assert not b |
| b2: object = 'y' + str() not in TUP2 |
| assert not b2 |
| |
| assert 'y' + str() not in TUP1 |
| b3: object = 'x' not in TUP1 |
| assert not b2 |
| |
| assert 'x' not in TUP0 |
| |
| log = [] |
| |
| def f_a() -> str: |
| log.append('f_a') |
| return 'a' |
| |
| def f_a2() -> str: |
| log.append('f_a2') |
| return 'a' |
| |
| def f_b() -> str: |
| log.append('f_b') |
| return 'b' |
| |
| def f_c() -> str: |
| log.append('f_c') |
| return 'c' |
| |
| def test_tuple_in_order_of_evaluation() -> None: |
| log.clear() |
| assert f_a() in (f_b(), f_a2()) |
| assert log ==["f_a", "f_b", "f_a2"] |
| |
| log.clear() |
| assert f_a() not in (f_b(), f_c()) |
| assert log ==["f_a", "f_b", "f_c"] |
| |
| log.clear() |
| assert f_a() in (f_b(), f_a2(), f_c()) |
| assert log ==["f_a", "f_b", "f_a2", "f_c"] |
| |
| def f_t() -> tuple[str, ...]: |
| log.append('f_t') |
| return ('x', 'a') |
| |
| def test_tuple_in_non_specialized() -> None: |
| log.clear() |
| assert f_a() in f_t() |
| assert log == ["f_a", "f_t"] |
| |
| log.clear() |
| assert f_b() not in f_t() |
| assert log == ["f_b", "f_t"] |
| |
| def test_add() -> None: |
| res = (1, 2, 3, 4) |
| assert (1, 2) + (3, 4) == res |
| with assertRaises(TypeError, 'can only concatenate tuple (not "list") to tuple'): |
| assert (1, 2) + cast(Any, [3, 4]) == res |
| |
| def multiply(a: Tuple[Any, ...], b: int) -> Tuple[Any, ...]: |
| return a * b |
| |
| def test_multiply() -> None: |
| res = (1, 1, 1) |
| assert (1,) * 3 == res |
| assert 3 * (1,) == res |
| assert multiply((1,), 3) == res |
| |
| [case testIsInstance] |
| from copysubclass import subc |
| def test_built_in() -> None: |
| assert isinstance((), tuple) |
| assert isinstance((1, 2), tuple) |
| assert isinstance(('a', 'b', 'c'), tuple) |
| assert isinstance(subc(()), tuple) |
| assert isinstance(subc((1, 2)), tuple) |
| assert isinstance(subc(('a', 'b', 'c')), tuple) |
| |
| assert not isinstance(set(), tuple) |
| assert not isinstance({}, tuple) |
| assert not isinstance([1,2,3], tuple) |
| assert not isinstance({'a','b'}, tuple) |
| assert not isinstance(int() + 1, tuple) |
| assert not isinstance(str() + 'a', tuple) |
| |
| def test_user_defined() -> None: |
| from userdefinedtuple import tuple |
| |
| assert isinstance(tuple(), tuple) |
| assert not isinstance((1, tuple()), tuple) |
| |
| [file copysubclass.py] |
| from typing import Any |
| class subc(tuple[Any]): |
| pass |
| |
| [file userdefinedtuple.py] |
| class tuple: |
| pass |