run-multimodule.test 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887
  1. -- These test cases compile two or more modules at a time.
  2. -- Any file prefixed with "other" is compiled.
  3. --
  4. -- Note that these are run in three compilation modes: regular,
  5. -- multi-file and separate. See the docstrings of
  6. -- mypyc.test.test_run.TestRunMultiFile and
  7. -- mypyc.test.test_run.TestRunSeparate for more information.
  8. --
  9. -- Some of these files perform multiple incremental runs. See
  10. -- test-data/unit/check-incremental.test for more information
  11. -- about how this is specified (e.g. .2 file name suffixes).
  12. [case testMultiModulePackage]
  13. from p.other import g, _i as i
  14. def f(x: int) -> int:
  15. from p.other import h
  16. return i(h(g(x + 1)))
  17. [file p/__init__.py]
  18. [file p/other.py]
  19. def g(x: int) -> int:
  20. return x + 2
  21. def h(x: int) -> int:
  22. return x + 1
  23. def _i(x: int) -> int:
  24. return x + 3
  25. [file driver.py]
  26. import native
  27. from native import f
  28. from p.other import g
  29. assert f(3) == 10
  30. assert g(2) == 4
  31. try:
  32. f(1.1)
  33. except TypeError:
  34. pass
  35. else:
  36. assert False
  37. try:
  38. g(1.1)
  39. except TypeError:
  40. pass
  41. else:
  42. assert False
  43. [case testMultiModuleFastpaths]
  44. [file other_main.py]
  45. [file other_main.py.2]
  46. from other_b import A, func
  47. class B(A):
  48. pass
  49. def test() -> None:
  50. a = A()
  51. assert func() == 12
  52. assert a.method() == "test"
  53. test()
  54. [file other_b.py]
  55. class A:
  56. def method(self) -> str:
  57. return "test"
  58. def func() -> int:
  59. return 12
  60. # Remove all the methods and functions from globals to ensure that
  61. # they get called via the fastpaths even when doing incremental
  62. # compilation.
  63. setattr(A, 'method', None)
  64. setattr(A, '__init__', None)
  65. globals()['func'] = None
  66. globals()['A'] = None
  67. [file driver.py]
  68. import other_main
  69. [case testMultiModuleSameNames]
  70. # Use same names in both modules
  71. import other
  72. def f() -> int:
  73. return 0
  74. class C:
  75. x: int
  76. def __init__(self) -> None:
  77. self.x = 1
  78. def f(self, x: int) -> int:
  79. return self.x + x
  80. class D(C): pass
  81. def g(x: 'other.C') -> None:
  82. pass
  83. [file other.py]
  84. def f(x: int) -> int:
  85. return x + 1
  86. class C:
  87. x: int
  88. def __init__(self) -> None:
  89. self.x = 2
  90. def f(self, x: int) -> int:
  91. return self.x + x + 1
  92. class D(C): pass
  93. [file driver.py]
  94. import native, other
  95. assert native.f() == 0
  96. assert other.f(3) == 4
  97. c1 = native.C()
  98. c1.x += 3
  99. c2 = other.C()
  100. c2.x += 6
  101. assert c1.f(9) == 1 + 3 + 9
  102. assert c2.f(7) == 2 + 6 + 7 + 1
  103. assert isinstance(native.D(), native.C)
  104. assert isinstance(other.D(), other.C)
  105. assert not isinstance(native.D(), other.C)
  106. assert not isinstance(other.D(), native.C)
  107. [case testMultiModuleInitializeImportedModules]
  108. from other import f
  109. def g() -> int:
  110. return f(1)
  111. [file other.py]
  112. def f(x: int) -> int:
  113. return x + 4
  114. [file driver.py]
  115. import sys
  116. assert 'other' not in sys.modules
  117. from native import g
  118. assert 'other' in sys.modules
  119. assert g() == 5
  120. f = sys.modules['other'].f
  121. assert f(1) == 5
  122. try:
  123. f(1.1)
  124. except TypeError:
  125. pass
  126. else:
  127. assert False
  128. [case testMultiModuleImportClass]
  129. from typing import cast
  130. from other import C, a_global
  131. class D(C):
  132. def __init__(self, x: int) -> None:
  133. self.x = x
  134. def f(c: C) -> int:
  135. d = D(3)
  136. o: object = c
  137. c = cast(C, o)
  138. return a_global + c.x + c.f() + d.x + d.f() + 1
  139. [file other.py]
  140. from typing_extensions import Final
  141. a_global: Final = int('5')
  142. class C:
  143. x: int
  144. def __init__(self, x: int) -> None:
  145. self.x = x
  146. def __hash__(self) -> int:
  147. return self.x
  148. def __str__(self) -> str:
  149. return str(self.x)
  150. def f(self) -> int:
  151. return 2
  152. def check(self) -> None:
  153. assert isinstance(self, C)
  154. [file driver.py]
  155. from native import f, D
  156. from other import C
  157. c = C(4)
  158. assert f(c) == 5 + 4 + 2 + 3 + 2 + 1
  159. assert str(D(10)) == '10'
  160. assert hash(10) == 10
  161. try:
  162. f(1)
  163. except TypeError:
  164. pass
  165. else:
  166. assert False
  167. assert isinstance(D(10), C)
  168. c.check()
  169. D(10).check()
  170. [case testMultiModuleSpecialize]
  171. from other import A
  172. class B(A):
  173. def foo(self, x: object) -> int:
  174. print(2)
  175. return id(x)
  176. [file other.py]
  177. class A:
  178. def foo(self, x: int) -> object:
  179. print(1)
  180. return str(x)
  181. def use_a(x: A, y: int) -> object:
  182. return x.foo(y)
  183. [file driver.py]
  184. from native import B
  185. from other import A, use_a
  186. a = A()
  187. b = B()
  188. o = object()
  189. i = 10
  190. assert a.foo(10) == '10'
  191. assert b.foo(o) == id(o)
  192. assert use_a(a, 10) == '10'
  193. assert use_a(b, i) == id(i)
  194. [out]
  195. 1
  196. 2
  197. 1
  198. 2
  199. [case testMultiModuleLiterals]
  200. from other import gs, gi, gf
  201. def fs() -> str:
  202. return 'f' + gs()
  203. def fi() -> int:
  204. return 10001000100010001000 + gi()
  205. def ff() -> float:
  206. return 2.0 + gf()
  207. [file other.py]
  208. def gi() -> int:
  209. return 20001000100010001000
  210. def gs() -> str:
  211. return 'g'
  212. def gf() -> float:
  213. return 3.0
  214. [file driver.py]
  215. from native import fs, fi, ff
  216. assert fs() == 'fg'
  217. assert fi() == 30002000200020002000
  218. assert ff() == 5.0
  219. [case testMultiModuleTraceback]
  220. from other import fail2
  221. def fail() -> None:
  222. fail2()
  223. [file other.py]
  224. def fail2() -> None:
  225. x = [1]
  226. x[2] = 2
  227. [file driver.py]
  228. import traceback
  229. import sys
  230. import native
  231. import other
  232. try:
  233. other.fail2()
  234. except IndexError:
  235. tb = sys.exc_info()[2]
  236. assert tb.tb_next.tb_frame.f_globals is other.__dict__
  237. traceback.print_exc()
  238. try:
  239. native.fail()
  240. except IndexError:
  241. tb = sys.exc_info()[2]
  242. assert tb.tb_next.tb_frame.f_globals is native.__dict__
  243. traceback.print_exc()
  244. [out]
  245. Traceback (most recent call last):
  246. File "driver.py", line 6, in <module>
  247. other.fail2()
  248. File "other.py", line 3, in fail2
  249. x[2] = 2
  250. IndexError: list assignment index out of range
  251. Traceback (most recent call last):
  252. File "driver.py", line 12, in <module>
  253. native.fail()
  254. File "native.py", line 4, in fail
  255. fail2()
  256. File "other.py", line 3, in fail2
  257. x[2] = 2
  258. IndexError: list assignment index out of range
  259. [case testMultiModuleCycle]
  260. if False:
  261. from typing import Final
  262. import other
  263. x = int('0') # type: Final
  264. def f1() -> int:
  265. return other.f2() + other.x
  266. def f3() -> int:
  267. return 5
  268. [file other.py]
  269. if False:
  270. from typing import Final
  271. import native
  272. x = int('0') # type: Final
  273. def f2() -> int:
  274. return native.f3() + native.x
  275. [file driver.py]
  276. from native import f1
  277. assert f1() == 5
  278. [case testMultiModuleCycleWithClasses]
  279. import other
  280. class D: pass
  281. def f() -> other.C:
  282. return other.C()
  283. def g(c: other.C) -> D:
  284. return c.d
  285. [file other.py]
  286. import native
  287. class C:
  288. def __init__(self) -> None:
  289. self.d = native.D()
  290. def h(d: native.D) -> None:
  291. pass
  292. [file driver.py]
  293. from native import f, g
  294. from other import C, h
  295. c = f()
  296. assert isinstance(c, C)
  297. assert g(c) is c.d
  298. h(c.d)
  299. try:
  300. g(1)
  301. except TypeError:
  302. pass
  303. else:
  304. assert False
  305. try:
  306. h(1)
  307. except TypeError:
  308. pass
  309. else:
  310. assert False
  311. [case testMultiModuleCycleWithInheritance]
  312. import other
  313. class Deriv1(other.Base1):
  314. def __init__(self) -> None:
  315. super().__init__()
  316. class Base2:
  317. y: int
  318. def __init__(self) -> None:
  319. self.y = 2
  320. [file other.py]
  321. from typing import Tuple
  322. import native
  323. class Base1:
  324. a: Tuple[int, int]
  325. x: int
  326. def __init__(self) -> None:
  327. self.x = 1
  328. def make_2() -> native.Base2:
  329. return native.Base2()
  330. [file driver.py]
  331. from native import Deriv1
  332. from other import make_2
  333. a = Deriv1()
  334. assert a.x == 1
  335. b = make_2()
  336. assert b.y == 2
  337. [case testMultiModuleTraitInheritance]
  338. from other import Base1, Base2
  339. class Deriv1(Base1, Base2):
  340. pass
  341. [file other.py]
  342. from mypy_extensions import trait
  343. @trait
  344. class Base1:
  345. def foo(self) -> int: return 10
  346. @trait
  347. class Base2:
  348. def bar(self) -> int: return 12
  349. [file driver.py]
  350. from native import Deriv1
  351. a = Deriv1()
  352. assert a.foo() == 10 and a.bar() == 12
  353. [case testImportCycleWithNonCompiledModule]
  354. import m
  355. class C: pass
  356. def f1() -> int:
  357. m.D()
  358. return m.f2()
  359. def f3() -> int:
  360. return 2
  361. [file m.py]
  362. # This module is NOT compiled
  363. import native
  364. class D: pass
  365. def f2() -> int:
  366. native.C()
  367. return native.f3()
  368. [file driver.py]
  369. from native import f1
  370. assert f1() == 2
  371. [case testImportCycleWithTopLevelStatements]
  372. import other
  373. x = 1
  374. print(x)
  375. [file other.py]
  376. import native
  377. x = 2
  378. print(x)
  379. [file driver.py]
  380. import other
  381. print('-')
  382. import native
  383. print('>', native.x)
  384. print('>', other.x)
  385. [out]
  386. 1
  387. 2
  388. -
  389. > 1
  390. > 2
  391. [case testMultiModuleCycleIfMypy1]
  392. from other import foo, bar
  393. class Foo:
  394. def foo(self) -> None:
  395. foo(self)
  396. class Bar:
  397. def bar(self) -> None:
  398. bar(self)
  399. [file other.py]
  400. from typing_extensions import TYPE_CHECKING
  401. MYPY = False
  402. if MYPY:
  403. from native import Foo
  404. if TYPE_CHECKING:
  405. from native import Bar
  406. def foo(x: 'Foo') -> None:
  407. pass
  408. def bar(x: 'Bar') -> None:
  409. pass
  410. [file driver.py]
  411. from native import Foo, Bar
  412. Foo().foo()
  413. Bar().bar()
  414. [case testMultiModuleCycleIfMypy2]
  415. MYPY = False
  416. if MYPY:
  417. from other import C
  418. class D:
  419. def __init__(self) -> None:
  420. self.y = 1
  421. def f(c: 'C') -> int:
  422. return c.x
  423. [file other.py]
  424. from typing_extensions import TYPE_CHECKING
  425. if TYPE_CHECKING:
  426. from native import D
  427. class C:
  428. def __init__(self) -> None:
  429. self.x = 2
  430. def g(d: 'D') -> int:
  431. return d.y
  432. [file driver.py]
  433. from native import f, D
  434. from other import g, C
  435. assert f(C()) == 2
  436. assert g(D()) == 1
  437. try:
  438. f(D())
  439. except TypeError:
  440. pass
  441. else:
  442. assert False
  443. try:
  444. g(C())
  445. except TypeError:
  446. pass
  447. else:
  448. assert False
  449. [case testMultiModuleRelative]
  450. from package.a import f
  451. [file package/__init__.py]
  452. [file package/a.py]
  453. from . import b
  454. from .c import c3
  455. def f() -> None:
  456. print("Hello " + b.b2())
  457. print("Hello " + c3())
  458. [file package/b.py]
  459. def b2() -> str:
  460. return "moon!"
  461. [file package/c.py]
  462. def c3() -> str:
  463. return "sun!"
  464. [file driver.py]
  465. from native import f
  466. f()
  467. [out]
  468. Hello moon!
  469. Hello sun!
  470. [case testMultiModuleCrash]
  471. b = False
  472. if b:
  473. import other
  474. def foo() -> None:
  475. try:
  476. other.x
  477. except:
  478. pass
  479. else:
  480. assert False
  481. [file other.py]
  482. x = 10
  483. [file driver.py]
  484. from native import foo
  485. foo()
  486. [case testTrivialIncremental]
  487. # separate: [(["other.py", "other_b.py"], "stuff")]
  488. from other import x
  489. from other_b import z
  490. y = x + z
  491. [file other.py]
  492. x = 1
  493. [file other.py.2]
  494. x = 2
  495. [file other_b.py]
  496. z = 1
  497. [file driver.py]
  498. from native import y
  499. print(y)
  500. [out]
  501. 2
  502. [out2]
  503. 3
  504. [rechecked other, other_b]
  505. [case testIncrementalCompilation1]
  506. import non_native
  507. from other_a import A
  508. from other_b import z
  509. a = A()
  510. assert a.y == z
  511. assert non_native.foo() == 0
  512. [file other_a.py]
  513. from other_b import z
  514. from typing import Iterable
  515. class A:
  516. def __init__(self) -> None:
  517. self.y = z
  518. [file other_a.py.2]
  519. from other_b import z
  520. from typing import Iterable
  521. class A:
  522. def __init__(self) -> None:
  523. self.x = 'test'
  524. self.y = z
  525. [file other_b.py]
  526. import other_a
  527. z = 10
  528. def foo() -> 'other_a.A':
  529. return other_a.A()
  530. [file other_b.py.3]
  531. import other_a
  532. z = 20
  533. def foo() -> 'other_a.A':
  534. return other_a.A()
  535. [file non_native.py]
  536. import other_a
  537. def foo() -> int:
  538. return 0
  539. [file non_native.py.4]
  540. import other_a
  541. def foo() -> float:
  542. return 0
  543. [file driver.py]
  544. from native import a
  545. print(a.y, getattr(a, 'x', None))
  546. [out]
  547. 10 None
  548. [out2]
  549. 10 test
  550. [out3]
  551. 20 test
  552. [out4]
  553. 20 test
  554. [rechecked other_a, other_b, native, non_native]
  555. [rechecked2 other_a, other_b]
  556. [rechecked3 native, non_native]
  557. -- This one tests a group that is not an SCC.
  558. [case testIncrementalCompilation2]
  559. # separate: [(["other_a.py", "other_b.py"], "stuff")]
  560. from other_a import A
  561. from other_b import z
  562. a = A()
  563. assert a.y == z
  564. [file other_a.py]
  565. from other_b import z
  566. class A:
  567. def __init__(self) -> None:
  568. self.y = z
  569. [file other_a.py.2]
  570. from other_b import z
  571. class A:
  572. def __init__(self) -> None:
  573. self.x = 'test'
  574. self.y = z
  575. [file other_b.py]
  576. z = 10
  577. [file driver.py]
  578. from native import a
  579. print(a.y, getattr(a, 'x', None))
  580. [out]
  581. 10 None
  582. [out2]
  583. 10 test
  584. [rechecked other_a, other_b, native]
  585. [case testIncrementalCompilation3]
  586. from other import X
  587. Y = X
  588. def foo() -> int:
  589. return X
  590. [file other.py]
  591. from typing_extensions import Final
  592. X: Final = 10
  593. [file other.py.2]
  594. from typing_extensions import Final
  595. X: Final = 20
  596. [file driver.py]
  597. import native
  598. import other
  599. assert native.Y == other.X
  600. assert native.foo() == other.X
  601. [rechecked native, other]
  602. -- This one tests a group changing
  603. [case testIncrementalCompilation4]
  604. # separate: [(["other_a.py", "other_b.py"], "stuff")]
  605. # separate2: []
  606. from other_a import A
  607. from other_b import z
  608. a = A()
  609. assert a.y == z
  610. [file other_a.py]
  611. from other_b import z
  612. class A:
  613. def __init__(self) -> None:
  614. self.y = z
  615. [file other_b.py]
  616. z = 10
  617. [file wtvr.py.2]
  618. [file driver.py]
  619. from native import a
  620. print(a.y, getattr(a, 'x', None))
  621. [out]
  622. 10 None
  623. [out2]
  624. 10 None
  625. [rechecked other_a, other_b, native]
  626. -- This one tests cases where other modules *do not* need rechecked
  627. [case testIncrementalCompilation5]
  628. import other_a
  629. [file other_a.py]
  630. from other_b import f
  631. assert f(10) == 20
  632. [file other_a.py.2]
  633. from other_b import f
  634. assert f(20) == 40
  635. [file other_b.py]
  636. def f(x: int) -> int:
  637. return x * 2
  638. [file driver.py]
  639. import native
  640. [rechecked other_a]
  641. -- Delete one of the C files and make sure this forces recompilation
  642. [case testIncrementalCompilation6]
  643. import other_a
  644. assert other_a.foo() == 10
  645. [file other_a.py]
  646. def foo() -> int: return 10
  647. [file build/__native_other_a.c]
  648. [delete build/__native_other_a.c.2]
  649. [file driver.py]
  650. import native
  651. [rechecked native, other_a]
  652. [case testSeparateCompilationWithUndefinedAttribute]
  653. from other_a import A
  654. def f() -> None:
  655. a = A()
  656. if a.x == 5:
  657. print(a.y)
  658. print(a.m())
  659. else:
  660. assert a.x == 6
  661. try:
  662. print(a.y)
  663. except AttributeError:
  664. print('y undefined')
  665. else:
  666. assert False
  667. try:
  668. print(a.m())
  669. except AttributeError:
  670. print('y undefined')
  671. else:
  672. assert False
  673. [file other_a.py]
  674. from other_b import B
  675. class A(B):
  676. def __init__(self) -> None:
  677. self.y = 9
  678. [file other_a.py.2]
  679. from other_b import B
  680. class A(B):
  681. x = 6
  682. def __init__(self) -> None:
  683. pass
  684. [file other_b.py]
  685. class B:
  686. x = 5
  687. def __init__(self) -> None:
  688. self.y = 7
  689. def m(self) -> int:
  690. return self.y
  691. [file driver.py]
  692. from native import f
  693. f()
  694. [rechecked native, other_a]
  695. [out]
  696. 9
  697. 9
  698. [out2]
  699. y undefined
  700. y undefined
  701. [case testIncrementalCompilationWithDeletable]
  702. import other_a
  703. [file other_a.py]
  704. from other_b import C
  705. [file other_a.py.2]
  706. from other_b import C
  707. c = C()
  708. print(getattr(c, 'x', None))
  709. del c.x
  710. print(getattr(c, 'x', None))
  711. [file other_b.py]
  712. class C:
  713. __deletable__ = ['x']
  714. def __init__(self) -> None:
  715. self.x = 0
  716. [file driver.py]
  717. import native
  718. [out]
  719. [out2]
  720. 0
  721. None