1. Ned Batchelder
  2. coverage.py

Commits

Ned Batchelder  committed 50fbe53

Jumps to jumps could make loops look like they go places they really don't, so start new chunks for every absolute jump. Fixes issue #39.

Comments (0)

Files changed (4)

File CHANGES.txt Modified

View file
  • Ignore whitespace
  • Hide word diff
 
 - Settings are now read from a .coveragerc file.
 
+- Fixed a problem with nested loops having their branch possibilities
+  mischaracterized: `issue 39`_.
+
 - Added an AUTHORS.txt file.
 
+.. _issue 39: http://bitbucket.org/ned/coveragepy/issue/39
+
 
 Version 3.2, 5 December 2009
 ----------------------------

File coverage/parser.py Modified

View file
  • Ignore whitespace
  • Hide word diff
     'BREAK_LOOP', 'CONTINUE_LOOP',
     )
 
+# Opcodes that unconditionally begin a new code chunk.  By starting new chunks
+# with unconditional jump instructions, we neatly deal with jumps to jumps
+# properly.
+OPS_CHUNK_BEGIN = _opcode_set('JUMP_ABSOLUTE', 'JUMP_FORWARD')
+
 # Opcodes that push a block on the block stack.
 OPS_PUSH_BLOCK = _opcode_set('SETUP_LOOP', 'SETUP_EXCEPT', 'SETUP_FINALLY')
 
         ult = penult = None
 
         for bc in ByteCodes(self.code.co_code):
-            # Maybe have to start a new block
+            # Maybe have to start a new chunk
             if bc.offset in bytes_lines_map:
+                # Start a new chunk for each source line number.
                 if chunk:
                     chunk.exits.add(bc.offset)
                 chunk = Chunk(bc.offset, bytes_lines_map[bc.offset])
                 chunks.append(chunk)
+            elif bc.op in OPS_CHUNK_BEGIN:
+                # Jumps deserve their own unnumbered chunk.  This fixes
+                # problems with jumps to jumps getting confused.
+                if chunk:
+                    chunk.exits.add(bc.offset)
+                chunk = Chunk(bc.offset)
+                chunks.append(chunk)
 
             if not chunk:
                 chunk = Chunk(bc.offset)

File lab/cmd-opts.txt Modified

View file
  • Ignore whitespace
  • Hide word diff
             --timid                 bool                [run].timid
 
 
-        --include=directory         [run].include
-        --include=filename
-        --include=module
-        --exclude=directory         [run].exclude
+        --include=directory *       [run].include
+        --include=filename *
+        --include=module *
+        --exclude=directory *       [run].exclude
 
 
 

File test/test_arcs.py Modified

View file
  • Ignore whitespace
  • Hide word diff
             arcz_missing="27"   # while loop never exits naturally.
             )
 
+    def test_for_if_else_for(self):
+        self.check_coverage("""\
+            def branches_2(l):
+                if l:
+                    for e in l:
+                        a = 4
+                else:
+                    a = 6
+
+            def branches_3(l):
+                for x in l:
+                    if x:
+                        for e in l:
+                            a = 12
+                    else:
+                        a = 14
+            
+            branches_2([0,1])
+            branches_3([0,1])
+            """,
+            arcz=
+                ".1 18 8G GH H. "
+                ".2 23 34 43 26 3. 6. "
+                ".9 9A 9. AB BC CB B9 AE E9",
+            arcz_missing="26 6."
+            )
+
 
 class ExceptionArcTest(CoverageTest):
     """Arc-measuring tests involving exception handling."""