| -- These test cases compile two modules at a time (native and other.py) |
| |
| [case testMultiModuleBasic] |
| from other import g |
| def f(x: int) -> int: |
| from other import h |
| return h(g(x + 1)) |
| [file other.py] |
| def g(x: int) -> int: |
| return x + 2 |
| def h(x: int) -> int: |
| return x + 1 |
| [file driver.py] |
| import native |
| from native import f |
| from other import g |
| assert f(3) == 7 |
| assert g(2) == 4 |
| try: |
| f(1.1) |
| except TypeError: |
| pass |
| else: |
| assert False |
| try: |
| g(1.1) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| [case testMultiModuleSameNames] |
| # Use same names in both modules |
| import other |
| def f() -> int: |
| return 0 |
| class C: |
| x: int |
| def __init__(self) -> None: |
| self.x = 1 |
| def f(self, x: int) -> int: |
| return self.x + x |
| class D(C): pass |
| |
| def g(x: 'other.C') -> None: |
| pass |
| |
| [file other.py] |
| def f(x: int) -> int: |
| return x + 1 |
| class C: |
| x: int |
| def __init__(self) -> None: |
| self.x = 2 |
| def f(self, x: int) -> int: |
| return self.x + x + 1 |
| class D(C): pass |
| [file driver.py] |
| import native, other |
| assert native.f() == 0 |
| assert other.f(3) == 4 |
| c1 = native.C() |
| c1.x += 3 |
| c2 = other.C() |
| c2.x += 6 |
| assert c1.f(9) == 1 + 3 + 9 |
| assert c2.f(7) == 2 + 6 + 7 + 1 |
| assert isinstance(native.D(), native.C) |
| assert isinstance(other.D(), other.C) |
| assert not isinstance(native.D(), other.C) |
| assert not isinstance(other.D(), native.C) |
| |
| [case testMultiModuleInitializeImportedModules] |
| from other import f |
| |
| def g() -> int: |
| return f(1) |
| [file other.py] |
| def f(x: int) -> int: |
| return x + 4 |
| [file driver.py] |
| import sys |
| assert 'other' not in sys.modules |
| from native import g |
| assert 'other' in sys.modules |
| assert g() == 5 |
| f = sys.modules['other'].f |
| assert f(1) == 5 |
| try: |
| f(1.1) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| [case testMultiModuleImportClass] |
| from typing import cast |
| from other import C, a_global |
| |
| class D(C): |
| def __init__(self, x: int) -> None: |
| self.x = x |
| |
| def f(c: C) -> int: |
| d = D(3) |
| o: object = c |
| c = cast(C, o) |
| return a_global + c.x + c.f() + d.x + d.f() + 1 |
| [file other.py] |
| from typing_extensions import Final |
| a_global: Final = int('5') |
| |
| class C: |
| x: int |
| |
| def __init__(self, x: int) -> None: |
| self.x = x |
| |
| def __hash__(self) -> int: |
| return self.x |
| |
| def __str__(self) -> str: |
| return str(self.x) |
| |
| def f(self) -> int: |
| return 2 |
| |
| def check(self) -> None: |
| assert isinstance(self, C) |
| |
| [file driver.py] |
| from native import f, D |
| from other import C |
| c = C(4) |
| assert f(c) == 5 + 4 + 2 + 3 + 2 + 1 |
| assert str(D(10)) == '10' |
| assert hash(10) == 10 |
| try: |
| f(1) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| assert isinstance(D(10), C) |
| |
| c.check() |
| D(10).check() |
| |
| [case testMultiModuleSpecialize] |
| from other import A |
| |
| class B(A): |
| def foo(self, x: object) -> int: |
| print(2) |
| return id(x) |
| [file other.py] |
| class A: |
| def foo(self, x: int) -> object: |
| print(1) |
| return str(x) |
| |
| def use_a(x: A, y: int) -> object: |
| return x.foo(y) |
| |
| [file driver.py] |
| from native import B |
| from other import A, use_a |
| a = A() |
| b = B() |
| o = object() |
| i = 10 |
| assert a.foo(10) == '10' |
| assert b.foo(o) == id(o) |
| assert use_a(a, 10) == '10' |
| assert use_a(b, i) == id(i) |
| [out] |
| 1 |
| 2 |
| 1 |
| 2 |
| |
| [case testMultiModuleLiterals] |
| from other import gs, gi, gf |
| |
| def fs() -> str: |
| return 'f' + gs() |
| def fi() -> int: |
| return 10001000100010001000 + gi() |
| def ff() -> float: |
| return 2.0 + gf() |
| [file other.py] |
| def gi() -> int: |
| return 20001000100010001000 |
| def gs() -> str: |
| return 'g' |
| def gf() -> float: |
| return 3.0 |
| [file driver.py] |
| from native import fs, fi, ff |
| assert fs() == 'fg' |
| assert fi() == 30002000200020002000 |
| assert ff() == 5.0 |
| |
| [case testMultiModuleTraceback] |
| from other import fail2 |
| |
| def fail() -> None: |
| fail2() |
| [file other.py] |
| def fail2() -> None: |
| x = [1] |
| x[2] = 2 |
| [file driver.py] |
| import traceback |
| import sys |
| import native |
| import other |
| try: |
| other.fail2() |
| except IndexError: |
| tb = sys.exc_info()[2] |
| assert tb.tb_next.tb_frame.f_globals is other.__dict__ |
| traceback.print_exc() |
| try: |
| native.fail() |
| except IndexError: |
| tb = sys.exc_info()[2] |
| assert tb.tb_next.tb_frame.f_globals is native.__dict__ |
| traceback.print_exc() |
| [out] |
| Traceback (most recent call last): |
| File "driver.py", line 6, in <module> |
| other.fail2() |
| File "other.py", line 3, in fail2 |
| IndexError: list assignment index out of range |
| Traceback (most recent call last): |
| File "driver.py", line 12, in <module> |
| native.fail() |
| File "native.py", line 4, in fail |
| fail2() |
| File "other.py", line 3, in fail2 |
| IndexError: list assignment index out of range |
| |
| [case testMultiModuleCycle] |
| if False: |
| from typing import Final |
| import other |
| |
| x = int('0') # type: Final |
| |
| def f1() -> int: |
| return other.f2() + other.x |
| |
| def f3() -> int: |
| return 5 |
| [file other.py] |
| if False: |
| from typing import Final |
| import native |
| |
| x = int('0') # type: Final |
| |
| def f2() -> int: |
| return native.f3() + native.x |
| [file driver.py] |
| from native import f1 |
| assert f1() == 5 |
| |
| [case testMultiModuleCycleWithClasses] |
| import other |
| |
| class D: pass |
| |
| def f() -> other.C: |
| return other.C() |
| |
| def g(c: other.C) -> D: |
| return c.d |
| |
| [file other.py] |
| import native |
| |
| class C: |
| def __init__(self) -> None: |
| self.d = native.D() |
| |
| def h(d: native.D) -> None: |
| pass |
| |
| [file driver.py] |
| from native import f, g |
| from other import C, h |
| |
| c = f() |
| assert isinstance(c, C) |
| assert g(c) is c.d |
| h(c.d) |
| |
| try: |
| g(1) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| try: |
| h(1) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| [case testMultiModuleCycleWithInheritance] |
| import other |
| |
| class Deriv1(other.Base1): |
| def __init__(self) -> None: |
| super().__init__() |
| |
| class Base2: |
| y: int |
| def __init__(self) -> None: |
| self.y = 2 |
| |
| [file other.py] |
| from typing import Tuple |
| import native |
| |
| class Base1: |
| a: Tuple[int, int] |
| x: int |
| def __init__(self) -> None: |
| self.x = 1 |
| |
| def make_2() -> native.Base2: |
| return native.Base2() |
| |
| [file driver.py] |
| from native import Deriv1 |
| from other import make_2 |
| a = Deriv1() |
| assert a.x == 1 |
| b = make_2() |
| assert b.y == 2 |
| |
| [case testMultiModuleTraitInheritance] |
| from other import Base1, Base2 |
| |
| class Deriv1(Base1, Base2): |
| pass |
| |
| [file other.py] |
| from mypy_extensions import trait |
| |
| @trait |
| class Base1: |
| def foo(self) -> int: return 10 |
| @trait |
| class Base2: |
| def bar(self) -> int: return 12 |
| |
| [file driver.py] |
| from native import Deriv1 |
| a = Deriv1() |
| assert a.foo() == 10 and a.bar() == 12 |
| |
| |
| [case testImportCycleWithNonCompiledModule] |
| import m |
| |
| class C: pass |
| |
| def f1() -> int: |
| m.D() |
| return m.f2() |
| |
| def f3() -> int: |
| return 2 |
| |
| [file m.py] |
| # This module is NOT compiled |
| import native |
| |
| class D: pass |
| |
| def f2() -> int: |
| native.C() |
| return native.f3() |
| |
| [file driver.py] |
| from native import f1 |
| |
| assert f1() == 2 |
| |
| [case testImportCycleWithTopLevelStatements] |
| import other |
| x = 1 |
| print(x) |
| |
| [file other.py] |
| import native |
| x = 2 |
| print(x) |
| |
| [file driver.py] |
| import other |
| print('-') |
| import native |
| print('>', native.x) |
| print('>', other.x) |
| |
| [out] |
| 1 |
| 2 |
| - |
| > 1 |
| > 2 |
| |
| [case testMultiModuleCycleIfMypy1] |
| from other import foo, bar |
| |
| class Foo: |
| def foo(self) -> None: |
| foo(self) |
| class Bar: |
| def bar(self) -> None: |
| bar(self) |
| |
| [file other.py] |
| from typing_extensions import TYPE_CHECKING |
| MYPY = False |
| if MYPY: |
| from native import Foo |
| if TYPE_CHECKING: |
| from native import Bar |
| |
| def foo(x: 'Foo') -> None: |
| pass |
| def bar(x: 'Bar') -> None: |
| pass |
| |
| [file driver.py] |
| from native import Foo, Bar |
| Foo().foo() |
| Bar().bar() |
| |
| [case testMultiModuleCycleIfMypy2] |
| MYPY = False |
| if MYPY: |
| from other import C |
| |
| class D: |
| def __init__(self) -> None: |
| self.y = 1 |
| |
| def f(c: 'C') -> int: |
| return c.x |
| |
| [file other.py] |
| from typing_extensions import TYPE_CHECKING |
| if TYPE_CHECKING: |
| from native import D |
| |
| class C: |
| def __init__(self) -> None: |
| self.x = 2 |
| |
| def g(d: 'D') -> int: |
| return d.y |
| |
| [file driver.py] |
| from native import f, D |
| from other import g, C |
| |
| assert f(C()) == 2 |
| assert g(D()) == 1 |
| |
| try: |
| f(D()) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| try: |
| g(C()) |
| except TypeError: |
| pass |
| else: |
| assert False |
| |
| [case testMultiModuleRelative] |
| from package.a import f |
| [file package/__init__.py] |
| [file package/a.py] |
| from . import b |
| from .c import c3 |
| def f() -> None: |
| print("Hello " + b.b2()) |
| print("Hello " + c3()) |
| [file package/b.py] |
| def b2() -> str: |
| return "moon!" |
| [file package/c.py] |
| def c3() -> str: |
| return "sun!" |
| |
| [file driver.py] |
| from native import f |
| f() |
| [out] |
| Hello moon! |
| Hello sun! |
| |
| [case testMultiModuleCrash] |
| b = False |
| if b: |
| import other |
| |
| def foo() -> None: |
| try: |
| other.x |
| except: |
| pass |
| else: |
| assert False |
| |
| [file other.py] |
| x = 10 |
| |
| [file driver.py] |
| from native import foo |
| foo() |