[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.
--Ned.
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