blob: e2e8358bb43e230d938b54d4c4ce7bb1e07bfbf9 [file] [log] [blame] [edit]
# 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