summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coverage/env.py27
-rw-r--r--coverage/execfile.py6
-rw-r--r--coverage/parser.py2
-rw-r--r--tests/test_api.py2
-rw-r--r--tests/test_arcs.py22
5 files changed, 43 insertions, 16 deletions
diff --git a/coverage/env.py b/coverage/env.py
index 27602431..83b4be65 100644
--- a/coverage/env.py
+++ b/coverage/env.py
@@ -28,12 +28,39 @@ PY3 = PYVERSION >= (3, 0)
class PYBEHAVIOR(object):
"""Flags indicating this Python's behavior."""
+ # Is "if __debug__" optimized away?
+ optimize_if_debug = (not PYPY)
+
+ # If "if not __debug__" optimized away?
+ optimize_if_not_debug = (not PYPY) and (PYVERSION >= (3, 7, 0, 'alpha', 4))
+
+ # Do we have yield-from?
+ yield_from = (PYVERSION >= (3, 3))
+
+ # Do we have PEP 420 namespace packages?
+ namespaces_pep420 = (PYVERSION >= (3, 3))
+
# Do .pyc files have the source file size recorded in them?
size_in_pyc = (PYVERSION >= (3, 3))
+ # Do we have async and await syntax?
+ async_syntax = (PYVERSION >= (3, 5))
+
+ # PEP 448 defined additional unpacking generalizations
+ unpackings_pep448 = (PYVERSION >= (3, 5))
+
+ # Can co_lnotab have negative deltas?
+ negative_lnotab = (PYVERSION >= (3, 6))
+
# Do .pyc files conform to PEP 552? Hash-based pyc's.
hashed_pyc_pep552 = (PYVERSION >= (3, 7, 0, 'alpha', 4))
+ # Python 3.7.0b3 changed the behavior of the sys.path[0] entry for -m. It
+ # used to be an empty string (meaning the current directory). It changed
+ # to be the actual path to the current directory, so that os.chdir wouldn't
+ # affect the outcome.
+ actual_syspath0_dash_m = (PYVERSION >= (3, 7, 0, 'beta', 3))
+
# When a break/continue/return statement in a try block jumps to a finally
# block, does the finally block do the break/continue/return (pre-3.8), or
# does the finally jump back to the break/continue/return (3.8) to do the
diff --git a/coverage/execfile.py b/coverage/execfile.py
index 0e78e5dc..97997b06 100644
--- a/coverage/execfile.py
+++ b/coverage/execfile.py
@@ -124,11 +124,7 @@ class PyRunner(object):
should_update_sys_path = True
if self.as_module:
- # Python 3.7.0b3 changed the behavior of the sys.path[0] entry for -m. It
- # used to be an empty string (meaning the current directory). It changed
- # to be the actual path to the current directory, so that os.chdir wouldn't
- # affect the outcome.
- if env.PYVERSION >= (3, 7, 0, 'beta', 3):
+ if env.PYBEHAVIOR.actual_syspath0_dash_m:
path0 = os.getcwd()
else:
path0 = ""
diff --git a/coverage/parser.py b/coverage/parser.py
index 1c19f69e..6ae99fe4 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -409,7 +409,7 @@ class ByteParser(object):
yield (byte_num, line_num)
last_line_num = line_num
byte_num += byte_incr
- if env.PYVERSION >= (3, 6) and line_incr >= 0x80:
+ if env.PYBEHAVIOR.negative_lnotab and line_incr >= 0x80:
line_incr -= 0x100
line_num += line_incr
if line_num != last_line_num:
diff --git a/tests/test_api.py b/tests/test_api.py
index 2f6f7a2f..755a89a2 100644
--- a/tests/test_api.py
+++ b/tests/test_api.py
@@ -495,7 +495,7 @@ class NamespaceModuleTest(UsingModulesMixin, CoverageTest):
def setUp(self):
super(NamespaceModuleTest, self).setUp()
- if env.PYVERSION < (3, 3):
+ if not env.PYBEHAVIOR.namespaces_pep420:
self.skipTest("Python before 3.3 doesn't have namespace packages")
def test_explicit_namespace_module(self):
diff --git a/tests/test_arcs.py b/tests/test_arcs.py
index d3430af2..cbbac64a 100644
--- a/tests/test_arcs.py
+++ b/tests/test_arcs.py
@@ -1056,7 +1056,7 @@ class YieldTest(CoverageTest):
self.assertEqual(self.stdout(), "20\n12\n")
def test_yield_from(self):
- if env.PYVERSION < (3, 3):
+ if not env.PYBEHAVIOR.yield_from:
self.skipTest("Python before 3.3 doesn't have 'yield from'")
self.check_coverage("""\
def gen(inp):
@@ -1159,8 +1159,8 @@ class OptimizedIfTest(CoverageTest):
arcz=".1 1C CE EF F.",
)
- def test_constant_if(self):
- if env.PYPY:
+ def test_if_debug(self):
+ if not env.PYBEHAVIOR.optimize_if_debug:
self.skipTest("PyPy doesn't optimize away 'if __debug__:'")
# CPython optimizes away "if __debug__:"
self.check_coverage("""\
@@ -1173,13 +1173,17 @@ class OptimizedIfTest(CoverageTest):
""",
arcz=".1 12 24 41 26 61 1.",
)
+
+ def test_if_not_debug(self):
# Before 3.7, no Python optimized away "if not __debug__:"
- if env.PYVERSION < (3, 7, 0, 'alpha', 4):
- arcz = ".1 12 23 31 34 41 26 61 1."
- arcz_missing = "34 41"
- else:
+ if not env.PYBEHAVIOR.optimize_if_debug:
+ self.skipTest("PyPy doesn't optimize away 'if __debug__:'")
+ elif env.PYBEHAVIOR.optimize_if_not_debug:
arcz = ".1 12 23 31 26 61 1."
arcz_missing = ""
+ else:
+ arcz = ".1 12 23 31 34 41 26 61 1."
+ arcz_missing = "34 41"
self.check_coverage("""\
for value in [True, False]:
if value:
@@ -1230,7 +1234,7 @@ class MiscArcTest(CoverageTest):
)
def test_unpacked_literals(self):
- if env.PYVERSION < (3, 5):
+ if not env.PYBEHAVIOR.unpackings_pep448:
self.skipTest("Don't have unpacked literals until 3.5")
self.check_coverage("""\
d = {
@@ -1492,7 +1496,7 @@ class AsyncTest(CoverageTest):
"""Tests of the new async and await keywords in Python 3.5"""
def setUp(self):
- if env.PYVERSION < (3, 5):
+ if not env.PYBEHAVIOR.async_syntax:
self.skipTest("Async features are new in Python 3.5")
super(AsyncTest, self).setUp()