486 lines
9.1 KiB
Plaintext
486 lines
9.1 KiB
Plaintext
|
# Test cases for "range" objects, "for" and "while" loops (compile and run)
|
||
|
|
||
|
[case testFor]
|
||
|
from typing import List, Tuple
|
||
|
def count(n: int) -> None:
|
||
|
for i in range(n):
|
||
|
print(i)
|
||
|
def count_between(n: int, k: int) -> None:
|
||
|
for i in range(n, k):
|
||
|
print(i)
|
||
|
print('n=', n)
|
||
|
def count_down(n: int, k: int) -> None:
|
||
|
for i in range(n, k, -1):
|
||
|
print(i)
|
||
|
def count_double(n: int, k: int) -> None:
|
||
|
for i in range(n, k, 2):
|
||
|
print(i)
|
||
|
def list_iter(l: List[int]) -> None:
|
||
|
for i in l:
|
||
|
print(i)
|
||
|
def tuple_iter(l: Tuple[int, ...]) -> None:
|
||
|
for i in l:
|
||
|
print(i)
|
||
|
def str_iter(l: str) -> None:
|
||
|
for i in l:
|
||
|
print(i)
|
||
|
def list_rev_iter(l: List[int]) -> None:
|
||
|
for i in reversed(l):
|
||
|
print(i)
|
||
|
def list_rev_iter_lol(l: List[int]) -> None:
|
||
|
for i in reversed(l):
|
||
|
print(i)
|
||
|
if i == 3:
|
||
|
while l:
|
||
|
l.pop()
|
||
|
def count_down_short() -> None:
|
||
|
for i in range(10, 0, -1):
|
||
|
print(i)
|
||
|
[file driver.py]
|
||
|
from native import (
|
||
|
count, list_iter, list_rev_iter, list_rev_iter_lol, count_between, count_down, count_double,
|
||
|
count_down_short, tuple_iter, str_iter,
|
||
|
)
|
||
|
count(5)
|
||
|
list_iter(list(reversed(range(5))))
|
||
|
list_rev_iter(list(reversed(range(5))))
|
||
|
count_between(11, 15)
|
||
|
count_between(10**20, 10**20+3)
|
||
|
count_down(20, 10)
|
||
|
count_double(10, 15)
|
||
|
count_down_short()
|
||
|
print('==')
|
||
|
list_rev_iter_lol(list(reversed(range(5))))
|
||
|
tuple_iter((1, 2, 3))
|
||
|
str_iter("abc")
|
||
|
[out]
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
4
|
||
|
4
|
||
|
3
|
||
|
2
|
||
|
1
|
||
|
0
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
4
|
||
|
11
|
||
|
12
|
||
|
13
|
||
|
14
|
||
|
n= 11
|
||
|
100000000000000000000
|
||
|
100000000000000000001
|
||
|
100000000000000000002
|
||
|
n= 100000000000000000000
|
||
|
20
|
||
|
19
|
||
|
18
|
||
|
17
|
||
|
16
|
||
|
15
|
||
|
14
|
||
|
13
|
||
|
12
|
||
|
11
|
||
|
10
|
||
|
12
|
||
|
14
|
||
|
10
|
||
|
9
|
||
|
8
|
||
|
7
|
||
|
6
|
||
|
5
|
||
|
4
|
||
|
3
|
||
|
2
|
||
|
1
|
||
|
==
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
a
|
||
|
b
|
||
|
c
|
||
|
|
||
|
[case testLoopElse]
|
||
|
from typing import Iterator
|
||
|
def run_for_range(n: int) -> None:
|
||
|
for i in range(n):
|
||
|
if i == 3:
|
||
|
break
|
||
|
print(i)
|
||
|
else:
|
||
|
print(n+1)
|
||
|
|
||
|
def run_for_list(n: int) -> None:
|
||
|
for i in list(range(n)):
|
||
|
if i == 3:
|
||
|
break
|
||
|
print(i)
|
||
|
else:
|
||
|
print(n+1)
|
||
|
|
||
|
def run_for_iter(n: int) -> None:
|
||
|
def identity(x: Iterator[int]) -> Iterator[int]:
|
||
|
return x
|
||
|
for i in identity(range(n)):
|
||
|
if i == 3:
|
||
|
break
|
||
|
print(i)
|
||
|
else:
|
||
|
print(n+1)
|
||
|
|
||
|
def count(n: int) -> int:
|
||
|
i = 1
|
||
|
while i <= n:
|
||
|
i = i + 1
|
||
|
if i == 5:
|
||
|
break
|
||
|
else:
|
||
|
i *= -1
|
||
|
return i
|
||
|
|
||
|
def nested_while() -> int:
|
||
|
while True:
|
||
|
while False:
|
||
|
pass
|
||
|
else:
|
||
|
break
|
||
|
else:
|
||
|
return -1
|
||
|
return 0
|
||
|
|
||
|
def nested_for() -> int:
|
||
|
for x in range(1000):
|
||
|
for y in [1,2,3]:
|
||
|
pass
|
||
|
else:
|
||
|
break
|
||
|
else:
|
||
|
return -1
|
||
|
return 0
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import run_for_range, run_for_list, run_for_iter, count, nested_while, nested_for
|
||
|
assert nested_while() == 0
|
||
|
assert nested_for() == 0
|
||
|
assert count(0) == -1
|
||
|
assert count(1) == -2
|
||
|
assert count(5) == 5
|
||
|
assert count(6) == 5
|
||
|
run_for_range(3)
|
||
|
run_for_range(5)
|
||
|
print('==')
|
||
|
run_for_list(3)
|
||
|
run_for_list(5)
|
||
|
print('==')
|
||
|
run_for_iter(3)
|
||
|
run_for_iter(5)
|
||
|
[out]
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
4
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
==
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
4
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
==
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
4
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
|
||
|
[case testNestedLoopSameIdx]
|
||
|
from typing import List, Generator
|
||
|
|
||
|
def nested_enumerate() -> None:
|
||
|
l1 = [0,1,2]
|
||
|
l2 = [0,1,2]
|
||
|
outer_seen = []
|
||
|
outer = 0
|
||
|
for i, j in enumerate(l1):
|
||
|
assert i == outer
|
||
|
outer_seen.append(i)
|
||
|
inner = 0
|
||
|
for i, k in enumerate(l2):
|
||
|
assert i == inner
|
||
|
inner += 1
|
||
|
outer += 1
|
||
|
assert outer_seen == l1
|
||
|
|
||
|
def nested_range() -> None:
|
||
|
outer = 0
|
||
|
outer_seen = []
|
||
|
for i in range(3):
|
||
|
assert i == outer
|
||
|
outer_seen.append(i)
|
||
|
inner = 0
|
||
|
for i in range(3):
|
||
|
assert i == inner
|
||
|
inner += 1
|
||
|
outer += 1
|
||
|
assert outer_seen == [0,1,2]
|
||
|
|
||
|
def nested_list() -> None:
|
||
|
l1 = [0,1,2]
|
||
|
l2 = [0,1,2]
|
||
|
outer_seen = []
|
||
|
outer = 0
|
||
|
for i in l1:
|
||
|
assert i == outer
|
||
|
outer_seen.append(i)
|
||
|
inner = 0
|
||
|
for i in l2:
|
||
|
assert i == inner
|
||
|
inner += 1
|
||
|
outer += 1
|
||
|
assert outer_seen == l1
|
||
|
|
||
|
def nested_yield() -> Generator:
|
||
|
for i in range(3):
|
||
|
for i in range(3):
|
||
|
yield i
|
||
|
yield i
|
||
|
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import nested_enumerate, nested_range, nested_list, nested_yield
|
||
|
nested_enumerate()
|
||
|
nested_range()
|
||
|
nested_list()
|
||
|
gen = nested_yield()
|
||
|
for k in range(12):
|
||
|
assert next(gen) == k % 4
|
||
|
[out]
|
||
|
|
||
|
[case testForIterable]
|
||
|
from typing import Iterable, Dict, Any, Tuple
|
||
|
def iterate_over_any(a: Any) -> None:
|
||
|
for element in a:
|
||
|
print(element)
|
||
|
|
||
|
def iterate_over_iterable(iterable: Iterable[T]) -> None:
|
||
|
for element in iterable:
|
||
|
print(element)
|
||
|
|
||
|
def iterate_and_delete(d: Dict[int, int]) -> None:
|
||
|
for key in d:
|
||
|
d.pop(key)
|
||
|
|
||
|
def sum_over_values(d: Dict[int, int]) -> int:
|
||
|
s = 0
|
||
|
for key in d:
|
||
|
s = s + d[key]
|
||
|
return s
|
||
|
|
||
|
def sum_over_even_values(d: Dict[int, int]) -> int:
|
||
|
s = 0
|
||
|
for key in d:
|
||
|
if d[key] % 2:
|
||
|
continue
|
||
|
s = s + d[key]
|
||
|
return s
|
||
|
|
||
|
def sum_over_two_values(d: Dict[int, int]) -> int:
|
||
|
s = 0
|
||
|
i = 0
|
||
|
for key in d:
|
||
|
if i == 2:
|
||
|
break
|
||
|
s = s + d[key]
|
||
|
i = i + 1
|
||
|
return s
|
||
|
|
||
|
def iterate_over_tuple(iterable: Tuple[int, int, int]) -> None:
|
||
|
for element in iterable:
|
||
|
print(element)
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import iterate_over_any, iterate_over_iterable, iterate_and_delete, sum_over_values, sum_over_even_values, sum_over_two_values, iterate_over_tuple
|
||
|
import traceback
|
||
|
def broken_generator(n):
|
||
|
num = 0
|
||
|
while num < n:
|
||
|
yield num
|
||
|
num += 1
|
||
|
raise Exception('Exception Manually Raised')
|
||
|
|
||
|
d = {1:1, 2:2, 3:3, 4:4, 5:5}
|
||
|
print(sum_over_values(d))
|
||
|
print(sum_over_even_values(d))
|
||
|
print(sum_over_two_values(d))
|
||
|
|
||
|
try:
|
||
|
iterate_over_any(5)
|
||
|
except TypeError:
|
||
|
traceback.print_exc()
|
||
|
try:
|
||
|
iterate_over_iterable(broken_generator(5))
|
||
|
except Exception:
|
||
|
traceback.print_exc()
|
||
|
try:
|
||
|
iterate_and_delete(d)
|
||
|
except RuntimeError:
|
||
|
traceback.print_exc()
|
||
|
|
||
|
iterate_over_tuple((1, 2, 3))
|
||
|
[out]
|
||
|
Traceback (most recent call last):
|
||
|
File "driver.py", line 16, in <module>
|
||
|
iterate_over_any(5)
|
||
|
File "native.py", line 3, in iterate_over_any
|
||
|
for element in a:
|
||
|
TypeError: 'int' object is not iterable
|
||
|
Traceback (most recent call last):
|
||
|
File "driver.py", line 20, in <module>
|
||
|
iterate_over_iterable(broken_generator(5))
|
||
|
File "native.py", line 7, in iterate_over_iterable
|
||
|
for element in iterable:
|
||
|
File "driver.py", line 8, in broken_generator
|
||
|
raise Exception('Exception Manually Raised')
|
||
|
Exception: Exception Manually Raised
|
||
|
Traceback (most recent call last):
|
||
|
File "driver.py", line 24, in <module>
|
||
|
iterate_and_delete(d)
|
||
|
File "native.py", line 11, in iterate_and_delete
|
||
|
for key in d:
|
||
|
RuntimeError: dictionary changed size during iteration
|
||
|
15
|
||
|
6
|
||
|
3
|
||
|
0
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
4
|
||
|
1
|
||
|
2
|
||
|
3
|
||
|
|
||
|
[case testContinueFor]
|
||
|
def f() -> None:
|
||
|
for n in range(5):
|
||
|
continue
|
||
|
[file driver.py]
|
||
|
from native import f
|
||
|
f()
|
||
|
|
||
|
[case testMultipleVarsWithLoops]
|
||
|
# Test comprehensions and for loops with multiple index variables
|
||
|
l = [(1, 2, 'a'), (3, 4, 'b'), (5, 6, 'c')]
|
||
|
l2 = [str(a*100+b)+' '+c for a, b, c in l]
|
||
|
l3 = []
|
||
|
for a, b, c in l:
|
||
|
l3.append(str(a*1000+b)+' '+c)
|
||
|
[file driver.py]
|
||
|
from native import l, l2, l3
|
||
|
for a in l2 + l3:
|
||
|
print(a)
|
||
|
[out]
|
||
|
102 a
|
||
|
304 b
|
||
|
506 c
|
||
|
1002 a
|
||
|
3004 b
|
||
|
5006 c
|
||
|
|
||
|
[case testForZipAndEnumerate]
|
||
|
from typing import Iterable, List, Any
|
||
|
def f(a: Iterable[int], b: List[int]) -> List[Any]:
|
||
|
res = []
|
||
|
for (x, y), z in zip(enumerate(a), b):
|
||
|
res.append((x, y, z))
|
||
|
return res
|
||
|
def g(a: Iterable[int], b: Iterable[str]) -> List[Any]:
|
||
|
res = []
|
||
|
for x, (y, z) in enumerate(zip(a, b)):
|
||
|
res.append((x, y, z))
|
||
|
return res
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import f, g
|
||
|
|
||
|
assert f([6, 7], [8, 9]) == [(0, 6, 8), (1, 7, 9)]
|
||
|
assert g([6, 7], ['a', 'b']) == [(0, 6, 'a'), (1, 7, 'b')]
|
||
|
assert f([6, 7], [8]) == [(0, 6, 8)]
|
||
|
assert f([6], [8, 9]) == [(0, 6, 8)]
|
||
|
|
||
|
[case testIterTypeTrickiness]
|
||
|
# Test inferring the type of a for loop body doesn't cause us grief
|
||
|
# Extracted from somethings that broke in mypy
|
||
|
|
||
|
from typing import Optional
|
||
|
|
||
|
# really I only care that this one build
|
||
|
def foo(x: object) -> None:
|
||
|
if isinstance(x, dict):
|
||
|
for a in x:
|
||
|
pass
|
||
|
|
||
|
def bar(x: Optional[str]) -> None:
|
||
|
vars = (
|
||
|
("a", 'lol'),
|
||
|
("b", 'asdf'),
|
||
|
("lol", x),
|
||
|
("an int", 10),
|
||
|
)
|
||
|
for name, value in vars:
|
||
|
pass
|
||
|
|
||
|
[file driver.py]
|
||
|
from native import bar
|
||
|
bar(None)
|
||
|
|
||
|
[case testRangeObject]
|
||
|
from typing import Any
|
||
|
|
||
|
def f(x: range) -> int:
|
||
|
sum = 0
|
||
|
for i in x:
|
||
|
sum += i
|
||
|
return sum
|
||
|
|
||
|
def test_range_object() -> None:
|
||
|
r1 = range(4, 12, 2)
|
||
|
tmp_list = [x for x in r1]
|
||
|
assert tmp_list == [4, 6, 8, 10]
|
||
|
assert f(r1) == 28
|
||
|
r2: Any = range(10)
|
||
|
assert f(r2) == 45
|
||
|
r3: Any = 'x'
|
||
|
try:
|
||
|
f(r3)
|
||
|
except TypeError as e:
|
||
|
assert "range object expected; got str" in str(e)
|
||
|
try:
|
||
|
ff: Any = f
|
||
|
ff(r3)
|
||
|
except TypeError as e:
|
||
|
assert "range object expected; got str" in str(e)
|
||
|
try:
|
||
|
r4 = range(4, 12, 0)
|
||
|
except ValueError as e:
|
||
|
assert "range() arg 3 must not be zero" in str(e)
|