test_arcs.py 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436
  1. # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
  2. # For details: https://bitbucket.org/ned/coveragepy/src/default/NOTICE.txt
  3. """Tests for coverage.py's arc measurement."""
  4. from tests.coveragetest import CoverageTest
  5. import coverage
  6. from coverage import env
  7. from coverage.files import abs_file
  8. class SimpleArcTest(CoverageTest):
  9. """Tests for coverage.py's arc measurement."""
  10. def test_simple_sequence(self):
  11. self.check_coverage("""\
  12. a = 1
  13. b = 2
  14. """,
  15. arcz=".1 12 2.")
  16. self.check_coverage("""\
  17. a = 1
  18. b = 3
  19. """,
  20. arcz=".1 13 3.")
  21. self.check_coverage("""\
  22. a = 2
  23. b = 3
  24. c = 5
  25. """,
  26. arcz="-22 23 35 5-2")
  27. def test_function_def(self):
  28. self.check_coverage("""\
  29. def foo():
  30. a = 2
  31. foo()
  32. """,
  33. arcz=".1 .2 14 2. 4.")
  34. def test_if(self):
  35. self.check_coverage("""\
  36. a = 1
  37. if len([]) == 0:
  38. a = 3
  39. assert a == 3
  40. """,
  41. arcz=".1 12 23 24 34 4.", arcz_missing="24")
  42. self.check_coverage("""\
  43. a = 1
  44. if len([]) == 1:
  45. a = 3
  46. assert a == 1
  47. """,
  48. arcz=".1 12 23 24 34 4.", arcz_missing="23 34")
  49. def test_if_else(self):
  50. self.check_coverage("""\
  51. if len([]) == 0:
  52. a = 2
  53. else:
  54. a = 4
  55. assert a == 2
  56. """,
  57. arcz=".1 12 25 14 45 5.", arcz_missing="14 45")
  58. self.check_coverage("""\
  59. if len([]) == 1:
  60. a = 2
  61. else:
  62. a = 4
  63. assert a == 4
  64. """,
  65. arcz=".1 12 25 14 45 5.", arcz_missing="12 25")
  66. def test_compact_if(self):
  67. self.check_coverage("""\
  68. a = 1
  69. if len([]) == 0: a = 2
  70. assert a == 2
  71. """,
  72. arcz=".1 12 23 3.",
  73. )
  74. self.check_coverage("""\
  75. def fn(x):
  76. if x % 2: return True
  77. return False
  78. a = fn(1)
  79. assert a == True
  80. """,
  81. arcz=".1 14 45 5. .2 2. 23 3.", arcz_missing="23 3.")
  82. def test_multiline(self):
  83. self.check_coverage("""\
  84. a = (
  85. 2 +
  86. 3
  87. )
  88. b = \\
  89. 6
  90. """,
  91. arcz="-21 15 5-2",
  92. )
  93. def test_if_return(self):
  94. self.check_coverage("""\
  95. def if_ret(a):
  96. if a:
  97. return 3
  98. b = 4
  99. return 5
  100. x = if_ret(0) + if_ret(1)
  101. assert x == 8
  102. """,
  103. arcz=".1 16 67 7. .2 23 24 3. 45 5.",
  104. )
  105. def test_dont_confuse_exit_and_else(self):
  106. self.check_coverage("""\
  107. def foo():
  108. if foo:
  109. a = 3
  110. else:
  111. a = 5
  112. return a
  113. assert foo() == 3 # 7
  114. """,
  115. arcz=".1 17 7. .2 23 36 25 56 6.", arcz_missing="25 56"
  116. )
  117. self.check_coverage("""\
  118. def foo():
  119. if foo:
  120. a = 3
  121. else:
  122. a = 5
  123. foo() # 6
  124. """,
  125. arcz=".1 16 6. .2 23 3. 25 5.", arcz_missing="25 5."
  126. )
  127. def test_what_is_the_sound_of_no_lines_clapping(self):
  128. self.check_coverage("""\
  129. # __init__.py
  130. """,
  131. arcz=".1 1.",
  132. )
  133. class WithTest(CoverageTest):
  134. """Arc-measuring tests involving context managers."""
  135. def test_with(self):
  136. self.check_coverage("""\
  137. def example():
  138. with open("test", "w") as f: # exit
  139. f.write("")
  140. return 1
  141. example()
  142. """,
  143. arcz=".1 .2 23 34 4. 16 6."
  144. )
  145. def test_bug_146(self):
  146. # https://bitbucket.org/ned/coveragepy/issue/146
  147. self.check_coverage("""\
  148. for i in range(2):
  149. with open("test", "w") as f:
  150. print(3)
  151. print(4)
  152. print(5)
  153. """,
  154. arcz=".1 12 23 34 41 15 5."
  155. )
  156. class LoopArcTest(CoverageTest):
  157. """Arc-measuring tests involving loops."""
  158. def test_loop(self):
  159. self.check_coverage("""\
  160. for i in range(10):
  161. a = i
  162. assert a == 9
  163. """,
  164. arcz=".1 12 21 13 3.",
  165. )
  166. self.check_coverage("""\
  167. a = -1
  168. for i in range(0):
  169. a = i
  170. assert a == -1
  171. """,
  172. arcz=".1 12 23 32 24 4.", arcz_missing="23 32")
  173. def test_nested_loop(self):
  174. self.check_coverage("""\
  175. for i in range(3):
  176. for j in range(3):
  177. a = i + j
  178. assert a == 4
  179. """,
  180. arcz=".1 12 23 32 21 14 4.",
  181. )
  182. def test_break(self):
  183. self.check_coverage("""\
  184. for i in range(10):
  185. a = i
  186. break # 3
  187. a = 99
  188. assert a == 0 # 5
  189. """,
  190. arcz=".1 12 23 35 15 41 5.", arcz_missing="15 41")
  191. def test_continue(self):
  192. self.check_coverage("""\
  193. for i in range(10):
  194. a = i
  195. continue # 3
  196. a = 99
  197. assert a == 9 # 5
  198. """,
  199. arcz=".1 12 23 31 15 41 5.", arcz_missing="41")
  200. def test_nested_breaks(self):
  201. self.check_coverage("""\
  202. for i in range(3):
  203. for j in range(3):
  204. a = i + j
  205. break # 4
  206. if i == 2:
  207. break
  208. assert a == 2 and i == 2 # 7
  209. """,
  210. arcz=".1 12 23 34 45 25 56 51 67 17 7.", arcz_missing="17 25")
  211. def test_while_true(self):
  212. # With "while 1", the loop knows it's constant.
  213. self.check_coverage("""\
  214. a, i = 1, 0
  215. while 1:
  216. if i >= 3:
  217. a = 4
  218. break
  219. i += 1
  220. assert a == 4 and i == 3
  221. """,
  222. arcz=".1 12 23 34 45 36 63 57 7.",
  223. )
  224. # With "while True", 2.x thinks it's computation, 3.x thinks it's
  225. # constant.
  226. if env.PY3:
  227. arcz = ".1 12 23 34 45 36 63 57 7."
  228. else:
  229. arcz = ".1 12 23 27 34 45 36 62 57 7."
  230. self.check_coverage("""\
  231. a, i = 1, 0
  232. while True:
  233. if i >= 3:
  234. a = 4
  235. break
  236. i += 1
  237. assert a == 4 and i == 3
  238. """,
  239. arcz=arcz,
  240. )
  241. def test_for_if_else_for(self):
  242. self.check_coverage("""\
  243. def branches_2(l):
  244. if l:
  245. for e in l:
  246. a = 4
  247. else:
  248. a = 6
  249. def branches_3(l):
  250. for x in l:
  251. if x:
  252. for e in l:
  253. a = 12
  254. else:
  255. a = 14
  256. branches_2([0,1])
  257. branches_3([0,1])
  258. """,
  259. arcz=
  260. ".1 18 8G GH H. "
  261. ".2 23 34 43 26 3. 6. "
  262. "-89 9A 9-8 AB BC CB B9 AE E9",
  263. arcz_missing="26 6."
  264. )
  265. def test_for_else(self):
  266. self.check_coverage("""\
  267. def forelse(seq):
  268. for n in seq:
  269. if n > 5:
  270. break
  271. else:
  272. print('None of the values were greater than 5')
  273. print('Done')
  274. forelse([1,2])
  275. forelse([1,6])
  276. """,
  277. arcz=".1 .2 23 32 34 47 26 67 7. 18 89 9."
  278. )
  279. def test_while_else(self):
  280. self.check_coverage("""\
  281. def whileelse(seq):
  282. while seq:
  283. n = seq.pop()
  284. if n > 4:
  285. break
  286. else:
  287. n = 99
  288. return n
  289. assert whileelse([1, 2]) == 99
  290. assert whileelse([1, 5]) == 5
  291. """,
  292. arcz=".1 19 9A A. .2 23 34 45 58 42 27 78 8.",
  293. )
  294. def test_confusing_for_loop_bug_175(self):
  295. if env.PY3:
  296. # Py3 counts the list comp as a separate code object.
  297. arcz = ".1 -22 2-2 12 23 34 45 53 3."
  298. else:
  299. arcz = ".1 12 23 34 45 53 3."
  300. self.check_coverage("""\
  301. o = [(1,2), (3,4)]
  302. o = [a for a in o]
  303. for tup in o:
  304. x = tup[0]
  305. y = tup[1]
  306. """,
  307. arcz=arcz,
  308. )
  309. if env.PY3:
  310. arcz = ".1 12 -22 2-2 23 34 42 2."
  311. else:
  312. arcz = ".1 12 23 34 42 2."
  313. self.check_coverage("""\
  314. o = [(1,2), (3,4)]
  315. for tup in [a for a in o]:
  316. x = tup[0]
  317. y = tup[1]
  318. """,
  319. arcz=arcz,
  320. )
  321. def test_generator_expression(self):
  322. # Generator expression:
  323. self.check_coverage("""\
  324. o = ((1,2), (3,4))
  325. o = (a for a in o)
  326. for tup in o:
  327. x = tup[0]
  328. y = tup[1]
  329. """,
  330. arcz=".1 -22 2-2 12 23 34 45 53 3.",
  331. )
  332. def test_other_comprehensions(self):
  333. if env.PYVERSION < (2, 7):
  334. self.skipTest("Don't have set or dict comprehensions before 2.7")
  335. # Set comprehension:
  336. self.check_coverage("""\
  337. o = ((1,2), (3,4))
  338. o = {a for a in o}
  339. for tup in o:
  340. x = tup[0]
  341. y = tup[1]
  342. """,
  343. arcz=".1 -22 2-2 12 23 34 45 53 3.",
  344. )
  345. # Dict comprehension:
  346. self.check_coverage("""\
  347. o = ((1,2), (3,4))
  348. o = {a:1 for a in o}
  349. for tup in o:
  350. x = tup[0]
  351. y = tup[1]
  352. """,
  353. arcz=".1 -22 2-2 12 23 34 45 53 3.",
  354. )
  355. def test_multiline_dict_comp(self):
  356. if env.PYVERSION < (2, 7):
  357. self.skipTest("Don't have set or dict comprehensions before 2.7")
  358. if env.PYVERSION < (3, 5):
  359. arcz = "-42 2B B-4 2-4"
  360. else:
  361. arcz = "-32 2B B-3 2-3"
  362. # Multiline dict comp:
  363. self.check_coverage("""\
  364. # comment
  365. d = \\
  366. {
  367. i:
  368. str(i)
  369. for
  370. i
  371. in
  372. range(9)
  373. }
  374. x = 11
  375. """,
  376. arcz=arcz,
  377. )
  378. # Multi dict comp:
  379. if env.PYVERSION < (3, 5):
  380. arcz = "-42 2F F-4 2-4"
  381. else:
  382. arcz = "-32 2F F-3 2-3"
  383. self.check_coverage("""\
  384. # comment
  385. d = \\
  386. {
  387. (i, j):
  388. str(i+j)
  389. for
  390. i
  391. in
  392. range(9)
  393. for
  394. j
  395. in
  396. range(13)
  397. }
  398. x = 15
  399. """,
  400. arcz=arcz,
  401. )
  402. class ExceptionArcTest(CoverageTest):
  403. """Arc-measuring tests involving exception handling."""
  404. def test_try_except(self):
  405. self.check_coverage("""\
  406. a, b = 1, 1
  407. try:
  408. a = 3
  409. except:
  410. b = 5
  411. assert a == 3 and b == 1
  412. """,
  413. arcz=".1 12 23 36 45 56 6.", arcz_missing="45 56")
  414. self.check_coverage("""\
  415. a, b = 1, 1
  416. try:
  417. a = 3
  418. raise Exception("Yikes!")
  419. a = 5
  420. except:
  421. b = 7
  422. assert a == 3 and b == 7
  423. """,
  424. arcz=".1 12 23 34 46 58 67 78 8.",
  425. arcz_missing="58",
  426. )
  427. def test_hidden_raise(self):
  428. self.check_coverage("""\
  429. a, b = 1, 1
  430. def oops(x):
  431. if x % 2:
  432. raise Exception("odd")
  433. try:
  434. a = 6
  435. oops(1)
  436. a = 8
  437. except:
  438. b = 10
  439. assert a == 6 and b == 10
  440. """,
  441. arcz=".1 12 -23 34 3-2 4-2 25 56 67 78 8B 9A AB B.",
  442. arcz_missing="3-2 78 8B", arcz_unpredicted="79",
  443. )
  444. def test_except_with_type(self):
  445. self.check_coverage("""\
  446. a, b = 1, 1
  447. def oops(x):
  448. if x % 2:
  449. raise ValueError("odd")
  450. def try_it(x):
  451. try:
  452. a = 7
  453. oops(x)
  454. a = 9
  455. except ValueError:
  456. b = 11
  457. return a
  458. assert try_it(0) == 9 # C
  459. assert try_it(1) == 7 # D
  460. """,
  461. arcz=".1 12 -23 34 3-2 4-2 25 5D DE E. -56 67 78 89 9C AB BC C-5",
  462. arcz_unpredicted="8A",
  463. )
  464. def test_try_finally(self):
  465. self.check_coverage("""\
  466. a, c = 1, 1
  467. try:
  468. a = 3
  469. finally:
  470. c = 5
  471. assert a == 3 and c == 5
  472. """,
  473. arcz=".1 12 23 35 56 6.",
  474. )
  475. self.check_coverage("""\
  476. a, c, d = 1, 1, 1
  477. try:
  478. try:
  479. a = 4
  480. finally:
  481. c = 6
  482. except:
  483. d = 8
  484. assert a == 4 and c == 6 and d == 1 # 9
  485. """,
  486. arcz=".1 12 23 34 46 78 89 69 9.",
  487. arcz_missing="78 89",
  488. )
  489. self.check_coverage("""\
  490. a, c, d = 1, 1, 1
  491. try:
  492. try:
  493. a = 4
  494. raise Exception("Yikes!")
  495. a = 6
  496. finally:
  497. c = 8
  498. except:
  499. d = 10 # A
  500. assert a == 4 and c == 8 and d == 10 # B
  501. """,
  502. arcz=".1 12 23 34 45 58 68 89 8B 9A AB B.",
  503. arcz_missing="68 8B",
  504. )
  505. def test_finally_in_loop(self):
  506. self.check_coverage("""\
  507. a, c, d, i = 1, 1, 1, 99
  508. try:
  509. for i in range(5):
  510. try:
  511. a = 5
  512. if i > 0:
  513. raise Exception("Yikes!")
  514. a = 8
  515. finally:
  516. c = 10
  517. except:
  518. d = 12 # C
  519. assert a == 5 and c == 10 and d == 12 # D
  520. """,
  521. arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.",
  522. arcz_missing="3D",
  523. )
  524. self.check_coverage("""\
  525. a, c, d, i = 1, 1, 1, 99
  526. try:
  527. for i in range(5):
  528. try:
  529. a = 5
  530. if i > 10:
  531. raise Exception("Yikes!")
  532. a = 8
  533. finally:
  534. c = 10
  535. except:
  536. d = 12 # C
  537. assert a == 8 and c == 10 and d == 1 # D
  538. """,
  539. arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AB BC CD D.",
  540. arcz_missing="67 7A AB BC CD",
  541. )
  542. def test_break_through_finally(self):
  543. self.check_coverage("""\
  544. a, c, d, i = 1, 1, 1, 99
  545. try:
  546. for i in range(3):
  547. try:
  548. a = 5
  549. if i > 0:
  550. break
  551. a = 8
  552. finally:
  553. c = 10
  554. except:
  555. d = 12 # C
  556. assert a == 5 and c == 10 and d == 1 # D
  557. """,
  558. arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 AD BC CD D.",
  559. arcz_missing="3D BC CD",
  560. )
  561. def test_continue_through_finally(self):
  562. self.check_coverage("""\
  563. a, b, c, d, i = 1, 1, 1, 1, 99
  564. try:
  565. for i in range(5):
  566. try:
  567. a = 5
  568. if i > 0:
  569. continue
  570. b = 8
  571. finally:
  572. c = 10
  573. except:
  574. d = 12 # C
  575. assert (a, b, c, d) == (5, 8, 10, 1) # D
  576. """,
  577. arcz=".1 12 23 34 3D 45 56 67 68 7A 8A A3 BC CD D.",
  578. arcz_missing="BC CD",
  579. )
  580. def test_finally_in_loop_bug_92(self):
  581. self.check_coverage("""\
  582. for i in range(5):
  583. try:
  584. j = 3
  585. finally:
  586. f = 5
  587. g = 6
  588. h = 7
  589. """,
  590. arcz=".1 12 23 35 56 61 17 7.",
  591. )
  592. def test_bug_212(self):
  593. # "except Exception as e" is crucial here.
  594. self.check_coverage("""\
  595. def b(exc):
  596. try:
  597. while 1:
  598. raise Exception(exc) # 4
  599. except Exception as e:
  600. if exc != 'expected':
  601. raise
  602. q = 8
  603. b('expected')
  604. try:
  605. b('unexpected') # C
  606. except:
  607. pass
  608. """,
  609. arcz=".1 .2 1A 23 34 45 56 67 68 7. 8. AB BC C. DE E.",
  610. arcz_missing="C.", arcz_unpredicted="CD")
  611. def test_except_finally(self):
  612. self.check_coverage("""\
  613. a, b, c = 1, 1, 1
  614. try:
  615. a = 3
  616. except:
  617. b = 5
  618. finally:
  619. c = 7
  620. assert a == 3 and b == 1 and c == 7
  621. """,
  622. arcz=".1 12 23 45 37 57 78 8.", arcz_missing="45 57")
  623. self.check_coverage("""\
  624. a, b, c = 1, 1, 1
  625. def oops(x):
  626. if x % 2: raise Exception("odd")
  627. try:
  628. a = 5
  629. oops(1)
  630. a = 7
  631. except:
  632. b = 9
  633. finally:
  634. c = 11
  635. assert a == 5 and b == 9 and c == 11
  636. """,
  637. arcz=".1 12 -23 3-2 24 45 56 67 7B 89 9B BC C.",
  638. arcz_missing="67 7B", arcz_unpredicted="68")
  639. def test_multiple_except_clauses(self):
  640. self.check_coverage("""\
  641. a, b, c = 1, 1, 1
  642. try:
  643. a = 3
  644. except ValueError:
  645. b = 5
  646. except IndexError:
  647. a = 7
  648. finally:
  649. c = 9
  650. assert a == 3 and b == 1 and c == 9
  651. """,
  652. arcz=".1 12 23 45 46 39 59 67 79 9A A.",
  653. arcz_missing="45 59 46 67 79",
  654. )
  655. self.check_coverage("""\
  656. a, b, c = 1, 1, 1
  657. try:
  658. a = int("xyz") # ValueError
  659. except ValueError:
  660. b = 5
  661. except IndexError:
  662. a = 7
  663. finally:
  664. c = 9
  665. assert a == 1 and b == 5 and c == 9
  666. """,
  667. arcz=".1 12 23 45 46 39 59 67 79 9A A.",
  668. arcz_missing="39 46 67 79",
  669. arcz_unpredicted="34",
  670. )
  671. self.check_coverage("""\
  672. a, b, c = 1, 1, 1
  673. try:
  674. a = [1][3] # IndexError
  675. except ValueError:
  676. b = 5
  677. except IndexError:
  678. a = 7
  679. finally:
  680. c = 9
  681. assert a == 7 and b == 1 and c == 9
  682. """,
  683. arcz=".1 12 23 45 46 39 59 67 79 9A A.",
  684. arcz_missing="39 45 59",
  685. arcz_unpredicted="34",
  686. )
  687. self.check_coverage("""\
  688. a, b, c = 1, 1, 1
  689. try:
  690. try:
  691. a = 4/0 # ZeroDivisionError
  692. except ValueError:
  693. b = 6
  694. except IndexError:
  695. a = 8
  696. finally:
  697. c = 10
  698. except ZeroDivisionError:
  699. pass
  700. assert a == 1 and b == 1 and c == 10
  701. """,
  702. arcz=".1 12 23 34 4A 56 6A 57 78 8A AD BC CD D.",
  703. arcz_missing="4A 56 6A 78 8A AD",
  704. arcz_unpredicted="45 7A AB",
  705. )
  706. def test_return_finally(self):
  707. self.check_coverage("""\
  708. a = [1]
  709. def func():
  710. try:
  711. return 10
  712. finally:
  713. a.append(6)
  714. assert func() == 10
  715. assert a == [1, 6]
  716. """,
  717. arcz=".1 12 28 89 9. -23 34 46 6-2",
  718. )
  719. def test_except_jump_finally(self):
  720. self.check_coverage("""\
  721. def func(x):
  722. a = f = g = 2
  723. try:
  724. for i in range(4):
  725. try:
  726. 6/0
  727. except ZeroDivisionError:
  728. if x == 'break':
  729. a = 9
  730. break
  731. elif x == 'continue':
  732. a = 12
  733. continue
  734. elif x == 'return':
  735. a = 15 # F
  736. return a, f, g, i # G
  737. elif x == 'raise': # H
  738. a = 18 # I
  739. raise ValueError() # J
  740. finally:
  741. f = 21 # L
  742. except ValueError: # M
  743. g = 23 # N
  744. return a, f, g, i # O
  745. assert func('break') == (9, 21, 2, 0) # Q
  746. assert func('continue') == (12, 21, 2, 3) # R
  747. assert func('return') == (15, 2, 2, 0) # S
  748. assert func('raise') == (18, 21, 23, 0) # T
  749. """,
  750. arcz=
  751. ".1 1Q QR RS ST T. "
  752. ".2 23 34 45 56 4O 6L "
  753. "78 89 9A AL 8B BC CD DL BE EF FG GL EH HI IJ JL HL "
  754. "LO L4 L. LM "
  755. "MN NO O.",
  756. arcz_missing="6L HL",
  757. arcz_unpredicted="67",
  758. )
  759. def test_else_jump_finally(self):
  760. self.check_coverage("""\
  761. def func(x):
  762. a = f = g = 2
  763. try:
  764. for i in range(4):
  765. try:
  766. b = 6
  767. except ZeroDivisionError:
  768. pass
  769. else:
  770. if x == 'break':
  771. a = 11
  772. break
  773. elif x == 'continue':
  774. a = 14
  775. continue
  776. elif x == 'return':
  777. a = 17 # H
  778. return a, f, g, i # I
  779. elif x == 'raise': # J
  780. a = 20 # K
  781. raise ValueError() # L
  782. finally:
  783. f = 23 # N
  784. except ValueError: # O
  785. g = 25 # P
  786. return a, f, g, i # Q
  787. assert func('break') == (11, 23, 2, 0) # S
  788. assert func('continue') == (14, 23, 2, 3) # T
  789. assert func('return') == (17, 2, 2, 0) # U
  790. assert func('raise') == (20, 23, 25, 0) # V
  791. """,
  792. arcz=
  793. ".1 1S ST TU UV V. "
  794. ".2 23 34 45 56 6A 78 8N 4Q "
  795. "AB BC CN AD DE EF FN DG GH HI IN GJ JK KL LN JN "
  796. "NQ N4 N. NO "
  797. "OP PQ Q.",
  798. arcz_missing="78 8N JN",
  799. arcz_unpredicted="",
  800. )
  801. class YieldTest(CoverageTest):
  802. """Arc tests for generators."""
  803. def test_yield_in_loop(self):
  804. self.check_coverage("""\
  805. def gen(inp):
  806. for n in inp:
  807. yield n
  808. list(gen([1,2,3]))
  809. """,
  810. arcz=".1 .2 23 2. 32 15 5.",
  811. )
  812. def test_padded_yield_in_loop(self):
  813. self.check_coverage("""\
  814. def gen(inp):
  815. i = 2
  816. for n in inp:
  817. i = 4
  818. yield n
  819. i = 6
  820. i = 7
  821. list(gen([1,2,3]))
  822. """,
  823. arcz=".1 19 9. .2 23 34 45 56 63 37 7.",
  824. )
  825. def test_bug_308(self):
  826. self.check_coverage("""\
  827. def run():
  828. for i in range(10):
  829. yield lambda: i
  830. for f in run():
  831. print(f())
  832. """,
  833. arcz=".1 15 56 65 5. .2 23 32 2. -33 3-3",
  834. )
  835. self.check_coverage("""\
  836. def run():
  837. yield lambda: 100
  838. for i in range(10):
  839. yield lambda: i
  840. for f in run():
  841. print(f())
  842. """,
  843. arcz=".1 16 67 76 6. .2 23 34 43 3. -22 2-2 -44 4-4",
  844. )
  845. self.check_coverage("""\
  846. def run():
  847. yield lambda: 100 # no branch miss
  848. for f in run():
  849. print(f())
  850. """,
  851. arcz=".1 14 45 54 4. .2 2. -22 2-2",
  852. )
  853. def test_bug_324(self):
  854. # This code is tricky: the list() call pulls all the values from gen(),
  855. # but each of them is a generator itself that is never iterated. As a
  856. # result, the generator expression on line 3 is never entered or run.
  857. self.check_coverage("""\
  858. def gen(inp):
  859. for n in inp:
  860. yield (i * 2 for i in range(n))
  861. list(gen([1,2,3]))
  862. """,
  863. arcz=
  864. ".1 15 5. " # The module level
  865. ".2 23 32 2. " # The gen() function
  866. "-33 3-3", # The generator expression
  867. arcz_missing="-33 3-3",
  868. )
  869. def test_coroutines(self):
  870. self.check_coverage("""\
  871. def double_inputs():
  872. while len([1]): # avoid compiler differences
  873. x = yield
  874. x *= 2
  875. yield x
  876. gen = double_inputs()
  877. next(gen)
  878. print(gen.send(10))
  879. next(gen)
  880. print(gen.send(6))
  881. """,
  882. arcz=
  883. ".1 17 78 89 9A AB B. "
  884. ".2 23 34 45 52 2.",
  885. arcz_missing="2.",
  886. )
  887. self.assertEqual(self.stdout(), "20\n12\n")
  888. def test_yield_from(self):
  889. if env.PYVERSION < (3, 3):
  890. self.skipTest("Python before 3.3 doesn't have 'yield from'")
  891. self.check_coverage("""\
  892. def gen(inp):
  893. i = 2
  894. for n in inp:
  895. i = 4
  896. yield from range(3)
  897. i = 6
  898. i = 7
  899. list(gen([1,2,3]))
  900. """,
  901. arcz=".1 19 9. .2 23 34 45 56 63 37 7.",
  902. arcz_unpredicted="5.",
  903. )
  904. def test_abandoned_yield(self):
  905. # https://bitbucket.org/ned/coveragepy/issue/440
  906. self.check_coverage("""\
  907. def gen():
  908. print("yup")
  909. yield "yielded"
  910. print("nope")
  911. print(next(gen()))
  912. """,
  913. lines=[1, 2, 3, 4, 6],
  914. missing="4",
  915. arcz=".1 16 6. .2 23 34 4.",
  916. arcz_missing="34 4.",
  917. )
  918. class MiscArcTest(CoverageTest):
  919. """Miscellaneous arc-measuring tests."""
  920. def test_dict_literal(self):
  921. if env.PYVERSION < (3, 5):
  922. arcz = ".1 19 9."
  923. else:
  924. # Python 3.5 changed how dict literals are constructed.
  925. arcz = "-21 19 9-2"
  926. self.check_coverage("""\
  927. d = {
  928. 'a': 2,
  929. 'b': 3,
  930. 'c': {
  931. 'd': 5,
  932. 'e': 6,
  933. }
  934. }
  935. assert d
  936. """,
  937. arcz=arcz,
  938. )
  939. self.check_coverage("""\
  940. d = \\
  941. { 'a': 2,
  942. 'b': 3,
  943. 'c': {
  944. 'd': 5,
  945. 'e': 6,
  946. }
  947. }
  948. assert d
  949. """,
  950. arcz="-21 19 9-2",
  951. )
  952. def test_unpacked_literals(self):
  953. if env.PYVERSION < (3, 5):
  954. self.skipTest("Don't have unpacked literals until 3.5")
  955. self.check_coverage("""\
  956. d = {
  957. 'a': 2,
  958. 'b': 3,
  959. }
  960. weird = {
  961. **d,
  962. **{'c': 7},
  963. 'd': 8,
  964. }
  965. assert weird['b'] == 3
  966. """,
  967. arcz="-21 15 5A A-2"
  968. )
  969. self.check_coverage("""\
  970. l = [
  971. 2,
  972. 3,
  973. ]
  974. weird = [
  975. *l,
  976. *[7],
  977. 8,
  978. ]
  979. assert weird[1] == 3
  980. """,
  981. arcz="-21 15 5A A-2"
  982. )
  983. def test_pathologically_long_code_object(self):
  984. # https://bitbucket.org/ned/coveragepy/issue/359
  985. # The structure of this file is such that an EXTENDED_ARG bytecode is
  986. # needed to encode the jump at the end. We weren't interpreting those
  987. # opcodes.
  988. # Note that we no longer interpret bytecode at all, but it couldn't
  989. # hurt to keep the test...
  990. code = """\
  991. data = [
  992. """ + "".join("""\
  993. [
  994. {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}, {i}],
  995. """.format(i=i) for i in range(2000)
  996. ) + """\
  997. ]
  998. print(len(data))
  999. """
  1000. self.check_coverage(
  1001. code,
  1002. arcs=[(-3, 1), (1, 4004), (4004, -3)],
  1003. arcs_missing=[], arcs_unpredicted=[],
  1004. )
  1005. def test_optimized_away_lines(self):
  1006. self.check_coverage("""\
  1007. a = 1
  1008. if len([2]):
  1009. c = 3
  1010. if 0: # this line isn't in the compiled code.
  1011. if len([5]):
  1012. d = 6
  1013. e = 7
  1014. """,
  1015. lines=[1, 2, 3, 7],
  1016. arcz=".1 12 23 27 37 7.",
  1017. arcz_missing="27",
  1018. )
  1019. def test_partial_generators(self):
  1020. # https://bitbucket.org/ned/coveragepy/issues/475/generator-expression-is-marked-as-not
  1021. # Line 2 is executed completely.
  1022. # Line 3 is started but not finished, because zip ends when #2 ends.
  1023. # Line 4 is never started.
  1024. cov = self.check_coverage("""\
  1025. def f(a, b):
  1026. c = (i for i in a) # 2
  1027. d = (j for j in b) # 3
  1028. e = (k for k in b) # 4
  1029. return dict(zip(c, d))
  1030. f(['a', 'b'], [1, 2])
  1031. """,
  1032. arcz=".1 17 7. .2 23 34 45 5. -22 2-2 -33 3-3 -44 4-4",
  1033. arcz_missing="3-3 -44 4-4",
  1034. )
  1035. # ugh, unexposed methods??
  1036. filename = self.last_module_name + ".py"
  1037. fr = cov._get_file_reporter(filename)
  1038. arcs_executed = cov._analyze(filename).arcs_executed()
  1039. self.assertEqual(
  1040. fr.missing_arc_description(3, -3, arcs_executed),
  1041. "line 3 didn't finish the generator expression on line 3"
  1042. )
  1043. self.assertEqual(
  1044. fr.missing_arc_description(4, -4, arcs_executed),
  1045. "line 4 didn't run the generator expression on line 4"
  1046. )
  1047. class DecoratorArcTest(CoverageTest):
  1048. """Tests of arcs with decorators."""
  1049. def test_function_decorator(self):
  1050. self.check_coverage("""\
  1051. def decorator(arg):
  1052. def _dec(f):
  1053. return f
  1054. return _dec
  1055. @decorator(6)
  1056. @decorator(
  1057. len([8]),
  1058. )
  1059. def my_function(
  1060. a=len([11]),
  1061. ):
  1062. x = 13
  1063. a = 14
  1064. my_function()
  1065. """,
  1066. arcz=
  1067. ".1 16 67 7A AE EF F. " # main line
  1068. ".2 24 4. -23 3-2 " # decorators
  1069. "-6D D-6 ", # my_function
  1070. )
  1071. def test_class_decorator(self):
  1072. self.check_coverage("""\
  1073. def decorator(arg):
  1074. def _dec(c):
  1075. return c
  1076. return _dec
  1077. @decorator(6)
  1078. @decorator(
  1079. len([8]),
  1080. )
  1081. class MyObject(
  1082. object
  1083. ):
  1084. X = 13
  1085. a = 14
  1086. """,
  1087. arcz=
  1088. ".1 16 67 6D 7A AE E. " # main line
  1089. ".2 24 4. -23 3-2 " # decorators
  1090. "-66 D-6 ", # MyObject
  1091. )
  1092. def test_bug_466(self):
  1093. # A bad interaction between decorators and multi-line list assignments,
  1094. # believe it or not...!
  1095. self.check_coverage("""\
  1096. class Parser(object):
  1097. @classmethod
  1098. def parse(cls):
  1099. formats = [ 5 ]
  1100. return None
  1101. Parser.parse()
  1102. """,
  1103. arcz=".1 1A A. 13 3. -35 58 8-3",
  1104. )
  1105. self.check_coverage("""\
  1106. class Parser(object):
  1107. @classmethod
  1108. def parse(cls):
  1109. formats = [
  1110. 6,
  1111. ]
  1112. return None
  1113. Parser.parse()
  1114. """,
  1115. arcz=".1 1A A. 13 3. -35 58 8-3",
  1116. )
  1117. class LambdaArcTest(CoverageTest):
  1118. """Tests of lambdas"""
  1119. def test_multiline_lambda(self):
  1120. self.check_coverage("""\
  1121. fn = (lambda x:
  1122. x + 2
  1123. )
  1124. assert fn(4) == 6
  1125. """,
  1126. arcz=".1 14 4-1 1-1",
  1127. )
  1128. self.check_coverage("""\
  1129. fn = \\
  1130. (
  1131. lambda
  1132. x:
  1133. x
  1134. +
  1135. 8
  1136. )
  1137. assert fn(10) == 18
  1138. """,
  1139. arcz="-42 2A A-4 2-4",
  1140. )
  1141. def test_unused_lambdas_are_confusing_bug_90(self):
  1142. self.check_coverage("""\
  1143. a = 1
  1144. fn = lambda x: x
  1145. b = 3
  1146. """,
  1147. arcz=".1 12 -22 2-2 23 3.", arcz_missing="-22 2-2",
  1148. )
  1149. def test_raise_with_lambda_looks_like_partial_branch(self):
  1150. self.check_coverage("""\
  1151. def ouch(fn):
  1152. 2/0
  1153. a = b = c = d = 3
  1154. try:
  1155. a = ouch(lambda: 5)
  1156. if a:
  1157. b = 7
  1158. except ZeroDivisionError:
  1159. c = 9
  1160. d = 10
  1161. assert (a, b, c, d) == (3, 3, 9, 10)
  1162. """,
  1163. lines=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
  1164. missing="6-7",
  1165. arcz=".1 13 34 45 56 67 6A 7A 89 9A AB B. .2 2. -55 5-5",
  1166. arcz_missing="56 67 6A 7A -55 5-5",
  1167. arcz_unpredicted="58",
  1168. )
  1169. def test_lambda_in_dict(self):
  1170. self.check_coverage("""\
  1171. x = 1
  1172. x = 2
  1173. d = {
  1174. 4: lambda: [],
  1175. 5: lambda: [],
  1176. 6: lambda: [],
  1177. 7: lambda: [],
  1178. }
  1179. for k, v in d.items(): # 10
  1180. if k & 1:
  1181. v()
  1182. """,
  1183. arcz=".1 12 23 3A AB BC BA CA A. -43 -53 -63 -73 3-4 3-5 3-6 3-7",
  1184. arcz_missing="-43 3-4 -63 3-6",
  1185. arcz_unpredicted="",
  1186. )
  1187. class AsyncTest(CoverageTest):
  1188. """Tests of the new async and await keywords in Python 3.5"""
  1189. def setUp(self):
  1190. if env.PYVERSION < (3, 5):
  1191. self.skipTest("Async features are new in Python 3.5")
  1192. super(AsyncTest, self).setUp()
  1193. def test_async(self):
  1194. self.check_coverage("""\
  1195. import asyncio
  1196. async def compute(x, y): # 3
  1197. print("Compute %s + %s ..." % (x, y))
  1198. await asyncio.sleep(0.001)
  1199. return x + y # 6
  1200. async def print_sum(x, y): # 8
  1201. result = (0 +
  1202. await compute(x, y) # A
  1203. )
  1204. print("%s + %s = %s" % (x, y, result))
  1205. loop = asyncio.get_event_loop() # E
  1206. loop.run_until_complete(print_sum(1, 2))
  1207. loop.close() # G
  1208. """,
  1209. arcz=
  1210. ".1 13 38 8E EF FG G. "
  1211. "-34 45 56 6-3 "
  1212. "-89 9C C-8",
  1213. arcz_unpredicted="5-3 9-8",
  1214. )
  1215. self.assertEqual(self.stdout(), "Compute 1 + 2 ...\n1 + 2 = 3\n")
  1216. def test_async_for(self):
  1217. self.check_coverage("""\
  1218. import asyncio
  1219. class AsyncIteratorWrapper: # 3
  1220. def __init__(self, obj): # 4
  1221. self._it = iter(obj)
  1222. async def __aiter__(self): # 7
  1223. return self
  1224. async def __anext__(self): # A
  1225. try:
  1226. return next(self._it)
  1227. except StopIteration:
  1228. raise StopAsyncIteration
  1229. async def doit(): # G
  1230. async for letter in AsyncIteratorWrapper("abc"):
  1231. print(letter)
  1232. print(".")
  1233. loop = asyncio.get_event_loop() # L
  1234. loop.run_until_complete(doit())
  1235. loop.close()
  1236. """,
  1237. arcz=
  1238. ".1 13 3G GL LM MN N. " # module main line
  1239. "-33 34 47 7A A-3 " # class definition
  1240. "-GH HI IH HJ J-G " # doit
  1241. "-45 5-4 " # __init__
  1242. "-78 8-7 " # __aiter__
  1243. "-AB BC C-A DE E-A ", # __anext__
  1244. arcz_unpredicted="CD",
  1245. )
  1246. self.assertEqual(self.stdout(), "a\nb\nc\n.\n")
  1247. def test_async_with(self):
  1248. self.check_coverage("""\
  1249. async def go():
  1250. async with x:
  1251. pass
  1252. """,
  1253. arcz=".1 1. .2 23 3.",
  1254. arcz_missing=".2 23 3.",
  1255. )
  1256. class ExcludeTest(CoverageTest):
  1257. """Tests of exclusions to indicate known partial branches."""
  1258. def test_default(self):
  1259. # A number of forms of pragma comment are accepted.
  1260. self.check_coverage("""\
  1261. a = 1
  1262. if a: #pragma: no branch
  1263. b = 3
  1264. c = 4
  1265. if c: # pragma NOBRANCH
  1266. d = 6
  1267. e = 7
  1268. if e:#\tpragma:\tno branch
  1269. f = 9
  1270. """,
  1271. [1,2,3,4,5,6,7,8,9],
  1272. arcz=".1 12 23 24 34 45 56 57 67 78 89 9. 8.",
  1273. )
  1274. def test_custom_pragmas(self):
  1275. self.check_coverage("""\
  1276. a = 1
  1277. while a: # [only some]
  1278. c = 3
  1279. break
  1280. assert c == 5-2
  1281. """,
  1282. [1,2,3,4,5],
  1283. partials=["only some"],
  1284. arcz=".1 12 23 34 45 25 5.",
  1285. )
  1286. class LineDataTest(CoverageTest):
  1287. """Tests that line_data gives us what we expect."""
  1288. def test_branch(self):
  1289. cov = coverage.Coverage(branch=True)
  1290. self.make_file("fun1.py", """\
  1291. def fun1(x):
  1292. if x == 1:
  1293. return
  1294. fun1(3)
  1295. """)
  1296. self.start_import_stop(cov, "fun1")
  1297. data = cov.get_data()
  1298. fun1_lines = data.lines(abs_file("fun1.py"))
  1299. self.assertCountEqual(fun1_lines, [1, 2, 5])