diff options
author | loic@dachary.org <loic@dachary.org> | 2016-12-15 18:33:16 +0100 |
---|---|---|
committer | loic@dachary.org <loic@dachary.org> | 2016-12-15 18:33:16 +0100 |
commit | 5c131498d140e172c5471929be4f30c65a200547 (patch) | |
tree | a02534e2f0b9269dea5aca1d8bde889ab859189e | |
parent | 88207df5fa00861bf42f0993b23ce541817b72dd (diff) | |
download | python-coveragepy-git-5c131498d140e172c5471929be4f30c65a200547.tar.gz |
also use AST for while constants in python-2.7 #502
The node.id is set to False, True or None is python-2.7: there is no
reason to only check for it with python-3. It is more reliable than
using the DEFAULT_PARTIAL_ALWAYS regexps on source lines.
close #502
--HG--
branch : issue-502-7
-rw-r--r-- | coverage/parser.py | 11 | ||||
-rw-r--r-- | tests/coveragetest.py | 8 | ||||
-rw-r--r-- | tests/modules/zerocoverage/__init__.py | 1 | ||||
-rw-r--r-- | tests/modules/zerocoverage/__main__.py | 1 | ||||
-rw-r--r-- | tests/modules/zerocoverage/zero.py | 3 | ||||
-rw-r--r-- | tests/test_arcs.py | 21 |
6 files changed, 35 insertions, 10 deletions
diff --git a/coverage/parser.py b/coverage/parser.py index f65e4abb..e2708519 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -644,11 +644,12 @@ class AstArcAnalyzer(object): """Is this a compile-time constant?""" node_name = node.__class__.__name__ if node_name in ["NameConstant", "Num"]: - return True + return "Num" elif node_name == "Name": - if env.PY3 and node.id in ["True", "False", "None"]: - return True - return False + if (( env.PY3 or env.PYVERSION >= (2, 7)) and + node.id in ["True", "False", "None"]): + return "Name" + return None # In the fullness of time, these might be good tests to write: # while EXPR: @@ -950,7 +951,7 @@ class AstArcAnalyzer(object): def _handle__While(self, node): constant_test = self.is_constant_expr(node.test) start = to_top = self.line_for_node(node.test) - if constant_test: + if constant_test and (env.PY3 or constant_test == "Num"): to_top = self.line_for_node(node.body[0]) self.block_stack.append(LoopBlock(start=to_top)) from_start = ArcStart(start, cause="the condition on line {lineno} was never true") diff --git a/tests/coveragetest.py b/tests/coveragetest.py index dacb9b63..4a917192 100644 --- a/tests/coveragetest.py +++ b/tests/coveragetest.py @@ -397,9 +397,8 @@ class CoverageTest( # Add our test modules directory to PYTHONPATH. I'm sure there's too # much path munging here, but... - here = os.path.dirname(self.nice_file(coverage.__file__, "..")) - testmods = self.nice_file(here, 'tests/modules') - zipfile = self.nice_file(here, 'tests/zipmods.zip') + testmods = self.nice_file(self.here(), 'tests/modules') + zipfile = self.nice_file(self.here(), 'tests/zipmods.zip') pypath = os.getenv('PYTHONPATH', '') if pypath: pypath += os.pathsep @@ -410,6 +409,9 @@ class CoverageTest( print(self.last_command_output) return self.last_command_status, self.last_command_output + def here(self): + return os.path.dirname(self.nice_file(coverage.__file__, "..")) + def report_from_command(self, cmd): """Return the report from the `cmd`, with some convenience added.""" report = self.run_command(cmd).replace('\\', '/') diff --git a/tests/modules/zerocoverage/__init__.py b/tests/modules/zerocoverage/__init__.py new file mode 100644 index 00000000..0acf595e --- /dev/null +++ b/tests/modules/zerocoverage/__init__.py @@ -0,0 +1 @@ +# no empty file to please hg diff --git a/tests/modules/zerocoverage/__main__.py b/tests/modules/zerocoverage/__main__.py new file mode 100644 index 00000000..91082160 --- /dev/null +++ b/tests/modules/zerocoverage/__main__.py @@ -0,0 +1 @@ +print('done') diff --git a/tests/modules/zerocoverage/zero.py b/tests/modules/zerocoverage/zero.py new file mode 100644 index 00000000..6ae283f1 --- /dev/null +++ b/tests/modules/zerocoverage/zero.py @@ -0,0 +1,3 @@ +def method(self): + while True: + return 1 diff --git a/tests/test_arcs.py b/tests/test_arcs.py index 2fd033b8..50751826 100644 --- a/tests/test_arcs.py +++ b/tests/test_arcs.py @@ -252,10 +252,12 @@ class LoopArcTest(CoverageTest): """, 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. + # With "while True", 2.x thinks it's computation, + # 2.7+ and 3.x thinks it's constant. if env.PY3: arcz = ".1 12 23 34 45 36 63 57 7." + elif env.PYVERSION >= (2, 7): + arcz = ".1 12 23 34 45 36 62 57 7." else: arcz = ".1 12 23 27 34 45 36 62 57 7." self.check_coverage("""\ @@ -270,10 +272,25 @@ class LoopArcTest(CoverageTest): arcz=arcz, ) + def test_zero_coverage_and_regexps(self): + # https://bitbucket.org/ned/coveragepy/issue/502 + if env.PYVERSION < (2, 7): + self.skipTest("No node.id before 2.7") + self.clean_local_file_imports() + zerocoverage_path = self.nice_file(self.here(), 'tests/modules/zerocoverage') + out = self.run_command( + "coverage run --branch --source {0} -m zerocoverage".format(zerocoverage_path)) + self.assertEqual(out, 'done\n') + report = self.report_from_command("coverage report -m") + squeezed = self.squeezed_lines(report) + self.assertIn("zero.py 3 3 0 0 0% 1-3", squeezed[4]) + def test_bug_496_continue_in_constant_while(self): # https://bitbucket.org/ned/coveragepy/issue/496 if env.PY3: arcz = ".1 12 23 34 45 53 46 6." + elif env.PYVERSION >= (2, 7): + arcz = ".1 12 23 34 45 52 46 6." else: arcz = ".1 12 2-1 23 34 45 52 46 6." self.check_coverage("""\ |