| [case testIsNone] |
| from typing import Optional |
| |
| class A: pass |
| |
| def f(x: Optional[A]) -> int: |
| if x is None: |
| return 1 |
| return 2 |
| [out] |
| def f(x): |
| x :: union[__main__.A, None] |
| r0 :: None |
| r1 :: object |
| r2 :: bool |
| r3, r4 :: short_int |
| L0: |
| r0 = None |
| r1 = box(None, r0) |
| r2 = x is r1 |
| if r2 goto L1 else goto L2 :: bool |
| L1: |
| r3 = 1 |
| return r3 |
| L2: |
| r4 = 2 |
| return r4 |
| |
| [case testIsNotNone] |
| from typing import Optional |
| |
| class A: pass |
| |
| def f(x: Optional[A]) -> int: |
| if x is not None: |
| return 1 |
| return 2 |
| [out] |
| def f(x): |
| x :: union[__main__.A, None] |
| r0 :: None |
| r1 :: object |
| r2, r3 :: bool |
| r4, r5 :: short_int |
| L0: |
| r0 = None |
| r1 = box(None, r0) |
| r2 = x is r1 |
| r3 = !r2 |
| if r3 goto L1 else goto L2 :: bool |
| L1: |
| r4 = 1 |
| return r4 |
| L2: |
| r5 = 2 |
| return r5 |
| |
| [case testIsTruthy] |
| from typing import Optional |
| |
| class A: pass |
| |
| def f(x: Optional[A]) -> int: |
| if x: |
| return 1 |
| return 2 |
| [out] |
| def f(x): |
| x :: union[__main__.A, None] |
| r0 :: object |
| r1 :: bool |
| r2, r3 :: short_int |
| L0: |
| r0 = builtins.None :: object |
| r1 = x is not r0 |
| if r1 goto L1 else goto L2 :: bool |
| L1: |
| r2 = 1 |
| return r2 |
| L2: |
| r3 = 2 |
| return r3 |
| |
| [case testIsTruthyOverride] |
| from typing import Optional |
| |
| class A: pass |
| |
| class B(A): |
| def __bool__(self) -> bool: |
| return False |
| |
| |
| def f(x: Optional[A]) -> int: |
| if x: |
| return 1 |
| return 2 |
| [out] |
| def B.__bool__(self): |
| self :: __main__.B |
| r0 :: bool |
| L0: |
| r0 = False |
| return r0 |
| def f(x): |
| x :: union[__main__.A, None] |
| r0 :: object |
| r1 :: bool |
| r2 :: __main__.A |
| r3 :: bool |
| r4, r5 :: short_int |
| L0: |
| r0 = builtins.None :: object |
| r1 = x is not r0 |
| if r1 goto L1 else goto L3 :: bool |
| L1: |
| r2 = cast(__main__.A, x) |
| r3 = bool r2 :: object |
| if r3 goto L2 else goto L3 :: bool |
| L2: |
| r4 = 1 |
| return r4 |
| L3: |
| r5 = 2 |
| return r5 |
| |
| [case testAssignToOptional] |
| from typing import Optional |
| |
| class A: |
| a: Optional[int] |
| |
| def f(x: Optional[A], y: Optional[A], z: Optional[int]) -> None: |
| x = None |
| x = A() |
| x = y |
| z = 1 |
| a = A() |
| a.a = 1 |
| a.a = None |
| [out] |
| def f(x, y, z): |
| x, y :: union[__main__.A, None] |
| z :: union[int, None] |
| r0 :: None |
| r1 :: object |
| r2 :: __main__.A |
| r3 :: short_int |
| r4 :: object |
| r5, a :: __main__.A |
| r6 :: short_int |
| r7 :: object |
| r8 :: bool |
| r9 :: None |
| r10 :: object |
| r11 :: bool |
| r12 :: None |
| L0: |
| r0 = None |
| r1 = box(None, r0) |
| x = r1 |
| r2 = A() |
| x = r2 |
| x = y |
| r3 = 1 |
| r4 = box(short_int, r3) |
| z = r4 |
| r5 = A() |
| a = r5 |
| r6 = 1 |
| r7 = box(short_int, r6) |
| a.a = r7; r8 = is_error |
| r9 = None |
| r10 = box(None, r9) |
| a.a = r10; r11 = is_error |
| r12 = None |
| return r12 |
| |
| [case testBoxOptionalListItem] |
| from typing import List, Optional |
| |
| def f(x: List[Optional[int]]) -> None: |
| x[0] = 0 |
| x[1] = None |
| [out] |
| def f(x): |
| x :: list |
| r0, r1 :: short_int |
| r2 :: object |
| r3 :: bool |
| r4 :: None |
| r5 :: short_int |
| r6 :: object |
| r7 :: bool |
| r8 :: None |
| L0: |
| r0 = 0 |
| r1 = 0 |
| r2 = box(short_int, r0) |
| r3 = x.__setitem__(r1, r2) :: list |
| r4 = None |
| r5 = 1 |
| r6 = box(None, r4) |
| r7 = x.__setitem__(r5, r6) :: list |
| r8 = None |
| return r8 |
| |
| [case testNarrowDownFromOptional] |
| from typing import Optional |
| |
| class A: pass |
| |
| def f(x: Optional[A]) -> A: |
| y = A() |
| if x is not None: |
| y = x |
| return x |
| return y |
| [out] |
| def f(x): |
| x :: union[__main__.A, None] |
| r0, y :: __main__.A |
| r1 :: None |
| r2 :: object |
| r3, r4 :: bool |
| r5, r6 :: __main__.A |
| L0: |
| r0 = A() |
| y = r0 |
| r1 = None |
| r2 = box(None, r1) |
| r3 = x is r2 |
| r4 = !r3 |
| if r4 goto L1 else goto L2 :: bool |
| L1: |
| r5 = cast(__main__.A, x) |
| y = r5 |
| r6 = cast(__main__.A, x) |
| return r6 |
| L2: |
| return y |
| |
| [case testPartialOptionalType] |
| def f(y: int) -> None: |
| x = None |
| if y == 1: |
| x = y |
| if x is not None: |
| y = x |
| [out] |
| def f(y): |
| y :: int |
| r0 :: None |
| x :: union[int, None] |
| r1 :: object |
| r2 :: short_int |
| r3 :: bool |
| r4 :: object |
| r5 :: None |
| r6 :: object |
| r7, r8 :: bool |
| r9 :: int |
| r10 :: None |
| L0: |
| r0 = None |
| r1 = box(None, r0) |
| x = r1 |
| r2 = 1 |
| r3 = y == r2 :: int |
| if r3 goto L1 else goto L2 :: bool |
| L1: |
| r4 = box(int, y) |
| x = r4 |
| L2: |
| r5 = None |
| r6 = box(None, r5) |
| r7 = x is r6 |
| r8 = !r7 |
| if r8 goto L3 else goto L4 :: bool |
| L3: |
| r9 = unbox(int, x) |
| y = r9 |
| L4: |
| r10 = None |
| return r10 |
| |
| [case testUnionType] |
| from typing import Union |
| |
| class A: |
| a: int |
| |
| def f(x: Union[int, A]) -> int: |
| if isinstance(x, int): |
| return x + 1 |
| else: |
| return x.a |
| [out] |
| def f(x): |
| x :: union[int, __main__.A] |
| r0 :: object |
| r1 :: bool |
| r2 :: int |
| r3 :: short_int |
| r4 :: int |
| r5 :: __main__.A |
| r6 :: int |
| L0: |
| r0 = int |
| r1 = isinstance x, r0 |
| if r1 goto L1 else goto L2 :: bool |
| L1: |
| r2 = unbox(int, x) |
| r3 = 1 |
| r4 = r2 + r3 :: int |
| return r4 |
| L2: |
| r5 = cast(__main__.A, x) |
| r6 = r5.a |
| return r6 |
| L3: |
| unreachable |
| |
| [case testUnionTypeInList] |
| from typing import List, Union |
| |
| def f(x: List[Union[int, str]]) -> object: |
| return x[0] |
| [out] |
| def f(x): |
| x :: list |
| r0 :: short_int |
| r1 :: object |
| r2 :: union[int, str] |
| L0: |
| r0 = 0 |
| r1 = x[r0] :: list |
| r2 = cast(union[int, str], r1) |
| return r2 |
| |
| [case testUnionAttributeAccess] |
| from typing import Union |
| class A: |
| a: int |
| class B: |
| a: object |
| def get(o: Union[A, B]) -> None: |
| z = o.a |
| def set(o: Union[A, B], s: str) -> None: |
| o.a = s |
| |
| [out] |
| def get(o): |
| o :: union[__main__.A, __main__.B] |
| r0, r1 :: object |
| r2 :: bool |
| r3 :: __main__.A |
| r4 :: int |
| r5 :: object |
| r6 :: __main__.B |
| r7, z :: object |
| r8 :: None |
| L0: |
| r1 = __main__.A :: type |
| r2 = type_is o, r1 |
| if r2 goto L1 else goto L2 :: bool |
| L1: |
| r3 = cast(__main__.A, o) |
| r4 = r3.a |
| r5 = box(int, r4) |
| r0 = r5 |
| goto L3 |
| L2: |
| r6 = cast(__main__.B, o) |
| r7 = r6.a |
| r0 = r7 |
| L3: |
| z = r0 |
| r8 = None |
| return r8 |
| def set(o, s): |
| o :: union[__main__.A, __main__.B] |
| s, r0 :: str |
| r1 :: bool |
| r2 :: None |
| L0: |
| r0 = unicode_5 :: static ('a') |
| r1 = setattr o, r0, s |
| r2 = None |
| return r2 |
| |
| [case testUnionMethodCall] |
| from typing import Union |
| class A: |
| def f(self, x: int) -> int: |
| return x |
| class B: |
| def f(self, x: object) -> object: |
| return x |
| class C: |
| def f(self, x: object) -> int: |
| return 0 |
| def g(o: Union[A, B, C]) -> None: |
| z = o.f(1) |
| |
| [out] |
| def A.f(self, x): |
| self :: __main__.A |
| x :: int |
| L0: |
| return x |
| def B.f(self, x): |
| self :: __main__.B |
| x :: object |
| L0: |
| return x |
| def C.f(self, x): |
| self :: __main__.C |
| x :: object |
| r0 :: short_int |
| L0: |
| r0 = 0 |
| return r0 |
| def g(o): |
| o :: union[__main__.A, __main__.B, __main__.C] |
| r0 :: short_int |
| r1, r2 :: object |
| r3 :: bool |
| r4 :: __main__.A |
| r5 :: int |
| r6, r7 :: object |
| r8 :: bool |
| r9 :: __main__.B |
| r10, r11 :: object |
| r12 :: __main__.C |
| r13 :: object |
| r14 :: int |
| r15, z :: object |
| r16 :: None |
| L0: |
| r0 = 1 |
| r2 = __main__.A :: type |
| r3 = type_is o, r2 |
| if r3 goto L1 else goto L2 :: bool |
| L1: |
| r4 = cast(__main__.A, o) |
| r5 = r4.f(r0) |
| r6 = box(int, r5) |
| r1 = r6 |
| goto L5 |
| L2: |
| r7 = __main__.B :: type |
| r8 = type_is o, r7 |
| if r8 goto L3 else goto L4 :: bool |
| L3: |
| r9 = cast(__main__.B, o) |
| r10 = box(short_int, r0) |
| r11 = r9.f(r10) |
| r1 = r11 |
| goto L5 |
| L4: |
| r12 = cast(__main__.C, o) |
| r13 = box(short_int, r0) |
| r14 = r12.f(r13) |
| r15 = box(int, r14) |
| r1 = r15 |
| L5: |
| z = r1 |
| r16 = None |
| return r16 |
| |
| [case testUnionWithNonNativeItem] |
| from typing import Union |
| from m import B |
| |
| class A: |
| x: int |
| |
| def f(o: Union[A, B]) -> None: |
| o.x |
| |
| def g(o: Union[B, A]) -> None: |
| o.x |
| |
| [file m.py] |
| class B: |
| x: int |
| |
| [out] |
| def f(o): |
| o :: union[__main__.A, object] |
| r0 :: int |
| r1 :: object |
| r2 :: bool |
| r3 :: __main__.A |
| r4 :: int |
| r5 :: object |
| r6 :: str |
| r7 :: object |
| r8 :: int |
| r9 :: None |
| L0: |
| r1 = __main__.A :: type |
| r2 = type_is o, r1 |
| if r2 goto L1 else goto L2 :: bool |
| L1: |
| r3 = cast(__main__.A, o) |
| r4 = r3.x |
| r0 = r4 |
| goto L3 |
| L2: |
| r5 = o |
| r6 = unicode_7 :: static ('x') |
| r7 = getattr r5, r6 |
| r8 = unbox(int, r7) |
| r0 = r8 |
| L3: |
| r9 = None |
| return r9 |
| def g(o): |
| o :: union[object, __main__.A] |
| r0 :: int |
| r1 :: object |
| r2 :: bool |
| r3 :: __main__.A |
| r4 :: int |
| r5 :: object |
| r6 :: str |
| r7 :: object |
| r8 :: int |
| r9 :: None |
| L0: |
| r1 = __main__.A :: type |
| r2 = type_is o, r1 |
| if r2 goto L1 else goto L2 :: bool |
| L1: |
| r3 = cast(__main__.A, o) |
| r4 = r3.x |
| r0 = r4 |
| goto L3 |
| L2: |
| r5 = o |
| r6 = unicode_7 :: static ('x') |
| r7 = getattr r5, r6 |
| r8 = unbox(int, r7) |
| r0 = r8 |
| L3: |
| r9 = None |
| return r9 |
| |
| [case testUnionWithNoNativeItems] |
| from typing import Union |
| from m import A, B |
| |
| def f(o: Union[A, B]) -> None: |
| o.x |
| |
| [file m.py] |
| class A: |
| x: object |
| class B: |
| x: int |
| |
| [out] |
| def f(o): |
| o :: union[object, object] |
| r0, r1 :: object |
| r2 :: str |
| r3 :: object |
| r4 :: None |
| L0: |
| r1 = o |
| r2 = unicode_6 :: static ('x') |
| r3 = getattr r1, r2 |
| r0 = r3 |
| L1: |
| r4 = None |
| return r4 |