[TIP] replacing "break" with "continue" causes line to not be covered w/ coverage.py

Ned Batchelder ned at nedbatchelder.com
Sat Jul 2 18:28:11 PDT 2011

Ah, the joys of code optimizers.  The peephole optimizer recognizes your 
code and optimizes away the continue, essentially turning your if 
statement into a jump directly to the beginning of the loop.  All of 
your tests that change the continue into a different statement break 
that optimization, and "prove" to you that the statement is executed.  
Coverage.py can't measure the continue as being executed because Python 
never reports that it is executed.

When I first discovered this in my own code, I thought, "We've seen this 
before: C compilers have switches to disable optimizations for precisely 
this sort of reason."  I wrote a bug against Python asking for a way to 
disable optimizations in those cases where it's more important to reason 
about the code than for the code to run quickly.  The bug is here: 
http://bugs.python.org/issue2506 , it was frustratingly closed as "won't 
fix".  Raymond Hettinger has argued against complicating the optimizer 
in other places, mostly, it seems due to a lack of automated testing of 
the optimizer, and the fear that comes from that realization.  
Ironically, the best way to test an optimizer is to provide a way to 
completely disable it, and then to run code twice, once with 
optimization and once without, and see that they produce the same results.

Any help you can provide to get people on board with a well-tested 
optimizer that can be completely disabled, would be appreciated.  Until 
then, there's nothing to do except add a "#pragma: no cover" comment to 
that line.


On 7/2/2011 5:22 PM, Laurens Van Houtven wrote:
> Hey.
> I'm experiencing some strange behavior. I have a loop, and when I 
> continue to the next element on some condition, it told me that line 
> wasn't covered. Then, I put a pdb.set_trace() in, and I saw that it 
> was, in fact, being run. I put a raise ValueError() instead of that 
> "continue", and it raised. I replaced "continue" with "break", and now 
> coverage.py thinks the line is covered.
> What could be going on? Here's the diff:
> === modified file 'twisted/positioning/nmea.py'
> --- twisted/positioning/nmea.py    2011-07-02 18:40:44 +0000
> +++ twisted/positioning/nmea.py    2011-07-02 21:14:31 +0000
> @@ -552,7 +552,7 @@
>              prn, azimuth, elevation, snr = values
>              if prn is None or snr is None:
> -                break
> +                continue
>              satellite = base.Satellite(prn, azimuth, elevation, snr)
> self._sentenceData['_partialBeaconInformation'].beacons.add(satellite)
> The code lives in lp:~lvh/twisted/positioning.
> The strange thing is even trial --coverage (which is unrelated to 
> coverage.py...) thinks it's not covered. How can that be?
> cheers
> lvh
> _______________________________________________
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
> http://lists.idyll.org/listinfo/testing-in-python
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/testing-in-python/attachments/20110702/038d6b03/attachment.htm>

More information about the testing-in-python mailing list