File tree 4 files changed +54
-5
lines changed
4 files changed +54
-5
lines changed Original file line number Diff line number Diff line change @@ -23,7 +23,10 @@ upgrading your version of coverage.py.
23
23
Unreleased
24
24
----------
25
25
26
- Nothing yet.
26
+ - fix: multi-line ``with `` statements could cause contained branches to be
27
+ incorrectly marked as missing (`issue 1880 `_). This is now fixed.
28
+
29
+ .. _issue 1880 : https://github.com/nedbat/coveragepy/issues/1880
27
30
28
31
29
32
.. start-releases
Original file line number Diff line number Diff line change @@ -81,6 +81,10 @@ class PYBEHAVIOR:
81
81
# When leaving a with-block, do we visit the with-line again for the exit?
82
82
exit_through_with = (PYVERSION >= (3 , 10 , 0 , "beta" ))
83
83
84
+ # When leaving a with-block, do we visit the with-line exactly,
85
+ # or the inner-most context manager?
86
+ exit_with_through_ctxmgr = (PYVERSION >= (3 , 12 ))
87
+
84
88
# Match-case construct.
85
89
match_case = (PYVERSION >= (3 , 10 ))
86
90
Original file line number Diff line number Diff line change @@ -1261,12 +1261,19 @@ def _handle__While(self, node: ast.While) -> set[ArcStart]:
1261
1261
return exits
1262
1262
1263
1263
def _handle__With (self , node : ast .With ) -> set [ArcStart ]:
1264
- start = self .line_for_node (node )
1264
+ if env .PYBEHAVIOR .exit_with_through_ctxmgr :
1265
+ starts = [self .line_for_node (item .context_expr ) for item in node .items ]
1266
+ else :
1267
+ starts = [self .line_for_node (node )]
1265
1268
if env .PYBEHAVIOR .exit_through_with :
1266
- self .current_with_starts .add (start )
1267
- self .all_with_starts .add (start )
1268
- exits = self .process_body (node .body , from_start = ArcStart (start ))
1269
+ for start in starts :
1270
+ self .current_with_starts .add (start )
1271
+ self .all_with_starts .add (start )
1272
+
1273
+ exits = self .process_body (node .body , from_start = ArcStart (starts [- 1 ]))
1274
+
1269
1275
if env .PYBEHAVIOR .exit_through_with :
1276
+ start = starts [- 1 ]
1270
1277
self .current_with_starts .remove (start )
1271
1278
with_exit = {ArcStart (start )}
1272
1279
if exits :
Original file line number Diff line number Diff line change @@ -347,6 +347,41 @@ def test_with_with_lambda(self) -> None:
347
347
branchz_missing = "" ,
348
348
)
349
349
350
+ def test_multiline_with (self ) -> None :
351
+ # https://github.com/nedbat/coveragepy/issues/1880
352
+ self .check_coverage ("""\
353
+ import contextlib, itertools
354
+ nums = itertools.count()
355
+ with (
356
+ contextlib.nullcontext() as x,
357
+ ):
358
+ while next(nums) < 6:
359
+ y = 7
360
+ z = 8
361
+ """ ,
362
+ branchz = "67 68" ,
363
+ branchz_missing = "" ,
364
+ )
365
+
366
+
367
+ def test_multi_multiline_with (self ) -> None :
368
+ # https://github.com/nedbat/coveragepy/issues/1880
369
+ self .check_coverage ("""\
370
+ import contextlib, itertools
371
+ nums = itertools.count()
372
+ with (
373
+ contextlib.nullcontext() as x,
374
+ contextlib.nullcontext() as y,
375
+ contextlib.nullcontext() as z,
376
+ ):
377
+ while next(nums) < 8:
378
+ y = 9
379
+ z = 10
380
+ """ ,
381
+ branchz = "89 8A" ,
382
+ branchz_missing = "" ,
383
+ )
384
+
350
385
351
386
class LoopArcTest (CoverageTest ):
352
387
"""Arc-measuring tests involving loops."""
You can’t perform that action at this time.
0 commit comments