blob: 1b390e9c35043a8abfc31a8a06e9f7f0896f02d3 [file] [log] [blame] [edit]
[case testNestedFunctions]
from typing import Callable
def a() -> Callable[[], object]:
def inner() -> object:
return None
return inner
def b() -> Callable[[], Callable[[], str]]:
def first() -> Callable[[], str]:
def second() -> str:
return 'b.first.second: nested function'
return second
return first
def c(num: float) -> Callable[[str], str]:
def inner(s: str) -> str:
return s + '!'
return inner
def d(num: float) -> str:
def inner(s: str) -> str:
return s + '?'
a = inner('one')
b = inner('two')
return a
def inner() -> str:
return 'inner: normal function'
def first() -> str:
return 'first: normal function'
def second() -> str:
return 'second: normal function'
[out]
def inner_a_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_a_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_a_obj
r0 :: __main__.a_env
r1 :: object
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = box(None, 1)
return r1
def a():
r0 :: __main__.a_env
r1 :: __main__.inner_a_obj
r2 :: bool
inner :: object
L0:
r0 = a_env()
r1 = inner_a_obj()
r1.__mypyc_env__ = r0; r2 = is_error
inner = r1
return inner
def second_b_first_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def second_b_first_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.second_b_first_obj
r0 :: __main__.first_b_env
r1 :: __main__.b_env
r2 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = r0.__mypyc_env__
r2 = 'b.first.second: nested function'
return r2
def first_b_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def first_b_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.first_b_obj
r0 :: __main__.b_env
r1 :: __main__.first_b_env
r2 :: bool
r3 :: __main__.second_b_first_obj
r4 :: bool
second :: object
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = first_b_env()
r1.__mypyc_env__ = r0; r2 = is_error
r3 = second_b_first_obj()
r3.__mypyc_env__ = r1; r4 = is_error
second = r3
return second
def b():
r0 :: __main__.b_env
r1 :: __main__.first_b_obj
r2 :: bool
first :: object
L0:
r0 = b_env()
r1 = first_b_obj()
r1.__mypyc_env__ = r0; r2 = is_error
first = r1
return first
def inner_c_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_c_obj.__call__(__mypyc_self__, s):
__mypyc_self__ :: __main__.inner_c_obj
s :: str
r0 :: __main__.c_env
r1, r2 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = '!'
r2 = PyUnicode_Concat(s, r1)
return r2
def c(num):
num :: float
r0 :: __main__.c_env
r1 :: __main__.inner_c_obj
r2 :: bool
inner :: object
L0:
r0 = c_env()
r1 = inner_c_obj()
r1.__mypyc_env__ = r0; r2 = is_error
inner = r1
return inner
def inner_d_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_d_obj.__call__(__mypyc_self__, s):
__mypyc_self__ :: __main__.inner_d_obj
s :: str
r0 :: __main__.d_env
r1, r2 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = '?'
r2 = PyUnicode_Concat(s, r1)
return r2
def d(num):
num :: float
r0 :: __main__.d_env
r1 :: __main__.inner_d_obj
r2 :: bool
inner :: object
r3 :: str
r4 :: object[1]
r5 :: object_ptr
r6 :: object
r7, a, r8 :: str
r9 :: object[1]
r10 :: object_ptr
r11 :: object
r12, b :: str
L0:
r0 = d_env()
r1 = inner_d_obj()
r1.__mypyc_env__ = r0; r2 = is_error
inner = r1
r3 = 'one'
r4 = [r3]
r5 = load_address r4
r6 = PyObject_Vectorcall(inner, r5, 1, 0)
keep_alive r3
r7 = cast(str, r6)
a = r7
r8 = 'two'
r9 = [r8]
r10 = load_address r9
r11 = PyObject_Vectorcall(inner, r10, 1, 0)
keep_alive r8
r12 = cast(str, r11)
b = r12
return a
def inner():
r0 :: str
L0:
r0 = 'inner: normal function'
return r0
def first():
r0 :: str
L0:
r0 = 'first: normal function'
return r0
def second():
r0 :: str
L0:
r0 = 'second: normal function'
return r0
[case testFreeVars]
from typing import Callable
def a(num: int) -> int:
def inner() -> int:
return num
return inner()
def b() -> int:
num = 3
def inner() -> int:
nonlocal num
num = 4
foo = 6
return num
return inner() + num
def c(flag: bool) -> str:
if flag:
def inner() -> str:
return 'f.inner: first definition'
else:
def inner() -> str:
return 'f.inner: second definition'
return inner()
[out]
def inner_a_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_a_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_a_obj
r0 :: __main__.a_env
r1 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = r0.num
return r1
def a(num):
num :: int
r0 :: __main__.a_env
r1 :: bool
r2 :: __main__.inner_a_obj
r3 :: bool
inner, r4 :: object
r5 :: int
L0:
r0 = a_env()
r0.num = num; r1 = is_error
r2 = inner_a_obj()
r2.__mypyc_env__ = r0; r3 = is_error
inner = r2
r4 = PyObject_Vectorcall(inner, 0, 0, 0)
r5 = unbox(int, r4)
return r5
def inner_b_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_b_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_b_obj
r0 :: __main__.b_env
r1 :: bool
foo, r2 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r0.num = 8; r1 = is_error
foo = 12
r2 = r0.num
return r2
def b():
r0 :: __main__.b_env
r1 :: bool
r2 :: __main__.inner_b_obj
r3 :: bool
inner, r4 :: object
r5, r6, r7 :: int
L0:
r0 = b_env()
r0.num = 6; r1 = is_error
r2 = inner_b_obj()
r2.__mypyc_env__ = r0; r3 = is_error
inner = r2
r4 = PyObject_Vectorcall(inner, 0, 0, 0)
r5 = unbox(int, r4)
r6 = r0.num
r7 = CPyTagged_Add(r5, r6)
return r7
def inner_c_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_c_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_c_obj
r0 :: __main__.c_env
r1 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = 'f.inner: first definition'
return r1
def inner_c_obj_0.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_c_obj_0.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_c_obj_0
r0 :: __main__.c_env
r1 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = 'f.inner: second definition'
return r1
def c(flag):
flag :: bool
r0 :: __main__.c_env
r1 :: __main__.inner_c_obj
r2 :: bool
inner :: object
r3 :: __main__.inner_c_obj_0
r4 :: bool
r5 :: object
r6 :: str
L0:
r0 = c_env()
if flag goto L1 else goto L2 :: bool
L1:
r1 = inner_c_obj()
r1.__mypyc_env__ = r0; r2 = is_error
inner = r1
goto L3
L2:
r3 = inner_c_obj_0()
r3.__mypyc_env__ = r0; r4 = is_error
inner = r3
L3:
r5 = PyObject_Vectorcall(inner, 0, 0, 0)
r6 = cast(str, r5)
return r6
[case testSpecialNested]
def a() -> int:
x = 1
def b() -> int:
x += 1
def c() -> int:
return x
return c()
return b()
[out]
def c_a_b_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def c_a_b_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.c_a_b_obj
r0 :: __main__.b_a_env
r1 :: __main__.a_env
r2 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = r0.__mypyc_env__
r2 = r1.x
return r2
def b_a_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def b_a_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.b_a_obj
r0 :: __main__.a_env
r1 :: __main__.b_a_env
r2 :: bool
r3, r4 :: int
r5 :: bool
r6 :: __main__.c_a_b_obj
r7 :: bool
c, r8 :: object
r9 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = b_a_env()
r1.__mypyc_env__ = r0; r2 = is_error
r3 = r0.x
r4 = CPyTagged_Add(r3, 2)
r0.x = r4; r5 = is_error
r6 = c_a_b_obj()
r6.__mypyc_env__ = r1; r7 = is_error
c = r6
r8 = PyObject_Vectorcall(c, 0, 0, 0)
r9 = unbox(int, r8)
return r9
def a():
r0 :: __main__.a_env
r1 :: bool
r2 :: __main__.b_a_obj
r3 :: bool
b, r4 :: object
r5 :: int
L0:
r0 = a_env()
r0.x = 2; r1 = is_error
r2 = b_a_obj()
r2.__mypyc_env__ = r0; r3 = is_error
b = r2
r4 = PyObject_Vectorcall(b, 0, 0, 0)
r5 = unbox(int, r4)
return r5
[case testNestedFunctionInsideStatements]
def f(flag: bool) -> str:
if flag:
def inner() -> str:
return 'f.inner: first definition'
else:
def inner() -> str:
return 'f.inner: second definition'
return inner()
[out]
def inner_f_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_f_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_f_obj
r0 :: __main__.f_env
r1 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = 'f.inner: first definition'
return r1
def inner_f_obj_0.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def inner_f_obj_0.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.inner_f_obj_0
r0 :: __main__.f_env
r1 :: str
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = 'f.inner: second definition'
return r1
def f(flag):
flag :: bool
r0 :: __main__.f_env
r1 :: __main__.inner_f_obj
r2 :: bool
inner :: object
r3 :: __main__.inner_f_obj_0
r4 :: bool
r5 :: object
r6 :: str
L0:
r0 = f_env()
if flag goto L1 else goto L2 :: bool
L1:
r1 = inner_f_obj()
r1.__mypyc_env__ = r0; r2 = is_error
inner = r1
goto L3
L2:
r3 = inner_f_obj_0()
r3.__mypyc_env__ = r0; r4 = is_error
inner = r3
L3:
r5 = PyObject_Vectorcall(inner, 0, 0, 0)
r6 = cast(str, r5)
return r6
[case testNestedFunctionsCallEachOther]
from typing import Callable, List
def f(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)
[out]
def foo_f_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def foo_f_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.foo_f_obj
r0 :: __main__.f_env
r1, r2 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = r0.a
r2 = CPyTagged_Add(r1, 2)
return r2
def bar_f_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def bar_f_obj.__call__(__mypyc_self__):
__mypyc_self__ :: __main__.bar_f_obj
r0 :: __main__.f_env
r1, r2 :: object
r3 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = r0.foo
r2 = PyObject_Vectorcall(r1, 0, 0, 0)
r3 = unbox(int, r2)
return r3
def baz_f_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def baz_f_obj.__call__(__mypyc_self__, n):
__mypyc_self__ :: __main__.baz_f_obj
n :: int
r0 :: __main__.f_env
r1 :: bit
r2 :: int
r3, r4 :: object
r5 :: object[1]
r6 :: object_ptr
r7 :: object
r8, r9 :: int
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = int_eq n, 0
if r1 goto L1 else goto L2 :: bool
L1:
return 0
L2:
r2 = CPyTagged_Subtract(n, 2)
r3 = r0.baz
r4 = box(int, r2)
r5 = [r4]
r6 = load_address r5
r7 = PyObject_Vectorcall(r3, r6, 1, 0)
keep_alive r4
r8 = unbox(int, r7)
r9 = CPyTagged_Add(n, r8)
return r9
def f(a):
a :: int
r0 :: __main__.f_env
r1 :: bool
r2 :: __main__.foo_f_obj
r3, r4 :: bool
r5 :: __main__.bar_f_obj
r6, r7 :: bool
r8 :: __main__.baz_f_obj
r9, r10 :: bool
r11, r12 :: object
r13, r14 :: int
r15, r16 :: object
r17 :: object[1]
r18 :: object_ptr
r19 :: object
r20, r21 :: int
L0:
r0 = f_env()
r0.a = a; r1 = is_error
r2 = foo_f_obj()
r2.__mypyc_env__ = r0; r3 = is_error
r0.foo = r2; r4 = is_error
r5 = bar_f_obj()
r5.__mypyc_env__ = r0; r6 = is_error
r0.bar = r5; r7 = is_error
r8 = baz_f_obj()
r8.__mypyc_env__ = r0; r9 = is_error
r0.baz = r8; r10 = is_error
r11 = r0.bar
r12 = PyObject_Vectorcall(r11, 0, 0, 0)
r13 = unbox(int, r12)
r14 = r0.a
r15 = r0.baz
r16 = box(int, r14)
r17 = [r16]
r18 = load_address r17
r19 = PyObject_Vectorcall(r15, r18, 1, 0)
keep_alive r16
r20 = unbox(int, r19)
r21 = CPyTagged_Add(r13, r20)
return r21
[case testLambdas]
def f(x: int, y: int) -> None:
s = lambda a, b: a + b
t = lambda a, b: s(a, b)
return t(x, y)
[out]
def __mypyc_lambda__0_f_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def __mypyc_lambda__0_f_obj.__call__(__mypyc_self__, a, b):
__mypyc_self__ :: __main__.__mypyc_lambda__0_f_obj
a, b :: object
r0 :: __main__.f_env
r1 :: object
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = PyNumber_Add(a, b)
return r1
def __mypyc_lambda__1_f_obj.__get__(__mypyc_self__, instance, owner):
__mypyc_self__, instance, owner, r0 :: object
r1 :: bit
r2 :: object
L0:
r0 = load_address _Py_NoneStruct
r1 = instance == r0
if r1 goto L1 else goto L2 :: bool
L1:
return __mypyc_self__
L2:
r2 = PyMethod_New(__mypyc_self__, instance)
return r2
def __mypyc_lambda__1_f_obj.__call__(__mypyc_self__, a, b):
__mypyc_self__ :: __main__.__mypyc_lambda__1_f_obj
a, b :: object
r0 :: __main__.f_env
r1 :: object
r2 :: object[2]
r3 :: object_ptr
r4 :: object
L0:
r0 = __mypyc_self__.__mypyc_env__
r1 = r0.s
r2 = [a, b]
r3 = load_address r2
r4 = PyObject_Vectorcall(r1, r3, 2, 0)
keep_alive a, b
return r4
def f(x, y):
x, y :: int
r0 :: __main__.f_env
r1 :: __main__.__mypyc_lambda__0_f_obj
r2, r3 :: bool
r4 :: __main__.__mypyc_lambda__1_f_obj
r5 :: bool
t, r6, r7 :: object
r8 :: object[2]
r9 :: object_ptr
r10 :: object
r11 :: None
L0:
r0 = f_env()
r1 = __mypyc_lambda__0_f_obj()
r1.__mypyc_env__ = r0; r2 = is_error
r0.s = r1; r3 = is_error
r4 = __mypyc_lambda__1_f_obj()
r4.__mypyc_env__ = r0; r5 = is_error
t = r4
r6 = box(int, x)
r7 = box(int, y)
r8 = [r6, r7]
r9 = load_address r8
r10 = PyObject_Vectorcall(t, r9, 2, 0)
keep_alive r6, r7
r11 = unbox(None, r10)
return r11
[case testRecursiveFunction]
from typing import Callable
def baz(n: int) -> int:
if n == 0:
return 0
return n + baz(n - 1)
[out]
def baz(n):
n :: int
r0 :: bit
r1, r2, r3 :: int
L0:
r0 = int_eq n, 0
if r0 goto L1 else goto L2 :: bool
L1:
return 0
L2:
r1 = CPyTagged_Subtract(n, 2)
r2 = baz(r1)
r3 = CPyTagged_Add(n, r2)
return r3