summaryrefslogtreecommitdiff
path: root/coverage
diff options
context:
space:
mode:
authorNed Batchelder <ned@nedbatchelder.com>2018-11-09 07:03:25 -0500
committerNed Batchelder <ned@nedbatchelder.com>2018-11-11 16:45:33 -0500
commite5dcb933ab791206040a849eacd726ffe40c348a (patch)
tree81ea6018218db5436766f1d46ff999351e33b82c /coverage
parentcc12f4b7c40347b7297f7f6d938150bfde8c9ed5 (diff)
downloadpython-coveragepy-git-e5dcb933ab791206040a849eacd726ffe40c348a.tar.gz
Python 3.8 will optimize away "while True:"
Diffstat (limited to 'coverage')
-rw-r--r--coverage/env.py2
-rw-r--r--coverage/parser.py21
2 files changed, 23 insertions, 0 deletions
diff --git a/coverage/env.py b/coverage/env.py
index fd98fa2b..d97b193c 100644
--- a/coverage/env.py
+++ b/coverage/env.py
@@ -39,6 +39,8 @@ class PYBEHAVIOR(object):
# (old behavior)?
trace_decorated_def = (PYVERSION >= (3, 8))
+ # Are while-true loops optimized into absolute jumps with no loop setup?
+ nix_while_true = (PYVERSION >= (3, 8))
# Coverage.py specifics.
diff --git a/coverage/parser.py b/coverage/parser.py
index 6ae81c19..1c19f69e 100644
--- a/coverage/parser.py
+++ b/coverage/parser.py
@@ -711,6 +711,13 @@ class AstArcAnalyzer(object):
node = None
return node
+ # Missing nodes: _missing__*
+ #
+ # Entire statements can be optimized away by Python. They will appear in
+ # the AST, but not the bytecode. These functions are called (by
+ # find_non_missing_node) to find a node to use instead of the missing
+ # node. They can return None if the node should truly be gone.
+
def _missing__If(self, node):
# If the if-node is missing, then one of its children might still be
# here, but not both. So return the first of the two that isn't missing.
@@ -738,6 +745,20 @@ class AstArcAnalyzer(object):
return non_missing_children[0]
return NodeList(non_missing_children)
+ def _missing__While(self, node):
+ body_nodes = self.find_non_missing_node(NodeList(node.body))
+ if not body_nodes:
+ return None
+ # Make a synthetic While-true node.
+ new_while = ast.While()
+ new_while.lineno = body_nodes.lineno
+ new_while.test = ast.Name()
+ new_while.test.lineno = body_nodes.lineno
+ new_while.test.id = "True"
+ new_while.body = body_nodes.body
+ new_while.orelse = None
+ return new_while
+
def is_constant_expr(self, node):
"""Is this a compile-time constant?"""
node_name = node.__class__.__name__