summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgtags1
-rw-r--r--CHANGES.txt9
-rw-r--r--coverage/__init__.py2
-rw-r--r--coverage/bytecode.py9
-rw-r--r--coverage/parser.py2
-rw-r--r--test/coveragetest.py3
-rw-r--r--test/farm/html/run_b_branch.py6
-rw-r--r--test/farm/html/src/b.py19
-rw-r--r--test/test_arcs.py19
9 files changed, 54 insertions, 16 deletions
diff --git a/.hgtags b/.hgtags
index 8b322ddd..54ec5bf0 100644
--- a/.hgtags
+++ b/.hgtags
@@ -24,3 +24,4 @@ f63624fedea89b2acb361e1d7d6c5375ebced2aa coverage-3.3
fcc4407bece6ca1266c91734bfdc657b66e10290 coverage-3.4b2
25f2c1579f1c9539b2c140b86f6c00cbfbf4c565 coverage-3.4
b7db1026817a4ae98c58c561f6ef79e95d0e13f9 coverage-3.5b1
+7be6416f60b90b75d8c81e5369612b7f48dc26cd coverage-3.5
diff --git a/CHANGES.txt b/CHANGES.txt
index c3da3f4e..71aa26d3 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -2,6 +2,15 @@
Change history for Coverage.py
------------------------------
+Version 3.5.1
+-------------
+
+- for-else constructs are understood better, and don't cause erroneous partial
+ branch warnings. Fixes `issue 122`_.
+
+.. _issue 122: http://bitbucket.org/ned/coveragepy/issue/122/for-else-always-reports-missing-branch
+
+
Version 3.5 --- 29 June 2011
----------------------------
diff --git a/coverage/__init__.py b/coverage/__init__.py
index d8dbc0f6..0a6c75c4 100644
--- a/coverage/__init__.py
+++ b/coverage/__init__.py
@@ -5,7 +5,7 @@ http://nedbatchelder.com/code/coverage
"""
-__version__ = "3.5" # see detailed history in CHANGES.txt
+__version__ = "3.5.1a0" # see detailed history in CHANGES.txt
__url__ = "http://nedbatchelder.com/code/coverage"
if max(__version__).isalpha():
diff --git a/coverage/bytecode.py b/coverage/bytecode.py
index ab522d6c..61c311eb 100644
--- a/coverage/bytecode.py
+++ b/coverage/bytecode.py
@@ -5,10 +5,19 @@ import opcode, sys, types
class ByteCode(object):
"""A single bytecode."""
def __init__(self):
+ # The offset of this bytecode in the code object.
self.offset = -1
+
+ # The opcode, defined in the `opcode` module.
self.op = -1
+
+ # The argument, a small integer, whose meaning depends on the opcode.
self.arg = -1
+
+ # The offset in the code object of the next bytecode.
self.next_offset = -1
+
+ # The offset to jump to.
self.jump_to = -1
diff --git a/coverage/parser.py b/coverage/parser.py
index cbbb5a6a..b65689c4 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -297,7 +297,7 @@ OPS_EXCEPT_BLOCKS = _opcode_set('SETUP_EXCEPT', 'SETUP_FINALLY')
OPS_POP_BLOCK = _opcode_set('POP_BLOCK')
# Opcodes that have a jump destination, but aren't really a jump.
-OPS_NO_JUMP = _opcode_set('SETUP_EXCEPT', 'SETUP_FINALLY')
+OPS_NO_JUMP = OPS_PUSH_BLOCK
# Individual opcodes we need below.
OP_BREAK_LOOP = _opcode('BREAK_LOOP')
diff --git a/test/coveragetest.py b/test/coveragetest.py
index a94f5122..3242e52f 100644
--- a/test/coveragetest.py
+++ b/test/coveragetest.py
@@ -32,6 +32,9 @@ class CoverageTest(TestCase):
run_in_temp_dir = True
def setUp(self):
+ # Tell newer unittest implementations to print long helpful messages.
+ self.longMessage = True
+
# tearDown will restore the original sys.path
self.old_syspath = sys.path[:]
diff --git a/test/farm/html/run_b_branch.py b/test/farm/html/run_b_branch.py
index f129e436..31543398 100644
--- a/test/farm/html/run_b_branch.py
+++ b/test/farm/html/run_b_branch.py
@@ -15,14 +15,14 @@ compare("gold_b_branch", "html_b_branch", size_within=10, file_pattern="*.html")
contains("html_b_branch/b.html",
"<span class='key'>if</span> <span class='nam'>x</span> <span class='op'>&lt;</span> <span class='num'>2</span>",
"&nbsp; &nbsp; <span class='nam'>a</span> <span class='op'>=</span> <span class='num'>3</span>",
- "<span class='pc_cov'>76%</span>",
+ "<span class='pc_cov'>70%</span>",
"<span class='annotate' title='no jump to this line number'>8</span>",
"<span class='annotate' title='no jump to this line number'>exit</span>",
- "<span class='annotate' title='no jumps to these line numbers'>25&nbsp;&nbsp; 26</span>",
+ "<span class='annotate' title='no jumps to these line numbers'>23&nbsp;&nbsp; 25</span>",
)
contains("html_b_branch/index.html",
"<a href='b.html'>b</a>",
- "<span class='pc_cov'>76%</span>"
+ "<span class='pc_cov'>70%</span>"
)
clean("html_b_branch")
diff --git a/test/farm/html/src/b.py b/test/farm/html/src/b.py
index dffdd50f..3bf73a9f 100644
--- a/test/farm/html/src/b.py
+++ b/test/farm/html/src/b.py
@@ -16,13 +16,14 @@ def two(x):
two(1)
-def three_way():
- # for-else can be a three-way branch.
- for i in range(10):
- if i == 3:
- break
- else:
- return 23
- return 17
+def three():
+ try:
+ # This if has two branches, *neither* one taken.
+ if name_error_this_variable_doesnt_exist:
+ a = 1
+ else:
+ a = 2
+ except:
+ pass
-three_way()
+three()
diff --git a/test/test_arcs.py b/test/test_arcs.py
index 0c169297..2c983170 100644
--- a/test/test_arcs.py
+++ b/test/test_arcs.py
@@ -213,12 +213,12 @@ class LoopArcTest(CoverageTest):
i += 1
assert a == 4 and i == 3
""",
- arcz=".1 12 23 27 34 45 36 63 57 7.",
+ arcz=".1 12 23 34 45 36 63 57 7.",
)
# With "while True", 2.x thinks it's computation, 3.x thinks it's
# constant.
if sys.version_info >= (3, 0):
- arcz = ".1 12 23 27 34 45 36 63 57 7."
+ arcz = ".1 12 23 34 45 36 63 57 7."
else:
arcz = ".1 12 23 27 34 45 36 62 57 7."
self.check_coverage("""\
@@ -260,6 +260,21 @@ class LoopArcTest(CoverageTest):
arcz_missing="26 6."
)
+ def test_for_else(self):
+ self.check_coverage("""\
+ def forelse(seq):
+ for n in seq:
+ if n > 5:
+ break
+ else:
+ print('None of the values were greater than 5')
+ print('Done')
+ forelse([1,2])
+ forelse([1,6])
+ """,
+ arcz=".1 .2 23 32 34 47 26 67 7. 18 89 9."
+ )
+
class ExceptionArcTest(CoverageTest):
"""Arc-measuring tests involving exception handling."""