blob: 3008e7add3fd78bbf56e8ed435aeeeec1a31c125 [file] [log] [blame]
[case testCallTrivialFunction]
def f(x: int) -> int:
return x
[file driver.py]
from native import f
print(f(3))
print(f(-157))
print(f(10**20))
print(f(-10**20))
[out]
3
-157
100000000000000000000
-100000000000000000000
[case testInc]
def inc(x: int) -> int:
return x + 1
[file driver.py]
from native import inc
print(inc(3))
print(inc(-5))
print(inc(10**20))
[out]
4
-4
100000000000000000001
[case testCount]
def count(n: int) -> int:
i = 1
while i <= n:
i = i + 1
return i
[file driver.py]
from native import count
print(count(0))
print(count(1))
print(count(5))
[out]
1
2
6
[case testFor]
from typing import List
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)
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 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
)
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))))
[out]
0
1
2
3
4
4
3
2
1
0
0
1
2
3
4
11
12
13
14
100000000000000000000
100000000000000000001
100000000000000000002
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
[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 testAsync]
import asyncio
async def h() -> int:
return 1
async def g() -> int:
await asyncio.sleep(0.01)
return await h()
async def f() -> int:
return await g()
loop = asyncio.get_event_loop()
result = loop.run_until_complete(f())
assert result == 1
[typing fixtures/typing-full.pyi]
[file driver.py]
from native import f
import asyncio
loop = asyncio.get_event_loop()
result = loop.run_until_complete(f())
assert result == 1
[case testRecursiveFibonacci]
def fib(n: int) -> int:
if n <= 1:
return 1
else:
return fib(n - 1) + fib(n - 2)
return 0 # TODO: This should be unnecessary
[file driver.py]
from native import fib
print(fib(0))
print(fib(1))
print(fib(2))
print(fib(6))
[out]
1
1
2
13
[case testListPlusEquals]
from typing import Any
def append(x: Any) -> None:
x += [1]
[file driver.py]
from native import append
x = []
append(x)
assert x == [1]
[case testListSum]
from typing import List
def sum(a: List[int], l: int) -> int:
sum = 0
i = 0
while i < l:
sum = sum + a[i]
i = i + 1
return sum
[file driver.py]
from native import sum
print(sum([], 0))
print(sum([3], 1))
print(sum([5, 6, -4], 3))
print(sum([2**128 + 5, -2**127 - 8], 2))
[out]
0
3
7
170141183460469231731687303715884105725
[case testListSet]
from typing import List
def copy(a: List[int], b: List[int], l: int) -> int:
i = 0
while i < l:
a[i] = b[i]
i = i + 1
return 0
[file driver.py]
from native import copy
a = [0, '']
copy(a, [-1, 5], 2)
print(1, a)
copy(a, [2**128 + 5, -2**127 - 8], 2)
print(2, a)
[out]
1 [-1, 5]
2 [340282366920938463463374607431768211461, -170141183460469231731687303715884105736]
[case testSieve]
from typing import List
def primes(n: int) -> List[int]:
a = [1] * (n + 1)
a[0] = 0
a[1] = 0
i = 0
while i < n:
if a[i] == 1:
j = i * i
while j < n:
a[j] = 0
j = j + i
i = i + 1
return a
[file driver.py]
from native import primes
print(primes(3))
print(primes(13))
[out]
\[0, 0, 1, 1]
\[0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1]
[case testListPrims]
from typing import List
def append(x: List[int], n: int) -> None:
x.append(n)
def pop_last(x: List[int]) -> int:
return x.pop()
def pop(x: List[int], i: int) -> int:
return x.pop(i)
def count(x: List[int], i: int) -> int:
return x.count(i)
[file driver.py]
from native import append, pop_last, pop, count
l = [1, 2]
append(l, 10)
assert l == [1, 2, 10]
append(l, 3)
append(l, 4)
append(l, 5)
assert l == [1, 2, 10, 3, 4, 5]
pop_last(l)
pop_last(l)
assert l == [1, 2, 10, 3]
pop(l, 2)
assert l == [1, 2, 3]
pop(l, -2)
assert l == [1, 3]
assert count(l, 1) == 1
assert count(l, 2) == 0
[case testTrue]
def f() -> bool:
return True
[file driver.py]
from native import f
print(f())
[out]
True
[case testBoolIf]
def f(x: bool) -> bool:
if x:
return False
else:
return True
[file driver.py]
from native import f
print(f(True))
print(f(False))
[out]
False
True
[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 testEmptyTupleFunctionWithTupleType]
from typing import Tuple
def f() -> Tuple[()]:
return ()
[file driver.py]
from native import f
assert f() == ()
[case testEmptyTupleFunctionWithAnyType]
from typing import Any
def f() -> Any:
return ()
[file driver.py]
from native import f
assert f() == ()
[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)))
[out]
1
[case testTupleGetBoxedInt]
from typing import Tuple
def f(x: Tuple[Tuple[int, bool], int]) -> int:
return x[0][0]
[file driver.py]
from native import f
big_number = pow(2, 80)
print(f(((big_number,True),2)))
[out]
1208925819614629174706176
[case testNewTuple]
def f() -> int:
x = (False, 1)
return x[1]
[file driver.py]
from native import f
print(f())
[out]
1
[case testNewTupleBoxedInt]
def f(y: int) -> int:
x = (False, y)
return x[1]
[file driver.py]
from native import f
big_number = pow(2, 80)
print(f(big_number))
[out]
1208925819614629174706176
[case testSequenceTuple]
from typing import List
def f(x: List[int]) -> int:
return tuple(x)[1]
[file driver.py]
from native import f
print(f([1,2,3,4]))
[out]
2
[case testSequenceTupleLen]
from typing import List
def f(x: List[int]) -> int:
return len(tuple(x))
[file driver.py]
from native import f
print(f([1,2,3,4]))
[out]
4
[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 testMaybeUninitVar]
class C:
def __init__(self, x: int) -> None:
self.x = x
def f(b: bool) -> None:
u = C(1)
while b:
v = C(2)
if v is not u:
break
print(v.x)
[file driver.py]
from native import f
f(True)
[out]
2
[case testUninitBoom]
def f(a: bool, b: bool) -> None:
if a:
x = 'lol'
if b:
print(x)
def g() -> None:
try:
[0][1]
y = 1
except Exception:
pass
print(y)
[file driver.py]
from native import f, g
from testutil import assertRaises
f(True, True)
f(False, False)
with assertRaises(NameError):
f(False, True)
with assertRaises(NameError):
g()
[out]
lol
[case testFunctionCallWithDefaultArgs]
from typing import Tuple, List, Optional, Callable, Any
def f(x: int, y: int = 3, s: str = "test", z: object = 5) -> Tuple[int, str]:
def inner() -> int:
return x + y
return inner(), s
def g() -> None:
assert f(2) == (5, "test")
assert f(s = "123", x = -2) == (1, "123")
def h(a: Optional[object] = None, b: Optional[str] = None) -> Tuple[object, Optional[str]]:
return (a, b)
def same(x: object = object()) -> object:
return x
a_lambda: Callable[..., Any] = lambda n=20: n
def nested_funcs(n: int) -> List[Callable[..., Any]]:
ls: List[Callable[..., Any]] = []
for i in range(n):
def f(i: int = i) -> int:
return i
ls.append(f)
return ls
[file driver.py]
from native import f, g, h, same, nested_funcs, a_lambda
g()
assert f(2) == (5, "test")
assert f(s = "123", x = -2) == (1, "123")
assert h() == (None, None)
assert h(10) == (10, None)
assert h(b='a') == (None, 'a')
assert h(10, 'a') == (10, 'a')
assert same() == same()
assert [f() for f in nested_funcs(10)] == list(range(10))
assert a_lambda(10) == 10
assert a_lambda() == 20
[case testMethodCallWithDefaultArgs]
from typing import Tuple, List
class A:
def f(self, x: int, y: int = 3, s: str = "test") -> Tuple[int, str]:
def inner() -> int:
return x + y
return inner(), s
def g() -> None:
a = A()
assert a.f(2) == (5, "test")
assert a.f(s = "123", x = -2) == (1, "123")
[file driver.py]
from native import A, g
g()
a = A()
assert a.f(2) == (5, "test")
assert a.f(s = "123", x = -2) == (1, "123")
[case testMethodCallOrdering]
class A:
def __init__(self, s: str) -> None:
print(s)
def f(self, x: 'A', y: 'A') -> None:
pass
def g() -> None:
A('A!').f(A('hello'), A('world'))
[file driver.py]
from native import g
g()
[out]
A!
hello
world
[case testImports]
import testmodule
def f(x: int) -> int:
return testmodule.factorial(5)
def g(x: int) -> int:
from welp import foo
return foo(x)
[file testmodule.py]
def factorial(x: int) -> int:
if x == 0:
return 1
else:
return x * factorial(x-1)
[file welp.py]
def foo(x: int) -> int:
return x
[file driver.py]
from native import f, g
print(f(5))
print(g(5))
[out]
120
5
[case testBuiltins]
y = 10
def f(x: int) -> None:
print(5)
d = globals()
assert d['y'] == 10
d['y'] = 20
assert y == 20
[file driver.py]
from native import f
f(5)
[out]
5
[case testImportMissing]
# The unchecked module is configured by the test harness to not be
# picked up by mypy, so we can test that we do that right thing when
# calling library modules without stubs.
import unchecked # type: ignore
import unchecked as lol # type: ignore
assert unchecked.x == 10
assert lol.x == 10
[file unchecked.py]
x = 10
[file driver.py]
import native
[case testOptional]
from typing import Optional
class A: pass
def f(x: Optional[A]) -> Optional[A]:
return x
def g(x: Optional[A]) -> int:
if x is None:
return 1
if x is not None:
return 2
return 3
def h(x: Optional[int], y: Optional[bool]) -> None:
pass
[file driver.py]
from native import f, g, A
a = A()
assert f(None) is None
assert f(a) is a
assert g(None) == 1
assert g(a) == 2
[case testFromImport]
from testmodule import g
def f(x: int) -> int:
return g(x)
[file testmodule.py]
def g(x: int) -> int:
return x + 1
[file driver.py]
from native import f
assert f(1) == 2
[case testStr]
def f() -> str:
return 'some string'
def g() -> str:
return 'some\a \v \t \x7f " \n \0string 🐍'
def tostr(x: int) -> str:
return str(x)
def concat(x: str, y: str) -> str:
return x + y
def eq(x: str) -> int:
if x == 'foo':
return 0
elif x != 'bar':
return 1
return 2
[file driver.py]
from native import f, g, tostr, concat, eq
assert f() == 'some string'
assert g() == 'some\a \v \t \x7f " \n \0string 🐍'
assert tostr(57) == '57'
assert concat('foo', 'bar') == 'foobar'
assert eq('foo') == 0
assert eq('zar') == 1
assert eq('bar') == 2
[case testFstring]
var = 'mypyc'
num = 20
f1 = f'Hello {var}, this is a test'
f2 = f'Hello {var!r}'
f3 = f'Hello {var!a}'
f4 = f'Hello {var!s}'
f5 = f'Hello {var:>20}'
f6 = f'Hello {var!r:>20}'
f7 = f'Hello {var:>{num}}'
f8 = f'Hello {var!r:>{num}}'
f9 = f'Hello {var}, hello again {var}'
[file driver.py]
from native import f1, f2, f3, f4, f5, f6, f7, f8, f9
assert f1 == "Hello mypyc, this is a test"
assert f2 == "Hello 'mypyc'"
assert f3 == "Hello 'mypyc'"
assert f4 == "Hello mypyc"
assert f5 == "Hello mypyc"
assert f6 == "Hello 'mypyc'"
assert f7 == "Hello mypyc"
assert f8 == "Hello 'mypyc'"
assert f9 == "Hello mypyc, hello again mypyc"
[out]
[case testSets]
from typing import Set, List
def instantiateLiteral() -> Set[int]:
return {1, 2, 3, 5, 8}
def fromIterator() -> List[Set[int]]:
x = set([1, 3, 5])
y = set((1, 3, 5))
z = set({1: '1', 3: '3', 5: '5'})
return [x, y, z]
def addIncrementing(s : Set[int]) -> None:
for a in [1, 2, 3]:
if a not in s:
s.add(a)
return
def replaceWith1(s : Set[int]) -> None:
s.clear()
s.add(1)
def remove1(s : Set[int]) -> None:
s.remove(1)
def discard1(s: Set[int]) -> None:
s.discard(1)
def pop(s : Set[int]) -> int:
return s.pop()
def update(s: Set[int], x: List[int]) -> None:
s.update(x)
[file driver.py]
from native import instantiateLiteral
from testutil import assertRaises
val = instantiateLiteral()
assert 1 in val
assert 2 in val
assert 3 in val
assert 5 in val
assert 8 in val
assert len(val) == 5
assert val == {1, 2, 3, 5, 8}
s = 0
for i in val:
s += i
assert s == 19
from native import fromIterator
sets = fromIterator()
for s in sets:
assert s == {1, 3, 5}
from native import addIncrementing
s = set()
addIncrementing(s)
assert s == {1}
addIncrementing(s)
assert s == {1, 2}
addIncrementing(s)
assert s == {1, 2, 3}
from native import replaceWith1
s = {3, 7, 12}
replaceWith1(s)
assert s == {1}
from native import remove1
import traceback
s = {1, 4, 6}
remove1(s)
assert s == {4, 6}
with assertRaises(KeyError, '1'):
remove1(s)
from native import discard1
s = {1, 4, 6}
discard1(s)
assert s == {4, 6}
discard1(s)
assert s == {4, 6}
from native import pop
s = {1, 2, 3}
x = pop(s)
assert len(s) == 2
assert x in [1, 2, 3]
y = pop(s)
assert len(s) == 1
assert y in [1, 2, 3]
assert x != y
z = pop(s)
assert len(s) == 0
assert z in [1, 2, 3]
assert x != z
assert y != z
with assertRaises(KeyError, 'pop from an empty set'):
pop(s)
from native import update
s = {1, 2, 3}
update(s, [5, 4, 3])
assert s == {1, 2, 3, 4, 5}
[case testDictStuff]
from typing import Dict, Any
from defaultdictwrap import make_dict
def f(x: int) -> int:
dict1 = {} # type: Dict[int, int]
dict1[1] = 1
dict2 = {} # type: Dict[int, int]
dict2[x] = 2
dict1.update(dict2)
l = [(5, 2)] # type: Any
dict1.update(l)
d2 = {6: 4} # type: Any
dict1.update(d2)
return dict1[1]
def g() -> int:
d = make_dict()
d['a'] = 10
d['a'] += 10
d['b'] += 10
l = [('c', 2)] # type: Any
d.update(l)
d2 = {'d': 4} # type: Any
d.update(d2)
return d['a'] + d['b']
def h() -> None:
d = {} # type: Dict[Any, Any]
d[{}]
def update_dict(x: Dict[Any, Any], y: Any):
x.update(y)
def make_dict1(x: Any) -> Dict[Any, Any]:
return dict(x)
def make_dict2(x: Dict[Any, Any]) -> Dict[Any, Any]:
return dict(x)
def u(x: int) -> int:
d = {} # type: Dict[str, int]
d.update(x=x)
return d['x']
[file defaultdictwrap.py]
from typing import Dict
from collections import defaultdict # type: ignore
def make_dict() -> Dict[str, int]:
return defaultdict(int)
[file driver.py]
from native import f, g, h, u, make_dict1, make_dict2, update_dict
assert f(1) == 2
assert f(2) == 1
assert g() == 30
# Make sure we get a TypeError from indexing with unhashable and not KeyError
try:
h()
except TypeError:
pass
else:
assert False
d = {'a': 1, 'b': 2}
assert make_dict1(d) == d
assert make_dict1(d.items()) == d
assert make_dict2(d) == d
# object.__dict__ is a "mappingproxy" and not a dict
assert make_dict1(object.__dict__) == dict(object.__dict__)
d = {}
update_dict(d, object.__dict__)
assert d == dict(object.__dict__)
assert u(10) == 10
[case testPyMethodCall]
from typing import List
def f(x: List[int]) -> int:
return x.pop()
def g(x: List[int], y: List[int]) -> None:
x.extend(y)
[file driver.py]
from native import f, g
l = [1, 2]
assert f(l) == 2
g(l, [10])
assert l == [1, 10]
assert f(l) == 10
assert f(l) == 1
g(l, [11, 12])
assert l == [11, 12]
[case testMethodCallWithKeywordArgs]
from typing import Tuple
import testmodule
class A:
def echo(self, a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
def test_native_method_call_with_kwargs() -> None:
a = A()
assert a.echo(1, c=3, b=2) == (1, 2, 3)
assert a.echo(c = 3, a = 1, b = 2) == (1, 2, 3)
def test_module_method_call_with_kwargs() -> None:
a = testmodule.A()
assert a.echo(1, c=3, b=2) == (1, 2, 3)
assert a.echo(c = 3, a = 1, b = 2) == (1, 2, 3)
[file testmodule.py]
from typing import Tuple
class A:
def echo(self, a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
[file driver.py]
import native
native.test_native_method_call_with_kwargs()
native.test_module_method_call_with_kwargs()
[case testException]
from typing import List
def f(x: List[int]) -> None:
g(x)
def g(x: List[int]) -> bool:
x[5] = 2
return True
def r1() -> None:
q1()
def q1() -> None:
raise Exception("test")
def r2() -> None:
q2()
def q2() -> None:
raise Exception
class A:
def __init__(self) -> None:
raise Exception
def hey() -> None:
A()
[file driver.py]
from native import f, r1, r2, hey
import traceback
try:
f([])
except IndexError:
traceback.print_exc()
try:
r1()
except Exception:
traceback.print_exc()
try:
r2()
except Exception:
traceback.print_exc()
try:
hey()
except Exception:
traceback.print_exc()
[out]
Traceback (most recent call last):
File "driver.py", line 4, in <module>
f([])
File "native.py", line 3, in f
g(x)
File "native.py", line 6, in g
x[5] = 2
IndexError: list assignment index out of range
Traceback (most recent call last):
File "driver.py", line 8, in <module>
r1()
File "native.py", line 10, in r1
q1()
File "native.py", line 13, in q1
raise Exception("test")
Exception: test
Traceback (most recent call last):
File "driver.py", line 12, in <module>
r2()
File "native.py", line 16, in r2
q2()
File "native.py", line 19, in q2
raise Exception
Exception
Traceback (most recent call last):
File "driver.py", line 16, in <module>
hey()
File "native.py", line 26, in hey
A()
File "native.py", line 23, in __init__
raise Exception
Exception
[case testTryExcept]
from typing import Any, Iterator
import wrapsys
def g(b: bool) -> None:
try:
if b:
x = [0]
x[1]
else:
raise Exception('hi')
except:
print("caught!")
def r(x: int) -> None:
if x == 0:
[0][1]
elif x == 1:
raise Exception('hi')
elif x == 2:
{1: 1}[0]
elif x == 3:
a = object() # type: Any
a.lol
def f(b: bool) -> None:
try:
r(int(b))
except AttributeError:
print('no')
except:
print(str(wrapsys.exc_info()[1]))
print(str(wrapsys.exc_info()[1]))
def h() -> None:
while True:
try:
raise Exception('gonna break')
except:
print(str(wrapsys.exc_info()[1]))
break
print(str(wrapsys.exc_info()[1]))
def i() -> None:
try:
r(0)
except:
print(type(wrapsys.exc_info()[1]))
raise
def j(n: int) -> None:
try:
r(n)
except (IndexError, KeyError):
print("lookup!")
except AttributeError as e:
print("attr! --", e)
def k() -> None:
try:
r(1)
except:
r(0)
def l() -> None:
try:
r(0)
except IndexError:
try:
r(2)
except KeyError as e:
print("key! --", e)
def m(x: object) -> int:
try:
st = id(x)
except Exception:
return -1
return st + 1
def iter_exception() -> Iterator[str]:
try:
r(0)
except KeyError as e:
yield 'lol'
[file wrapsys.py]
# This is a gross hack around some limitations of the test system/mypyc.
from typing import Any
import sys
def exc_info() -> Any:
return sys.exc_info() # type: ignore
[file driver.py]
import sys, traceback
from native import g, f, h, i, j, k, l, m, iter_exception
from testutil import assertRaises
print("== i ==")
try:
i()
except:
traceback.print_exc(file=sys.stdout)
print("== k ==")
try:
k()
except:
traceback.print_exc(file=sys.stdout)
print("== g ==")
g(True)
g(False)
print("== f ==")
f(True)
f(False)
print("== h ==")
h()
print("== j ==")
j(0)
j(2)
j(3)
try:
j(1)
except:
print("out!")
print("== l ==")
l()
m('lol')
with assertRaises(IndexError):
list(iter_exception())
[out]
== i ==
<class 'IndexError'>
Traceback (most recent call last):
File "driver.py", line 6, in <module>
i()
File "native.py", line 44, in i
r(0)
File "native.py", line 15, in r
[0][1]
IndexError: list index out of range
== k ==
Traceback (most recent call last):
File "native.py", line 59, in k
r(1)
File "native.py", line 17, in r
raise Exception('hi')
Exception: hi
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "driver.py", line 12, in <module>
k()
File "native.py", line 61, in k
r(0)
File "native.py", line 15, in r
[0][1]
IndexError: list index out of range
== g ==
caught!
caught!
== f ==
hi
None
list index out of range
None
== h ==
gonna break
None
== j ==
lookup!
lookup!
attr! -- 'object' object has no attribute 'lol'
out!
== l ==
key! -- 0
[case testTryFinally]
from typing import Any
import wrapsys
def a(b1: bool, b2: int) -> None:
try:
if b1:
raise Exception('hi')
finally:
print('finally:', str(wrapsys.exc_info()[1]))
if b2 == 2:
return
if b2 == 1:
raise Exception('again!')
def b(b1: int, b2: int) -> str:
try:
if b1 == 1:
raise Exception('hi')
elif b1 == 2:
[0][1]
elif b1 == 3:
return 'try'
except IndexError:
print('except')
finally:
print('finally:', str(wrapsys.exc_info()[1]))
if b2 == 2:
return 'finally'
if b2 == 1:
raise Exception('again!')
return 'outer'
def c() -> str:
try:
try:
return 'wee'
finally:
print("out a")
finally:
print("out b")
[file wrapsys.py]
# This is a gross hack around some limitations of the test system/mypyc.
from typing import Any
import sys
def exc_info() -> Any:
return sys.exc_info() # type: ignore
[file driver.py]
import traceback
import sys
from native import a, b, c
def run(f):
try:
x = f()
if x:
print("returned:", x)
except Exception as e:
print("caught:", type(e).__name__ + ": " + str(e))
print("== a ==")
for i in range(3):
for b1 in [False, True]:
run(lambda: a(b1, i))
print("== b ==")
for i in range(4):
for j in range(3):
run(lambda: b(i, j))
print("== b ==")
print(c())
[out]
== a ==
finally: None
finally: hi
caught: Exception: hi
finally: None
caught: Exception: again!
finally: hi
caught: Exception: again!
finally: None
finally: hi
== b ==
finally: None
returned: outer
finally: None
caught: Exception: again!
finally: None
returned: finally
finally: hi
caught: Exception: hi
finally: hi
caught: Exception: again!
finally: hi
returned: finally
except
finally: None
returned: outer
except
finally: None
caught: Exception: again!
except
finally: None
returned: finally
finally: None
returned: try
finally: None
caught: Exception: again!
finally: None
returned: finally
== b ==
out a
out b
wee
[case testCustomException]
from typing import List
class ListOutOfBounds(IndexError):
pass
class UserListWarning(UserWarning):
pass
def f(l: List[int], k: int) -> int:
try:
return l[k]
except IndexError:
raise ListOutOfBounds("Ruh-roh from f!")
def g(l: List[int], k: int) -> int:
try:
return f([1,2,3], 3)
except ListOutOfBounds:
raise ListOutOfBounds("Ruh-roh from g!")
def k(l: List[int], k: int) -> int:
try:
return g([1,2,3], 3)
except IndexError:
raise UserListWarning("Ruh-roh from k!")
def h() -> int:
try:
return k([1,2,3], 3)
except UserWarning:
return -1
[file driver.py]
from native import h
assert h() == -1
[case testWith]
from typing import Any
class Thing:
def __init__(self, x: str) -> None:
self.x = x
def __enter__(self) -> str:
print('enter!', self.x)
if self.x == 'crash':
raise Exception('ohno')
return self.x
def __exit__(self, x: Any, y: Any, z: Any) -> None:
print('exit!', self.x, y)
def foo(i: int) -> int:
with Thing('a') as x:
print("yooo?", x)
if i == 0:
return 10
elif i == 1:
raise Exception('exception!')
return -1
def bar() -> None:
with Thing('a') as x, Thing('b') as y:
print("yooo?", x, y)
def baz() -> None:
with Thing('a') as x, Thing('crash') as y:
print("yooo?", x, y)
[file driver.py]
from native import foo, bar, baz
assert foo(0) == 10
print('== foo ==')
try:
foo(1)
except Exception:
print('caught')
assert foo(2) == -1
print('== bar ==')
bar()
print('== baz ==')
try:
baz()
except Exception:
print('caught')
[out]
enter! a
yooo? a
exit! a None
== foo ==
enter! a
yooo? a
exit! a exception!
caught
enter! a
yooo? a
exit! a None
== bar ==
enter! a
enter! b
yooo? a b
exit! b None
exit! a None
== baz ==
enter! a
enter! crash
exit! a ohno
caught
[case testGenericEquality]
def eq(a: object, b: object) -> bool:
if a == b:
return True
else:
return False
def ne(a: object, b: object) -> bool:
if a != b:
return True
else:
return False
def f(o: object) -> bool:
if [1, 2] == o:
return True
else:
return False
[file driver.py]
from native import eq, ne, f
assert eq('xz', 'x' + 'z')
assert not eq('x', 'y')
assert not ne('xz', 'x' + 'z')
assert ne('x', 'y')
assert f([1, 2])
assert not f([2, 2])
assert not f(1)
[case testGenericBinaryOps]
from typing import Any
def add(x: Any, y: Any) -> Any:
return x + y
def subtract(x: Any, y: Any) -> Any:
return x - y
def multiply(x: Any, y: Any) -> Any:
return x * y
def floor_div(x: Any, y: Any) -> Any:
return x // y
def true_div(x: Any, y: Any) -> Any:
return x / y
def remainder(x: Any, y: Any) -> Any:
return x % y
def power(x: Any, y: Any) -> Any:
return x ** y
def lshift(x: Any, y: Any) -> Any:
return x << y
def rshift(x: Any, y: Any) -> Any:
return x >> y
def num_and(x: Any, y: Any) -> Any:
return x & y
def num_xor(x: Any, y: Any) -> Any:
return x ^ y
def num_or(x: Any, y: Any) -> Any:
return x | y
def lt(x: Any, y: Any) -> Any:
if x < y:
return True
else:
return False
def le(x: Any, y: Any) -> Any:
if x <= y:
return True
else:
return False
def gt(x: Any, y: Any) -> Any:
if x > y:
return True
else:
return False
def ge(x: Any, y: Any) -> Any:
if x >= y:
return True
else:
return False
def contains(x: Any, y: Any) -> Any:
if x in y:
return True
else:
return False
def identity(x: Any, y: Any) -> Any:
if x is y:
return True
else:
return False
def disidentity(x: Any, y: Any) -> Any:
if x is not y:
return True
else:
return False
def not_eq_cond(a: Any, b: Any) -> bool:
if not (a == b):
return True
else:
return False
def eq2(a: Any, b: Any) -> bool:
return a == b
def slice1(x: Any) -> Any:
return x[:]
def slice2(x: Any, y: Any) -> Any:
return x[y:]
def slice3(x: Any, y: Any) -> Any:
return x[:y]
def slice4(x: Any, y: Any, z: Any) -> Any:
return x[y:z]
def slice5(x: Any, y: Any, z: Any, zz: Any) -> Any:
return x[y:z:zz]
[file driver.py]
from native import *
assert add(5, 6) == 11
assert add('x', 'y') == 'xy'
assert subtract(8, 3) == 5
assert multiply(8, 3) == 24
assert floor_div(8, 3) == 2
assert true_div(7, 2) == 3.5
assert remainder(11, 4) == 3
assert remainder('%.3d', 5) == '005'
assert remainder('%d-%s', (5, 'xy')) == '5-xy'
assert power(3, 4) == 81
assert lshift(5, 3) == 40
assert rshift(41, 3) == 5
assert num_and(99, 56) == 32
assert num_xor(99, 56) == 91
assert num_or(99, 56) == 123
assert lt('a', 'b')
assert not lt('a', 'a')
assert not lt('b', 'a')
assert not gt('a', 'b')
assert not gt('a', 'a')
assert gt('b', 'a')
assert le('a', 'b')
assert le('a', 'a')
assert not le('b', 'a')
assert not ge('a', 'b')
assert ge('a', 'a')
assert ge('b', 'a')
assert contains('x', 'axb')
assert not contains('X', 'axb')
assert contains('x', {'x', 'y'})
a = [1, 3, 5]
assert slice1(a) == a
assert slice1(a) is not a
assert slice2(a, 1) == [3, 5]
assert slice3(a, -1) == [1, 3]
assert slice4(a, 1, -1) == [3]
assert slice5(a, 2, 0, -1) == [5, 3]
o1, o2 = object(), object()
assert identity(o1, o1)
assert not identity(o1, o2)
assert not disidentity(o1, o1)
assert disidentity(o1, o2)
assert eq2('xz', 'x' + 'z')
assert not eq2('x', 'y')
assert not not_eq_cond('xz', 'x' + 'z')
assert not_eq_cond('x', 'y')
[case testGenericMiscOps]
from typing import Any
def neg(x: Any) -> Any:
return -x
def pos(x: Any) -> Any:
return +x
def invert(x: Any) -> Any:
return ~x
def get_item(o: Any, k: Any) -> Any:
return o[k]
def set_item(o: Any, k: Any, v: Any) -> Any:
o[k] = v
[file driver.py]
from native import *
assert neg(6) == -6
assert pos(6) == 6
assert invert(6) == -7
d = {'x': 5}
assert get_item(d, 'x') == 5
set_item(d, 'y', 6)
assert d['y'] == 6
[case testIntMathOps]
# This tests integer math things that are either easier to test in Python than
# in our C tests or are tested here because (for annoying reasons) we don't run
# the C unit tests in our 32-bit CI.
def multiply(x: int, y: int) -> int:
return x * y
# these stringify their outputs because that will catch if exceptions are mishandled
def floor_div(x: int, y: int) -> str:
return str(x // y)
def remainder(x: int, y: int) -> str:
return str(x % y)
[file driver.py]
from native import multiply, floor_div, remainder
def test_multiply(x, y):
assert multiply(x, y) == x * y
def test_floor_div(x, y):
assert floor_div(x, y) == str(x // y)
def test_remainder(x, y):
assert remainder(x, y) == str(x % y)
test_multiply(10**6, 10**6)
test_multiply(2**15, 2**15-1)
test_multiply(2**14, 2**14)
test_multiply(10**12, 10**12)
test_multiply(2**30, 2**30-1)
test_multiply(2**29, 2**29)
test_floor_div(-2**62, -1)
test_floor_div(-2**30, -1)
try:
floor_div(10, 0)
except ZeroDivisionError:
pass
else:
assert False, "Expected ZeroDivisionError"
test_remainder(-2**62, -1)
test_remainder(-2**30, -1)
try:
remainder(10, 0)
except ZeroDivisionError:
pass
else:
assert False, "Expected ZeroDivisionError"
[case testSubclassAttributeAccess]
from mypy_extensions import trait
class A:
v = 0
class B(A):
v = 1
class C(B):
v = 2
[file driver.py]
from native import A, B, C
a = A()
b = B()
c = C()
[case testAnyAttributeAndMethodAccess]
from typing import Any, List
class C:
a: int
def m(self, x: int, a: List[int]) -> int:
return self.a + x + a[0]
def get_a(x: Any) -> Any:
return x.a
def set_a(x: Any, y: Any) -> None:
x.a = y
def call_m(x: Any) -> Any:
return x.m(1, [3])
[file driver.py]
from native import C, get_a, set_a, call_m
class D:
def m(self, x, a):
return self.a + x + a[0]
c = C()
c.a = 6
d = D()
d.a = 2
assert get_a(c) == 6
assert get_a(d) == 2
assert call_m(c) == 10
assert call_m(d) == 6
set_a(c, 5)
assert c.a == 5
set_a(d, 4)
assert d.a == 4
try:
get_a(object())
except AttributeError:
pass
else:
assert False
try:
call_m(object())
except AttributeError:
pass
else:
assert False
try:
set_a(object(), 5)
except AttributeError:
pass
else:
assert False
[case testAnyCall]
from typing import Any
def call(f: Any) -> Any:
return f(1, 'x')
[file driver.py]
from native import call
def f(x, y):
return (x, y)
def g(x): pass
assert call(f) == (1, 'x')
for bad in g, 1:
try:
call(bad)
except TypeError:
pass
else:
assert False, bad
[case testFloat]
def assign_and_return_float_sum() -> float:
f1 = 1.0
f2 = 2.0
f3 = 3.0
return f1 * f2 + f3
def from_int(i: int) -> float:
return float(i)
def to_int(x: float) -> int:
return int(x)
def get_complex() -> complex:
return 5.0j + 3.0
[file driver.py]
from native import assign_and_return_float_sum, from_int, to_int, get_complex
sum = 0.0
for i in range(10):
sum += assign_and_return_float_sum()
assert sum == 50.0
assert str(from_int(10)) == '10.0'
assert str(to_int(3.14)) == '3'
assert str(to_int(3)) == '3'
assert get_complex() == 3+5j
[case testBytes]
def f(x: bytes) -> bytes:
return x
def concat(a: bytes, b: bytes) -> bytes:
return a + b
def eq(a: bytes, b: bytes) -> bool:
return a == b
def neq(a: bytes, b: bytes) -> bool:
return a != b
def join() -> bytes:
seq = (b'1', b'"', b'\xf0')
return b'\x07'.join(seq)
[file driver.py]
from native import f, concat, eq, neq, join
assert f(b'123') == b'123'
assert f(b'\x07 \x0b " \t \x7f \xf0') == b'\x07 \x0b " \t \x7f \xf0'
assert concat(b'123', b'456') == b'123456'
assert eq(b'123', b'123')
assert not eq(b'123', b'1234')
assert neq(b'123', b'1234')
assert join() == b'1\x07"\x07\xf0'
[case testBigIntLiteral]
def big_int() -> None:
a_62_bit = 4611686018427387902
max_62_bit = 4611686018427387903
b_63_bit = 4611686018427387904
c_63_bit = 9223372036854775806
max_63_bit = 9223372036854775807
d_64_bit = 9223372036854775808
max_32_bit = 2147483647
max_31_bit = 1073741823
print(a_62_bit)
print(max_62_bit)
print(b_63_bit)
print(c_63_bit)
print(max_63_bit)
print(d_64_bit)
print(max_32_bit)
print(max_31_bit)
[file driver.py]
from native import big_int
big_int()
[out]
4611686018427387902
4611686018427387903
4611686018427387904
9223372036854775806
9223372036854775807
9223372036854775808
2147483647
1073741823
[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 testNeg]
def neg(x: int) -> int:
return -x
[file driver.py]
from native import neg
assert neg(5) == -5
assert neg(-5) == 5
assert neg(1073741823) == -1073741823
assert neg(-1073741823) == 1073741823
assert neg(1073741824) == -1073741824
assert neg(-1073741824) == 1073741824
assert neg(2147483647) == -2147483647
assert neg(-2147483647) == 2147483647
assert neg(2147483648) == -2147483648
assert neg(-2147483648) == 2147483648
assert neg(4611686018427387904) == -4611686018427387904
assert neg(-4611686018427387904) == 4611686018427387904
assert neg(9223372036854775807) == -9223372036854775807
assert neg(-9223372036854775807) == 9223372036854775807
assert neg(9223372036854775808) == -9223372036854775808
assert neg(-9223372036854775808) == 9223372036854775808
[case testContinueFor]
def f() -> None:
for n in range(5):
continue
[file driver.py]
from native import f
f()
[case testDisplays]
from typing import List, Set, Tuple, Sequence, Dict, Any
def listDisplay(x: List[int], y: List[int]) -> List[int]:
return [1, 2, *x, *y, 3]
def setDisplay(x: Set[int], y: Set[int]) -> Set[int]:
return {1, 2, *x, *y, 3}
def tupleDisplay(x: Sequence[str], y: Sequence[str]) -> Tuple[str, ...]:
return ('1', '2', *x, *y, '3')
def dictDisplay(x: str, y1: Dict[str, int], y2: Dict[str, int]) -> Dict[str, int]:
return {x: 2, **y1, 'z': 3, **y2}
[file driver.py]
from native import listDisplay, setDisplay, tupleDisplay, dictDisplay
assert listDisplay([4], [5, 6]) == [1, 2, 4, 5, 6, 3]
assert setDisplay({4}, {5}) == {1, 2, 3, 4, 5}
assert tupleDisplay(['4', '5'], ['6']) == ('1', '2', '4', '5', '6', '3')
assert dictDisplay('x', {'y1': 1}, {'y2': 2, 'z': 5}) == {'x': 2, 'y1': 1, 'y2': 2, 'z': 5}
[case testCallableTypes]
from typing import Callable
def absolute_value(x: int) -> int:
return x if x > 0 else -x
def call_native_function(x: int) -> int:
return absolute_value(x)
def call_python_function(x: int) -> int:
return int(x)
def return_float() -> float:
return 5.0
def return_callable_type() -> Callable[[], float]:
return return_float
def call_callable_type() -> float:
f = return_callable_type()
return f()
def return_passed_in_callable_type(f: Callable[[], float]) -> Callable[[], float]:
return f
def call_passed_in_callable_type(f: Callable[[], float]) -> float:
return f()
[file driver.py]
from native import call_native_function, call_python_function, return_float, return_callable_type, call_callable_type, return_passed_in_callable_type, call_passed_in_callable_type
a = call_native_function(1)
b = call_python_function(1)
c = return_callable_type()
d = call_callable_type()
e = return_passed_in_callable_type(return_float)
f = call_passed_in_callable_type(return_float)
assert a == 1
assert b == 1
assert c() == 5.0
assert d == 5.0
assert e() == 5.0
assert f == 5.0
[case testKeywordArgs]
from typing import Tuple
import testmodule
def g(a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
def test_call_native_function_with_keyword_args() -> None:
assert g(1, c = 3, b = 2) == (1, 2, 3)
assert g(c = 3, a = 1, b = 2) == (1, 2, 3)
def test_call_module_function_with_keyword_args() -> None:
assert testmodule.g(1, c = 3, b = 2) == (1, 2, 3)
assert testmodule.g(c = 3, a = 1, b = 2) == (1, 2, 3)
def test_call_python_function_with_keyword_args() -> None:
assert int("11", base=2) == 3
def test_call_lambda_function_with_keyword_args() -> None:
g = testmodule.get_lambda_function()
assert g(1, c = 3, b = 2) == (1, 2, 3)
assert g(c = 3, a = 1, b = 2) == (1, 2, 3)
[file testmodule.py]
from typing import Tuple
def g(a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
def get_lambda_function():
return (lambda a, b, c: (a, b, c))
[file driver.py]
import native
native.test_call_native_function_with_keyword_args()
native.test_call_module_function_with_keyword_args()
native.test_call_python_function_with_keyword_args()
native.test_call_lambda_function_with_keyword_args()
[case testStarArgs]
from typing import Tuple
def g(a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
def test_star_args() -> None:
assert g(*[1, 2, 3]) == (1, 2, 3)
assert g(*(1, 2, 3)) == (1, 2, 3)
assert g(*(1,), *[2, 3]) == (1, 2, 3)
assert g(*(), *(1,), *(), *(2,), *(3,), *()) == (1, 2, 3)
assert g(*range(3)) == (0, 1, 2)
[file driver.py]
import native
native.test_star_args()
[case testStar2Args]
from typing import Tuple
def g(a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
def test_star2_args() -> None:
assert g(**{'a': 1, 'b': 2, 'c': 3}) == (1, 2, 3)
assert g(**{'c': 3, 'a': 1, 'b': 2}) == (1, 2, 3)
assert g(b=2, **{'a': 1, 'c': 3}) == (1, 2, 3)
def test_star2_args_bad(v: dict) -> bool:
return g(a=1, b=2, **v) == (1, 2, 3)
[file driver.py]
import native
native.test_star2_args()
# this should raise TypeError due to duplicate kwarg, but currently it doesn't
assert native.test_star2_args_bad({'b': 2, 'c': 3})
[case testStarAndStar2Args]
from typing import Tuple
def g(a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
class C:
def g(self, a: int, b: int, c: int) -> Tuple[int, int, int]:
return a, b, c
def test_star_and_star2_args() -> None:
assert g(1, *(2,), **{'c': 3}) == (1, 2, 3)
assert g(*[1], **{'b': 2, 'c': 3}) == (1, 2, 3)
c = C()
assert c.g(1, *(2,), **{'c': 3}) == (1, 2, 3)
assert c.g(*[1], **{'b': 2, 'c': 3}) == (1, 2, 3)
[file driver.py]
import native
native.test_star_and_star2_args()
[case testAllTheArgCombinations]
from typing import Tuple
def g(a: int, b: int, c: int, d: int = -1) -> Tuple[int, int, int, int]:
return a, b, c, d
class C:
def g(self, a: int, b: int, c: int, d: int = -1) -> Tuple[int, int, int, int]:
return a, b, c, d
def test_all_the_arg_combinations() -> None:
assert g(1, *(2,), **{'c': 3}) == (1, 2, 3, -1)
assert g(*[1], **{'b': 2, 'c': 3, 'd': 4}) == (1, 2, 3, 4)
c = C()
assert c.g(1, *(2,), **{'c': 3}) == (1, 2, 3, -1)
assert c.g(*[1], **{'b': 2, 'c': 3, 'd': 4}) == (1, 2, 3, 4)
[file driver.py]
import native
native.test_all_the_arg_combinations()
[case testArbitraryLvalues]
from typing import List, Dict, Any
class O(object):
def __init__(self) -> None:
self.x = 1
def increment_attr(a: Any) -> Any:
a.x += 1
return a
def increment_attr_o(o: O) -> O:
o.x += 1
return o
def increment_all_indices(l: List[int]) -> List[int]:
for i in range(len(l)):
l[i] += 1
return l
def increment_all_keys(d: Dict[str, int]) -> Dict[str, int]:
for k in d:
d[k] += 1
return d
[file driver.py]
from native import O, increment_attr, increment_attr_o, increment_all_indices, increment_all_keys
class P(object):
def __init__(self) -> None:
self.x = 0
assert increment_attr(P()).x == 1
assert increment_attr_o(O()).x == 2
assert increment_all_indices([1, 2, 3]) == [2, 3, 4]
assert increment_all_keys({'a':1, 'b':2, 'c':3}) == {'a':2, 'b':3, 'c':4}
[case testNestedFunctions]
from typing import Callable
def outer() -> Callable[[], object]:
def inner() -> object:
return None
return inner
def first() -> Callable[[], Callable[[], str]]:
def second() -> Callable[[], str]:
def third() -> str:
return 'third: nested function'
return third
return second
def f1() -> int:
x = 1
def f2() -> int:
y = 2
def f3() -> int:
z = 3
return y
return f3()
return f2()
def outer_func() -> int:
def inner_func() -> int:
return x
x = 1
return inner_func()
def mutual_recursion(start : int) -> int:
def f1(k : int) -> int:
if k <= 0:
return 0
k -= 1
return f2(k)
def f2(k : int) -> int:
if k <= 0:
return 0
k -= 1
return f1(k)
return f1(start)
def topLayer() -> int:
def middleLayer() -> int:
def bottomLayer() -> int:
return x
return bottomLayer()
x = 1
return middleLayer()
def nest1() -> str:
def nest2() -> str:
def nest3() -> str:
def mut1(val: int) -> str:
if val <= 0:
return "bottomed"
val -= 1
return mut2(val)
def mut2(val: int) -> str:
if val <= 0:
return "bottomed"
val -= 1
return mut1(val)
return mut1(start)
return nest3()
start = 3
return nest2()
def uno(num: float) -> Callable[[str], str]:
def dos(s: str) -> str:
return s + '!'
return dos
def eins(num: float) -> str:
def zwei(s: str) -> str:
return s + '?'
a = zwei('eins')
b = zwei('zwei')
return a
def call_other_inner_func(a: int) -> int:
def foo() -> int:
return a + 1
def bar() -> int:
return foo()
def baz(n: int) -> int:
if n == 0:
return 0
return n + baz(n - 1)
return bar() + baz(a)
def inner() -> str:
return 'inner: normal function'
def second() -> str:
return 'second: normal function'
def third() -> str:
return 'third: normal function'
[file driver.py]
from native import (outer, inner, first, uno, eins, call_other_inner_func,
second, third, f1, outer_func, mutual_recursion, topLayer, nest1)
assert outer()() == None
assert inner() == 'inner: normal function'
assert first()()() == 'third: nested function'
assert uno(5.0)('uno') == 'uno!'
assert eins(4.0) == 'eins?'
assert call_other_inner_func(5) == 21
assert second() == 'second: normal function'
assert third() == 'third: normal function'
assert f1() == 2
assert outer_func() == 1
assert mutual_recursion(5) == 0
assert topLayer() == 1
assert nest1() == "bottomed"
[case testOverloads]
from typing import overload, Union, Tuple
@overload
def foo(x: int) -> int: ...
@overload
def foo(x: str) -> str: ...
def foo(x: Union[int, str]) -> Union[int, str]:
return x
class A:
@overload
def foo(self, x: int) -> int: ...
@overload
def foo(self, x: str) -> str: ...
def foo(self, x: Union[int, str]) -> Union[int, str]:
return x
def call1() -> Tuple[int, str]:
return (foo(10), foo('10'))
def call2() -> Tuple[int, str]:
x = A()
return (x.foo(10), x.foo('10'))
[file driver.py]
from native import *
assert call1() == (10, '10')
assert call2() == (10, '10')
[case testControlFlowExprs]
from typing import Tuple
def foo() -> object:
print('foo')
return 'foo'
def bar() -> object:
print('bar')
return 'bar'
def t(x: int) -> int:
print(x)
return x
def f(b: bool) -> Tuple[object, object, object]:
x = foo() if b else bar()
y = b or foo()
z = b and foo()
return (x, y, z)
def g() -> Tuple[object, object]:
return (foo() or bar(), foo() and bar())
def nand(p: bool, q: bool) -> bool:
if not (p and q):
return True
return False
def chained(x: int, y: int, z: int) -> bool:
return t(x) < t(y) > t(z)
def chained2(x: int, y: int, z: int, w: int) -> bool:
return t(x) < t(y) < t(z) < t(w)
[file driver.py]
from native import f, g, nand, chained, chained2
assert f(True) == ('foo', True, 'foo')
print()
assert f(False) == ('bar', 'foo', False)
print()
assert g() == ('foo', 'bar')
assert nand(True, True) == False
assert nand(True, False) == True
assert nand(False, True) == True
assert nand(False, False) == True
print()
assert chained(10, 20, 15) == True
print()
assert chained(10, 20, 30) == False
print()
assert chained(21, 20, 30) == False
print()
assert chained2(1, 2, 3, 4) == True
print()
assert chained2(1, 0, 3, 4) == False
print()
assert chained2(1, 2, 0, 4) == False
[out]
foo
foo
bar
foo
foo
foo
bar
10
20
15
10
20
30
21
20
1
2
3
4
1
0
1
2
0
[case testMultipleAssignment]
from typing import Tuple, List, Any
def from_tuple(t: Tuple[int, str]) -> List[Any]:
x, y = t
return [y, x]
def from_list(l: List[int]) -> List[int]:
x, y = l
return [y, x]
def from_any(o: Any) -> List[Any]:
x, y = o
return [y, x]
[file driver.py]
from native import from_tuple, from_list, from_any
assert from_tuple((1, 'x')) == ['x', 1]
assert from_list([3, 4]) == [4, 3]
assert from_any('xy') == ['y', 'x']
[case testUnboxTuple]
from typing import List, Tuple
def f(x: List[Tuple[int, int]]) -> int:
a, b = x[0]
return a + b
[file driver.py]
from native import f
assert f([(5, 6)]) == 11
[case testUnpack]
from typing import List
a, *b = [1, 2, 3, 4, 5]
*c, d = [1, 2, 3, 4, 5]
e, *f = [1,2]
j, *k, l = [1, 2, 3]
m, *n, o = [1, 2, 3, 4, 5, 6]
p, q, r, *s, t = [1,2,3,4,5,6,7,8,9,10]
tup = (1,2,3)
y, *z = tup
def unpack1(l : List[int]) -> None:
*v1, v2, v3 = l
def unpack2(l : List[int]) -> None:
v1, *v2, v3 = l
def unpack3(l : List[int]) -> None:
v1, v2, *v3 = l
[file driver.py]
from native import a, b, c, d, e, f, j, k, l, m, n, o, p, q, r, s, t, y, z
from native import unpack1, unpack2, unpack3
from testutil import assertRaises
assert a == 1
assert b == [2,3,4,5]
assert c == [1,2,3,4]
assert d == 5
assert e == 1
assert f == [2]
assert j == 1
assert k == [2]
assert l == 3
assert m == 1
assert n == [2,3,4,5]
assert o == 6
assert p == 1
assert q == 2
assert r == 3
assert s == [4,5,6,7,8,9]
assert t == 10
assert y == 1
assert z == [2,3]
with assertRaises(ValueError, "not enough values to unpack"):
unpack1([1])
with assertRaises(ValueError, "not enough values to unpack"):
unpack2([1])
with assertRaises(ValueError, "not enough values to unpack"):
unpack3([1])
[out]
[case testModuleTopLevel]
x = 1
print(x)
def f() -> None:
print(x + 1)
def g() -> None:
global x
x = 77
[file driver.py]
import native
native.f()
native.x = 5
native.f()
native.g()
print(native.x)
[out]
1
2
6
77
[case testExceptionAtModuleTopLevel]
from typing import Any
def f(x: int) -> None: pass
y: Any = ''
f(y)
[file driver.py]
import traceback
try:
import native
except TypeError:
traceback.print_exc()
else:
assert False
[out]
Traceback (most recent call last):
File "driver.py", line 3, in <module>
import native
File "native.py", line 6, in <module>
f(y)
TypeError: int object expected; got str
[case testComprehensions]
# A list comprehension
l = [str(x) + " " + str(y) + " " + str(x*y) for x in range(10)
if x != 6 if x != 5 for y in range(x) if y*x != 8]
# Test short-circuiting as well
def pred(x: int) -> bool:
if x > 6:
raise Exception()
return x > 3
# If we fail to short-circuit, pred(x) will be called with x=7
# eventually and will raise an exception.
l2 = [x for x in range(10) if x <= 6 if pred(x)]
# A dictionary comprehension
d = {k: k*k for k in range(10) if k != 5 if k != 6}
# A set comprehension
s = {str(x) + " " + str(y) + " " + str(x*y) for x in range(10)
if x != 6 if x != 5 for y in range(x) if y*x != 8}
[file driver.py]
from native import l, l2, d, s
for a in l:
print(a)
print(tuple(l2))
for k in sorted(d):
print(k, d[k])
for a in sorted(s):
print(a)
[out]
1 0 0
2 0 0
2 1 2
3 0 0
3 1 3
3 2 6
4 0 0
4 1 4
4 3 12
7 0 0
7 1 7
7 2 14
7 3 21
7 4 28
7 5 35
7 6 42
8 0 0
8 2 16
8 3 24
8 4 32
8 5 40
8 6 48
8 7 56
9 0 0
9 1 9
9 2 18
9 3 27
9 4 36
9 5 45
9 6 54
9 7 63
9 8 72
(4, 5, 6)
0 0
1 1
2 4
3 9
4 16
7 49
8 64
9 81
1 0 0
2 0 0
2 1 2
3 0 0
3 1 3
3 2 6
4 0 0
4 1 4
4 3 12
7 0 0
7 1 7
7 2 14
7 3 21
7 4 28
7 5 35
7 6 42
8 0 0
8 2 16
8 3 24
8 4 32
8 5 40
8 6 48
8 7 56
9 0 0
9 1 9
9 2 18
9 3 27
9 4 36
9 5 45
9 6 54
9 7 63
9 8 72
[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 testDel]
from typing import List
from testutil import assertRaises
def printDict(dict) -> None:
l = list(dict.keys()) # type: List[str]
l.sort()
for key in l:
print(key, dict[key])
print("#########")
def delList() -> None:
l = [1, 2, 3]
print(tuple(l))
del l[1]
print(tuple(l))
def delDict() -> None:
d = {"one":1, "two":2}
printDict(d)
del d["one"]
printDict(d)
def delListMultiple() -> None:
l = [1, 2, 3, 4, 5, 6, 7]
print(tuple(l))
del l[1], l[2], l[3]
print(tuple(l))
def delDictMultiple() -> None:
d = {"one":1, "two":2, "three":3, "four":4}
printDict(d)
del d["two"], d["four"]
printDict(d)
class Dummy():
def __init__(self, x: int, y: int) -> None:
self.x = x
self.y = y
def delAttribute() -> None:
dummy = Dummy(1, 2)
del dummy.x
with assertRaises(AttributeError):
dummy.x
def delAttributeMultiple() -> None:
dummy = Dummy(1, 2)
del dummy.x, dummy.y
with assertRaises(AttributeError):
dummy.x
with assertRaises(AttributeError):
dummy.y
def delLocal(b: bool) -> int:
dummy = 10
if b:
del dummy
return dummy
def delLocalLoop() -> None:
# Try deleting a local in a loop to make sure the control flow analysis works
dummy = 1
for i in range(10):
print(dummy)
dummy *= 2
if i == 4:
del dummy
global_var = 10
del global_var
[file driver.py]
from native import (
delList, delDict, delListMultiple, delDictMultiple, delAttribute,
delAttributeMultiple, delLocal, delLocalLoop,
)
import native
from testutil import assertRaises
delList()
delDict()
delListMultiple()
delDictMultiple()
delAttribute()
delAttributeMultiple()
with assertRaises(AttributeError):
native.global_var
with assertRaises(NameError, "local variable 'dummy' referenced before assignment"):
delLocal(True)
assert delLocal(False) == 10
with assertRaises(NameError, "local variable 'dummy' referenced before assignment"):
delLocalLoop()
[out]
(1, 2, 3)
(1, 3)
one 1
two 2
#########
two 2
#########
(1, 2, 3, 4, 5, 6, 7)
(1, 3, 5, 7)
four 4
one 1
three 3
two 2
#########
one 1
three 3
#########
1
2
4
8
16
[case testProperty]
from typing import Callable
from mypy_extensions import trait
class Temperature:
@property
def celsius(self) -> float:
return 5.0 * (self.farenheit - 32.0) / 9.0
def __init__(self, farenheit: float) -> None:
self.farenheit = farenheit
def print_temp(self) -> None:
print("F:", self.farenheit, "C:", self.celsius)
@property
def rankine(self) -> float:
raise NotImplementedError
class Access:
@property
def number_of_accesses(self) -> int:
self._count += 1
return self._count
def __init__(self) -> None:
self._count = 0
from typing import Callable
class BaseProperty:
@property
def doc(self) -> str:
return "Represents a sequence of values. Updates itself by next, which is a new value."
@property
def value(self) -> object:
return self._incrementer
@property
def bad_value(self) -> object:
return self._incrementer
@property
def next(self) -> BaseProperty:
return BaseProperty(self._incrementer + 1)
def __init__(self, value: int) -> None:
self._incrementer = value
class DerivedProperty(BaseProperty):
@property
def value(self) -> int:
return self._incrementer
@property
def bad_value(self) -> object:
return self._incrementer
def __init__(self, incr_func: Callable[[int], int], value: int) -> None:
BaseProperty.__init__(self, value)
self._incr_func = incr_func
@property
def next(self) -> DerivedProperty:
return DerivedProperty(self._incr_func, self._incr_func(self.value))
class AgainProperty(DerivedProperty):
@property
def next(self) -> AgainProperty:
return AgainProperty(self._incr_func, self._incr_func(self._incr_func(self.value)))
@property
def bad_value(self) -> int:
return self._incrementer
def print_first_n(n: int, thing: BaseProperty) -> None:
vals = []
cur_thing = thing
for _ in range(n):
vals.append(cur_thing.value)
cur_thing = cur_thing.next
print ('', vals)
@trait
class Trait:
@property
def value(self) -> int:
return 3
class Printer(Trait):
def print_value(self) -> None:
print(self.value)
[file driver.py]
from native import Temperature, Access
import traceback
x = Temperature(32.0)
try:
print (x.rankine)
except NotImplementedError as e:
traceback.print_exc()
print (x.celsius)
x.print_temp()
y = Temperature(212.0)
print (y.celsius)
y.print_temp()
z = Access()
print (z.number_of_accesses)
print (z.number_of_accesses)
print (z.number_of_accesses)
print (z.number_of_accesses)
from native import BaseProperty, DerivedProperty, AgainProperty, print_first_n
a = BaseProperty(7)
b = DerivedProperty((lambda x: x // 2 if (x % 2 == 0) else 3 * x + 1), 7)
c = AgainProperty((lambda x: x // 2 if (x % 2 == 0) else 3 * x + 1), 7)
def py_print_first_n(n: int, thing: BaseProperty) -> None:
vals = []
cur_thing = thing
for _ in range(n):
vals.append(cur_thing.value)
cur_thing = cur_thing.next
print ('', vals)
py_print_first_n(20, a)
py_print_first_n(20, b)
py_print_first_n(20, c)
print(a.next.next.next.bad_value)
print(b.next.next.next.bad_value)
print(c.next.next.next.bad_value)
print_first_n(20, a)
print_first_n(20, b)
print_first_n(20, c)
print (a.doc)
print (b.doc)
print (c.doc)
from native import Printer
Printer().print_value()
print (Printer().value)
[out]
Traceback (most recent call last):
File "driver.py", line 5, in <module>
print (x.rankine)
File "native.py", line 16, in rankine
raise NotImplementedError
NotImplementedError
0.0
F: 32.0 C: 0.0
100.0
F: 212.0 C: 100.0
1
2
3
4
[7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1]
[7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4]
10
34
26
[7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]
[7, 22, 11, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1, 4, 2, 1]
[7, 11, 17, 26, 40, 10, 16, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4, 1, 2, 4]
Represents a sequence of values. Updates itself by next, which is a new value.
Represents a sequence of values. Updates itself by next, which is a new value.
Represents a sequence of values. Updates itself by next, which is a new value.
3
3
[case testPropertySetters]
from mypy_extensions import trait
class Foo():
def __init__(self) -> None:
self.attr = "unmodified"
class A:
def __init__(self) -> None:
self._x = 0
self._foo = Foo()
@property
def x(self) -> int:
return self._x
@x.setter
def x(self, val : int) -> None:
self._x = val
@property
def foo(self) -> Foo:
return self._foo
@foo.setter
def foo(self, val : Foo) -> None:
self._foo = val
# Overrides base property setters and getters
class B(A):
def __init__(self) -> None:
self._x = 10
@property
def x(self) -> int:
return self._x + 1
@x.setter
def x(self, val : int) -> None:
self._x = val + 1
#Inerits base property setters and getters
class C(A):
def __init__(self) -> None:
A.__init__(self)
@trait
class D():
def __init__(self) -> None:
self._x = 0
@property
def x(self) -> int:
return self._x
@x.setter
def x(self, val : int) -> None:
self._x = val
#Inherits trait property setters and getters
class E(D):
def __init__(self) -> None:
D.__init__(self)
#Overrides trait property setters and getters
class F(D):
def __init__(self) -> None:
self._x = 10
@property
def x(self) -> int:
return self._x + 10
@x.setter
def x(self, val : int) -> None:
self._x = val + 10
# # Property setter and getter are subtypes of base property setters and getters
# # class G(A):
# # def __init__(self) -> None:
# # A.__init__(self)
# # @property
# # def y(self) -> int:
# # return self._y
# # @y.setter
# # def y(self, val : object) -> None:
# # self._y = val
[file other.py]
# Run in both interpreted and compiled mode
from native import A, B, C, D, E, F
a = A()
assert a.x == 0
assert a._x == 0
a.x = 1
assert a.x == 1
assert a._x == 1
a._x = 0
assert a.x == 0
assert a._x == 0
b = B()
assert b.x == 11
assert b._x == 10
b.x = 11
assert b.x == 13
b._x = 11
assert b.x == 12
c = C()
assert c.x == 0
c.x = 1000
assert c.x == 1000
e = E()
assert e.x == 0
e.x = 1000
assert e.x == 1000
f = F()
assert f.x == 20
f.x = 30
assert f.x == 50
[file driver.py]
# Run the tests in both interpreted and compiled mode
import other
import other_interpreted
[out]
[case testDunders]
from typing import Any
class Item:
def __init__(self, value: str) -> None:
self.value = value
def __hash__(self) -> int:
return hash(self.value)
def __eq__(self, rhs: object) -> bool:
return isinstance(rhs, Item) and self.value == rhs.value
def __lt__(self, x: 'Item') -> bool:
return self.value < x.value
class Subclass1(Item):
def __bool__(self) -> bool:
return bool(self.value)
class NonBoxedThing:
def __getitem__(self, index: Item) -> Item:
return Item("2 * " + index.value + " + 1")
class BoxedThing:
def __getitem__(self, index: int) -> int:
return 2 * index + 1
class Subclass2(BoxedThing):
pass
def index_into(x : Any, y : Any) -> Any:
return x[y]
def internal_index_into() -> None:
x = BoxedThing()
print (x[3])
y = NonBoxedThing()
z = Item("3")
print(y[z].value)
def is_truthy(x: Item) -> bool:
return True if x else False
[file driver.py]
from native import *
x = BoxedThing()
y = 3
print(x[y], index_into(x, y))
x = Subclass2()
y = 3
print(x[y], index_into(x, y))
z = NonBoxedThing()
w = Item("3")
print(z[w].value, index_into(z, w).value)
i1 = Item('lolol')
i2 = Item('lol' + 'ol')
i3 = Item('xyzzy')
assert hash(i1) == hash(i2)
assert i1 == i2
assert not i1 != i2
assert not i1 == i3
assert i1 != i3
assert i2 < i3
assert not i1 < i2
assert i1 == Subclass1('lolol')
assert is_truthy(Item(''))
assert is_truthy(Item('a'))
assert not is_truthy(Subclass1(''))
assert is_truthy(Subclass1('a'))
internal_index_into()
[out]
7 7
7 7
2 * 3 + 1 2 * 3 + 1
7
2 * 3 + 1
[case testDummyTypes]
from typing import Tuple, List, Dict, NamedTuple
from typing_extensions import Literal, TypedDict, NewType
class A:
pass
T = List[A]
U = List[Tuple[int, str]]
Z = List[List[int]]
D = Dict[int, List[int]]
N = NewType('N', int)
G = Tuple[int, str]
def foo(x: N) -> int:
return x
foo(N(10))
z = N(10)
Lol = NamedTuple('Lol', (('a', int), ('b', T)))
x = Lol(1, [])
def take_lol(x: Lol) -> int:
return x.a
TD = TypedDict('TD', {'a': int})
def take_typed_dict(x: TD) -> int:
return x['a']
def take_literal(x: Literal[1, 2, 3]) -> None:
print(x)
[file driver.py]
import sys
from native import *
if sys.version_info[:3] > (3, 5, 2):
assert "%s %s %s %s" % (T, U, Z, D) == "typing.List[native.A] typing.List[typing.Tuple[int, str]] typing.List[typing.List[int]] typing.Dict[int, typing.List[int]]"
print(x)
print(z)
print(take_lol(x))
print(take_typed_dict({'a': 20}))
try:
take_typed_dict(None)
except Exception as e:
print(type(e).__name__)
take_literal(1)
# We check that the type is the real underlying type
try:
take_literal(None)
except Exception as e:
print(type(e).__name__)
# ... but not that it is a valid literal value
take_literal(10)
[out]
Lol(a=1, b=[])
10
1
20
TypeError
1
TypeError
10
[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 testUnion]
from typing import Union
class A:
def __init__(self, x: int) -> None:
self.x = x
def f(self, y: int) -> int:
return y + self.x
class B:
def __init__(self, x: object) -> None:
self.x = x
def f(self, y: object) -> object:
return y
def f(x: Union[A, str]) -> object:
if isinstance(x, A):
return x.x
else:
return x + 'x'
def g(x: int) -> Union[A, int]:
if x == 0:
return A(1)
else:
return x + 1
def get(x: Union[A, B]) -> object:
return x.x
def call(x: Union[A, B]) -> object:
return x.f(5)
[file driver.py]
from native import A, B, f, g, get, call
assert f('a') == 'ax'
assert f(A(4)) == 4
assert isinstance(g(0), A)
assert g(2) == 3
assert get(A(5)) == 5
assert get(B('x')) == 'x'
assert call(A(4)) == 9
assert call(B('x')) == 5
try:
f(1)
except TypeError:
pass
else:
assert False
[case testYield]
from typing import Generator, Iterable, Union, Tuple
def yield_three_times() -> Iterable[int]:
yield 1
yield 2
yield 3
def yield_twice_and_return() -> Generator[int, None, int]:
yield 1
yield 2
return 4
def yield_while_loop() -> Generator[int, None, int]:
i = 0
while i < 5:
if i == 3:
return i
yield i
i += 1
return -1
def yield_for_loop() -> Iterable[int]:
l = [i for i in range(3)]
for i in l:
yield i
d = {k: None for k in range(3)}
for k in d:
yield k
for i in range(3):
yield i
for i in range(three()):
yield i
def yield_with_except() -> Generator[int, None, None]:
yield 10
try:
return
except:
print('Caught exception inside generator function')
def complex_yield(a: int, b: str, c: float) -> Generator[Union[str, int], None, float]:
x = 2
while x < a:
if x % 2 == 0:
dummy_var = 1
yield str(x) + ' ' + b
dummy_var = 1
else:
dummy_var = 1
yield x
dummy_var = 1
x += 1
return c
def yield_with_default(x: bool = False) -> Iterable[int]:
if x:
yield 0
def three() -> int:
return 3
class A(object):
def __init__(self, x: int) -> None:
self.x = x
def generator(self) -> Iterable[int]:
yield self.x
def return_tuple() -> Generator[int, None, Tuple[int, int]]:
yield 0
return 1, 2
[file driver.py]
from native import yield_three_times, yield_twice_and_return, yield_while_loop, yield_for_loop, yield_with_except, complex_yield, yield_with_default, A, return_tuple
from testutil import run_generator
assert run_generator(yield_three_times()) == ((1, 2, 3), None)
assert run_generator(yield_twice_and_return()) == ((1, 2), 4)
assert run_generator(yield_while_loop()) == ((0, 1, 2), 3)
assert run_generator(yield_for_loop()) == (tuple(4 * [i for i in range(3)]), None)
assert run_generator(yield_with_except()) == ((10,), None)
assert run_generator(complex_yield(5, 'foo', 1.0)) == (('2 foo', 3, '4 foo'), 1.0)
assert run_generator(yield_with_default()) == ((), None)
assert run_generator(A(0).generator()) == ((0,), None)
assert run_generator(return_tuple()) == ((0,), (1, 2))
for i in yield_twice_and_return():
print(i)
for i in yield_while_loop():
print(i)
[out]
1
2
0
1
2
[case testYieldTryFinallyWith]
from typing import Generator, Any
class Thing:
def __init__(self, x: str) -> None:
self.x = x
def __enter__(self) -> str:
print('enter!', self.x)
if self.x == 'crash':
raise Exception('ohno')
return self.x
def __exit__(self, x: Any, y: Any, z: Any) -> None:
print('exit!', self.x, y)
def yield_try_finally() -> Generator[int, None, str]:
try:
yield 1
yield 2
return 'lol'
except Exception:
raise
finally:
print('goodbye!')
def yield_with(i: int) -> Generator[int, None, int]:
with Thing('a') as x:
yield 1
print("yooo?", x)
if i == 0:
yield 2
return 10
elif i == 1:
raise Exception('exception!')
return -1
[file driver.py]
from native import yield_try_finally, yield_with
from testutil import run_generator
print(run_generator(yield_try_finally(), p=True))
print(run_generator(yield_with(0), p=True))
print(run_generator(yield_with(1), p=True))
[out]
1
2
goodbye!
((1, 2), 'lol')
enter! a
1
yooo? a
2
exit! a None
((1, 2), 10)
enter! a
1
yooo? a
exit! a exception!
((1,), 'exception!')
[case testYieldNested]
from typing import Callable, Generator
def normal(a: int, b: float) -> Callable:
def generator(x: int, y: str) -> Generator:
yield a
yield b
yield x
yield y
return generator
def generator(a: int) -> Generator:
def normal(x: int) -> int:
return a + x
for i in range(3):
yield normal(i)
def triple() -> Callable:
def generator() -> Generator:
x = 0
def inner() -> int:
x += 1
return x
while x < 3:
yield inner()
return generator
def another_triple() -> Callable:
def generator() -> Generator:
x = 0
def inner_generator() -> Generator:
x += 1
yield x
yield next(inner_generator())
return generator
def outer() -> Generator:
def recursive(n: int) -> Generator:
if n < 10:
for i in range(n):
yield i
return
for i in recursive(5):
yield i
return recursive(10)
[file driver.py]
from native import normal, generator, triple, another_triple, outer
from testutil import run_generator
assert run_generator(normal(1, 2.0)(3, '4.00')) == ((1, 2.0, 3, '4.00'), None)
assert run_generator(generator(1)) == ((1, 2, 3), None)
assert run_generator(triple()()) == ((1, 2, 3), None)
assert run_generator(another_triple()()) == ((1,), None)
assert run_generator(outer()) == ((0, 1, 2, 3, 4), None)
[case testYieldThrow]
from typing import Generator, Iterable, Any
from traceback import print_tb
from contextlib import contextmanager
import wrapsys
def generator() -> Iterable[int]:
try:
yield 1
yield 2
yield 3
except Exception as e:
print_tb(wrapsys.exc_info()[2])
s = str(e)
if s:
print('caught exception with value ' + s)
else:
print('caught exception without value')
return 0
def no_except() -> Iterable[int]:
yield 1
yield 2
def raise_something() -> Iterable[int]:
yield 1
yield 2
raise Exception('failure')
def wrapper(x: Any) -> Any:
return (yield from x)
def foo() -> Generator[int, None, None]:
try:
yield 1
except Exception as e:
print(str(e))
finally:
print('goodbye')
ctx_manager = contextmanager(foo)
[file wrapsys.py]
# This is a gross hack around some limitations of the test system/mypyc.
from typing import Any
import sys
def exc_info() -> Any:
return sys.exc_info() # type: ignore
[file driver.py]
import sys
from typing import Generator, Tuple, TypeVar, Sequence
from native import generator, ctx_manager, wrapper, no_except, raise_something
T = TypeVar('T')
U = TypeVar('U')
def run_generator_and_throw(gen: Generator[T, None, U],
num_times: int,
value: object = None,
traceback: object = None) -> Tuple[Sequence[T], U]:
res = []
try:
for i in range(num_times):
res.append(next(gen))
if value is not None and traceback is not None:
gen.throw(Exception, value, traceback)
elif value is not None:
gen.throw(Exception, value)
else:
gen.throw(Exception)
except StopIteration as e:
return (tuple(res), e.value)
except Exception as e:
return (tuple(res), str(e))
assert run_generator_and_throw(generator(), 0, 'hello') == ((), 'hello')
assert run_generator_and_throw(generator(), 3) == ((1, 2, 3), 0)
assert run_generator_and_throw(generator(), 2, 'some string') == ((1, 2), 0)
try:
raise Exception
except Exception as e:
tb = sys.exc_info()[2]
assert run_generator_and_throw(generator(), 1, 'some other string', tb) == ((1,), 0)
assert run_generator_and_throw(wrapper(generator()), 0, 'hello') == ((), 'hello')
assert run_generator_and_throw(wrapper(generator()), 3) == ((1, 2, 3), 0)
assert run_generator_and_throw(wrapper(generator()), 2, 'some string') == ((1, 2), 0)
# Make sure we aren't leaking exc_info
assert sys.exc_info()[0] is None
assert run_generator_and_throw(wrapper([1, 2, 3]), 3, 'lol') == ((1, 2, 3), 'lol')
assert run_generator_and_throw(wrapper(no_except()), 2, 'lol') == ((1, 2), 'lol')
assert run_generator_and_throw(wrapper(raise_something()), 3) == ((1, 2), 'failure')
with ctx_manager() as c:
raise Exception('exception')
[out]
File "native.py", line 10, in generator
yield 3
File "native.py", line 9, in generator
yield 2
File "native.py", line 8, in generator
yield 1
File "driver.py", line 31, in <module>
raise Exception
File "native.py", line 10, in generator
yield 3
File "native.py", line 30, in wrapper
return (yield from x)
File "native.py", line 9, in generator
yield 2
File "native.py", line 30, in wrapper
return (yield from x)
caught exception without value
caught exception with value some string
caught exception with value some other string
caught exception without value
caught exception with value some string
exception
goodbye
[case testYieldSend]
from typing import Generator
def basic() -> Generator[int, int, int]:
x = yield 1
y = yield (x + 1)
return y
def use_from() -> Generator[int, int, int]:
return (yield from basic())
[file driver.py]
from native import basic, use_from
from testutil import run_generator
assert run_generator(basic(), [5, 50]) == ((1, 6), 50)
assert run_generator(use_from(), [5, 50]) == ((1, 6), 50)
[case testYieldFrom]
from typing import Generator, Iterator, List
def basic() -> Iterator[int]:
yield from [1, 2, 3]
def call_next() -> int:
x = [] # type: List[int]
return next(iter(x))
def inner(b: bool) -> Generator[int, None, int]:
if b:
yield from [1, 2, 3]
return 10
def with_return(b: bool) -> Generator[int, None, int]:
x = yield from inner(b)
for a in [1, 2]:
pass
return x
[file driver.py]
from native import basic, call_next, with_return
from testutil import run_generator, assertRaises
assert run_generator(basic()) == ((1, 2, 3), None)
with assertRaises(StopIteration):
call_next()
assert run_generator(with_return(True)) == ((1, 2, 3), 10)
assert run_generator(with_return(False)) == ((), 10)
[case testDecorators1]
from typing import Generator, Callable, Iterator
from contextlib import contextmanager
def a(f: Callable[[], None]) -> Callable[[], None]:
def g() -> None:
print('Entering')
f()
print('Exited')
return g
def b(f: Callable[[], None]) -> Callable[[], None]:
def g() -> None:
print('***')
f()
print('***')
return g
@contextmanager
def foo() -> Iterator[int]:
try:
print('started')
yield 0
finally:
print('finished')
@contextmanager
def catch() -> Iterator[None]:
try:
print('started')
yield
except IndexError:
print('index')
raise
except Exception:
print('lol')
def thing() -> None:
c()
@a
@b
def c() -> None:
@a
@b
def d() -> None:
print('d')
print('c')
d()
def hm() -> None:
x = [1]
with catch():
x[2]
[file driver.py]
from native import foo, c, thing, hm
with foo() as f:
print('hello')
c()
thing()
print('==')
try:
hm()
except IndexError:
pass
else:
assert False
[out]
started
hello
finished
Entering
***
c
Entering
***
d
***
Exited
***
Exited
Entering
***
c
Entering
***
d
***
Exited
***
Exited
==
started
index
[case testDecoratorsMethods]
from typing import Any, Callable, Iterator
from contextlib import contextmanager
def a(f: Callable[[Any], None]) -> Callable[[Any], None]:
def g(a: Any) -> None:
print('Entering')
f(a)
print('Exited')
return g
class A:
@a
def foo(self) -> None:
print('foo')
@contextmanager
def generator(self) -> Iterator[int]:
try:
print('contextmanager: entering')
yield 0
finally:
print('contextmanager: exited')
def inside() -> None:
with A().generator() as g:
print('hello!')
with A().generator() as g:
print('hello!')
def lol() -> None:
with A().generator() as g:
raise Exception
[file driver.py]
from native import A, lol
A.foo(A())
A().foo()
with A().generator() as g:
print('hello!')
try:
lol()
except:
pass
else:
assert False
[out]
contextmanager: entering
hello!
contextmanager: exited
Entering
foo
Exited
Entering
foo
Exited
contextmanager: entering
hello!
contextmanager: exited
contextmanager: entering
contextmanager: exited
[case testAnyAll]
from typing import Iterable
def call_any_nested(l: Iterable[Iterable[int]], val: int = 0) -> int:
res = any(i == val for l2 in l for i in l2)
return 0 if res else 1
def call_any(l: Iterable[int], val: int = 0) -> int:
res = any(i == val for i in l)
return 0 if res else 1
def call_all(l: Iterable[int], val: int = 0) -> int:
res = all(i == val for i in l)
return 0 if res else 1
[file driver.py]
from native import call_any, call_all, call_any_nested
zeros = [0, 0, 0]
ones = [1, 1, 1]
mixed_001 = [0, 0, 1]
mixed_010 = [0, 1, 0]
mixed_100 = [1, 0, 0]
mixed_011 = [0, 1, 1]
mixed_101 = [1, 0, 1]
mixed_110 = [1, 1, 0]
assert call_any([]) == 1
assert call_any(zeros) == 0
assert call_any(ones) == 1
assert call_any(mixed_001) == 0
assert call_any(mixed_010) == 0
assert call_any(mixed_100) == 0
assert call_any(mixed_011) == 0
assert call_any(mixed_101) == 0
assert call_any(mixed_110) == 0
assert call_all([]) == 0
assert call_all(zeros) == 0
assert call_all(ones) == 1
assert call_all(mixed_001) == 1
assert call_all(mixed_010) == 1
assert call_all(mixed_100) == 1
assert call_all(mixed_011) == 1
assert call_all(mixed_101) == 1
assert call_all(mixed_110) == 1
assert call_any_nested([[1, 1, 1], [1, 1], []]) == 1
assert call_any_nested([[1, 1, 1], [0, 1], []]) == 0
[case testNextGenerator]
from typing import Iterable
def f(x: int) -> int:
print(x)
return x
def call_next_loud(l: Iterable[int], val: int) -> int:
return next(i for i in l if f(i) == val)
def call_next_default(l: Iterable[int], val: int) -> int:
return next((i*2 for i in l if i == val), -1)
def call_next_default_list(l: Iterable[int], val: int) -> int:
return next((i*2 for i in l if i == val), -1)
[file driver.py]
from native import call_next_loud, call_next_default, call_next_default_list
from testutil import assertRaises
assert call_next_default([0, 1, 2], 0) == 0
assert call_next_default([0, 1, 2], 1) == 2
assert call_next_default([0, 1, 2], 2) == 4
assert call_next_default([0, 1, 2], 3) == -1
assert call_next_default([], 0) == -1
assert call_next_default_list([0, 1, 2], 0) == 0
assert call_next_default_list([0, 1, 2], 1) == 2
assert call_next_default_list([0, 1, 2], 2) == 4
assert call_next_default_list([0, 1, 2], 3) == -1
assert call_next_default_list([], 0) == -1
assert call_next_loud([0, 1, 2], 0) == 0
assert call_next_loud([0, 1, 2], 1) == 1
assert call_next_loud([0, 1, 2], 2) == 2
with assertRaises(StopIteration):
call_next_loud([42], 3)
with assertRaises(StopIteration):
call_next_loud([], 3)
[out]
0
0
1
0
1
2
42
[case testGeneratorSuper]
from typing import Iterator, Callable, Any
class A():
def testA(self) -> int:
return 2
class B(A):
def testB(self) -> Iterator[int]:
x = super().testA()
while True:
yield x
def testAsserts():
b = B()
b_gen = b.testB()
assert next(b_gen) == 2
[file driver.py]
from native import testAsserts
testAsserts()
[case testAssignModule]
import a
assert a.x == 20
a.x = 10
[file a.py]
x = 20
[file driver.py]
import native
[case testNoneStuff]
from typing import Optional
class A:
x: int
def lol(x: A) -> None:
setattr(x, 'x', 5)
def none() -> None:
return
def arg(x: Optional[A]) -> bool:
return x is None
[file driver.py]
import native
native.lol(native.A())
# Catch refcounting failures
for i in range(10000):
native.none()
native.arg(None)
[case testBorrowRefs]
def make_garbage(arg: object) -> None:
b = True
while b:
arg = None
b = False
[file driver.py]
from native import make_garbage
import sys
def test():
x = object()
r0 = sys.getrefcount(x)
make_garbage(x)
r1 = sys.getrefcount(x)
assert r0 == r1
test()
[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 testFinalStaticRunFail]
if False:
from typing import Final
if bool():
x: 'Final' = [1]
def f() -> int:
return x[0]
[file driver.py]
from native import f
try:
print(f())
except ValueError as e:
print(e.args[0])
[out]
value for final name "x" was not set
[case testFinalStaticRunListTupleInt]
if False:
from typing import Final
x: 'Final' = [1]
y: 'Final' = (1, 2)
z: 'Final' = 1 + 1
def f() -> int:
return x[0]
def g() -> int:
return y[0]
def h() -> int:
return z - 1
[file driver.py]
from native import f, g, h, x, y, z
print(f())
print(x[0])
print(g())
print(y)
print(h())
print(z)
[out]
1
1
1
(1, 2)
1
2
[case testUnannotatedFunction]
def g(x: int) -> int:
return x * 2
def f(x):
return g(x)
[file driver.py]
from native import f
assert f(3) == 6
[case testCheckVersion]
import sys
# We lie about the version we are running in tests if it is 3.5, so
# that hits a crash case.
if sys.version_info[:2] == (3, 8):
def version() -> int:
return 8
elif sys.version_info[:2] == (3, 7):
def version() -> int:
return 7
elif sys.version_info[:2] == (3, 6):
def version() -> int:
return 6
else:
raise Exception("we don't support this version yet!")
[file driver.py]
import sys
version = sys.version_info[:2]
try:
import native
assert version != (3, 5), "3.5 should fail!"
assert native.version() == sys.version_info[1]
except RuntimeError:
assert version == (3, 5), "only 3.5 should fail!"
[case testNameClashIssues]
class A:
def foo(self) -> object:
yield
class B:
def foo(self) -> object:
yield
class C:
def foo(self) -> None:
def bar(self) -> None:
pass
class D:
def foo(self) -> None:
def bar(self) -> None:
pass
class E:
default: int
switch: int
[file driver.py]
# really I only care it builds
[case testTupleUnionFail]
# Test that order is irrelevant to unions
from typing import Optional, Tuple
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
[file driver.py]
# really I only care it builds
[case testDictFree]
# Test that we garbage collect stuff with __dict__ right!
from typing import Optional, Any, Dict, Generic, List
from base import Base
class A(Base):
z: Any
def make_garbage(x: List[str]) -> None:
a = A()
b = A()
a.x = b
b.x = a
a.y = [1,2,3,4,5]
[file base.py]
class Base:
x = None # type: object
y = None # type: object
[file driver.py]
from native import make_garbage
import gc
def test():
gc.collect(2)
x = len(gc.get_objects())
make_garbage([1,2,3,4])
gc.collect(2)
y = len(gc.get_objects())
assert x == y
test()
[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 testComplicatedArgs]
from typing import Tuple, Dict
def kwonly1(x: int = 0, *, y: int) -> Tuple[int, int]:
return x, y
def kwonly2(*, x: int = 0, y: int) -> Tuple[int, int]:
return x, y
def kwonly3(a: int, b: int = 0, *, y: int, x: int = 1) -> Tuple[int, int, int, int]:
return a, b, x, y
def kwonly4(*, x: int, y: int) -> Tuple[int, int]:
return x, y
def varargs1(*args: int) -> Tuple[int, ...]:
return args
def varargs2(*args: int, **kwargs: int) -> Tuple[Tuple[int, ...], Dict[str, int]]:
return args, kwargs
def varargs3(**kwargs: int) -> Dict[str, int]:
return kwargs
def varargs4(a: int, b: int = 0,
*args: int, y: int, x: int = 1,
**kwargs: int) -> Tuple[Tuple[int, ...], Dict[str, int]]:
return (a, b, *args), {'x': x, 'y': y, **kwargs}
class A:
def f(self, x: int) -> Tuple[int, ...]:
return (x,)
def g(self, x: int) -> Tuple[Tuple[int, ...], Dict[str, int]]:
return (x,), {}
class B(A):
def f(self, *args: int) -> Tuple[int, ...]:
return args
def g(self, *args: int, **kwargs: int) -> Tuple[Tuple[int, ...], Dict[str, int]]:
return args, kwargs
[file other.py]
# This file is imported in both compiled and interpreted mode in order to
# test both native calls and calls via the C API.
from native import (
kwonly1, kwonly2, kwonly3, kwonly4,
varargs1, varargs2, varargs3, varargs4,
A, B
)
# kwonly arg tests
assert kwonly1(10, y=20) == (10, 20)
assert kwonly1(y=20) == (0, 20)
assert kwonly2(x=10, y=20) == (10, 20)
assert kwonly2(y=20) == (0, 20)
assert kwonly3(10, y=20) == (10, 0, 1, 20)
assert kwonly3(a=10, y=20) == (10, 0, 1, 20)
assert kwonly3(10, 30, y=20) == (10, 30, 1, 20)
assert kwonly3(10, b=30, y=20) == (10, 30, 1, 20)
assert kwonly3(a=10, b=30, y=20) == (10, 30, 1, 20)
assert kwonly3(10, x=40, y=20) == (10, 0, 40, 20)
assert kwonly3(a=10, x=40, y=20) == (10, 0, 40, 20)
assert kwonly3(10, 30, x=40, y=20) == (10, 30, 40, 20)
assert kwonly3(10, b=30, x=40, y=20) == (10, 30, 40, 20)
assert kwonly3(a=10, b=30, x=40, y=20) == (10, 30, 40, 20)
assert kwonly4(x=1, y=2) == (1, 2)
assert kwonly4(y=2, x=1) == (1, 2)
# varargs tests
assert varargs1() == ()
assert varargs1(1, 2, 3) == (1, 2, 3)
assert varargs2(1, 2, 3) == ((1, 2, 3), {})
assert varargs2(1, 2, 3, x=4) == ((1, 2, 3), {'x': 4})
assert varargs2(x=4) == ((), {'x': 4})
assert varargs3() == {}
assert varargs3(x=4) == {'x': 4}
assert varargs3(x=4, y=5) == {'x': 4, 'y': 5}
assert varargs4(-1, y=2) == ((-1, 0), {'x': 1, 'y': 2})
assert varargs4(-1, 2, y=2) == ((-1, 2), {'x': 1, 'y': 2})
assert varargs4(-1, 2, 3, y=2) == ((-1, 2, 3), {'x': 1, 'y': 2})
assert varargs4(-1, 2, 3, x=10, y=2) == ((-1, 2, 3), {'x': 10, 'y': 2})
assert varargs4(-1, x=10, y=2) == ((-1, 0), {'x': 10, 'y': 2})
assert varargs4(-1, y=2, z=20) == ((-1, 0), {'x': 1, 'y': 2, 'z': 20})
assert varargs4(-1, 2, y=2, z=20) == ((-1, 2), {'x': 1, 'y': 2, 'z': 20})
assert varargs4(-1, 2, 3, y=2, z=20) == ((-1, 2, 3), {'x': 1, 'y': 2, 'z': 20})
assert varargs4(-1, 2, 3, x=10, y=2, z=20) == ((-1, 2, 3), {'x': 10, 'y': 2, 'z': 20})
assert varargs4(-1, x=10, y=2, z=20) == ((-1, 0), {'x': 10, 'y': 2, 'z': 20})
x = B() # type: A
assert x.f(1) == (1,)
assert x.g(1) == ((1,), {})
# This one is really funny! When we make native calls we lose
# track of which arguments are positional or keyword, so the glue
# calls them all positional unless they are keyword only...
# It would be possible to fix this by dynamically tracking which
# arguments were passed by keyword (for example, by passing a bitmask
# to functions indicating this), but paying a speed, size, and complexity
# cost for something so deeply marginal seems like a bad choice.
# assert x.g(x=1) == ((), {'x': 1})
[file driver.py]
from testutil import assertRaises
from native import (
kwonly1, kwonly2, kwonly3, kwonly4,
varargs1, varargs2, varargs3, varargs4,
)
# Run the non-exceptional tests in both interpreted and compiled mode
import other
import other_interpreted
# And the tests for errors at the interfaces in interpreted only
with assertRaises(TypeError, "missing required keyword-only argument 'y'"):
kwonly1()
with assertRaises(TypeError, "takes at most 1 positional argument (2 given)"):
kwonly1(10, 20)
with assertRaises(TypeError, "missing required keyword-only argument 'y'"):
kwonly2()
with assertRaises(TypeError, "takes no positional arguments"):
kwonly2(10, 20)
with assertRaises(TypeError, "missing required argument 'a'"):
kwonly3(b=30, x=40, y=20)
with assertRaises(TypeError, "missing required keyword-only argument 'y'"):
kwonly3(10)
with assertRaises(TypeError, "missing required keyword-only argument 'y'"):
kwonly4(x=1)
with assertRaises(TypeError, "missing required keyword-only argument 'x'"):
kwonly4(y=1)
with assertRaises(TypeError, "missing required keyword-only argument 'x'"):
kwonly4()
with assertRaises(TypeError, "'x' is an invalid keyword argument for varargs1()"):
varargs1(x=10)
with assertRaises(TypeError, "'x' is an invalid keyword argument for varargs1()"):
varargs1(1, x=10)
with assertRaises(TypeError, "varargs3() takes no positional arguments"):
varargs3(10)
with assertRaises(TypeError, "varargs3() takes no positional arguments"):
varargs3(10, x=10)
with assertRaises(TypeError, "varargs4() missing required argument 'a' (pos 1)"):
varargs4()
with assertRaises(TypeError, "varargs4() missing required keyword-only argument 'y'"):
varargs4(1, 2)
with assertRaises(TypeError, "varargs4() missing required keyword-only argument 'y'"):
varargs4(1, 2, x=1)
with assertRaises(TypeError, "varargs4() missing required keyword-only argument 'y'"):
varargs4(1, 2, 3)
with assertRaises(TypeError, "varargs4() missing required argument 'a' (pos 1)"):
varargs4(y=20)
[case testTypeErrorMessages]
from typing import Tuple
class A:
pass
class B:
pass
def f(x: B) -> None:
pass
def g(x: Tuple[int, A]) -> None:
pass
[file driver.py]
from testutil import assertRaises
from native import A, f, g
class Busted:
pass
Busted.__module__ = None
with assertRaises(TypeError, "int"):
f(0)
with assertRaises(TypeError, "native.A"):
f(A())
with assertRaises(TypeError, "tuple[None, native.A]"):
f((None, A()))
with assertRaises(TypeError, "tuple[tuple[int, str], native.A]"):
f(((1, "ha"), A()))
with assertRaises(TypeError, "tuple[<50 items>]"):
f(tuple(range(50)))
with assertRaises(TypeError, "errored formatting real type!"):
f(Busted())
with assertRaises(TypeError, "tuple[int, native.A] object expected; got tuple[int, int]"):
g((20, 30))
[case testComprehensionShadowBinder]
def foo(x: object) -> object:
if isinstance(x, list):
return tuple(x for x in x), x
return None
[file driver.py]
from native import foo
assert foo(None) == None
assert foo([1, 2, 3]) == ((1, 2, 3), [1, 2, 3])
[case testReexport]
# Test that we properly handle accessing values that have been reexported
import a
def f(x: int) -> int:
return a.g(x) + a.foo + a.b.foo
whatever = a.A()
[file a.py]
from b import g as g, A as A, foo as foo
import b
[file b.py]
def g(x: int) -> int:
return x + 1
class A:
pass
foo = 20
[file driver.py]
from native import f, whatever
import b
assert f(20) == 61
assert isinstance(whatever, b.A)