From b7a35186425cfef265548afc75b527752bed0c9a Mon Sep 17 00:00:00 2001 From: Ned Batchelder Date: Thu, 24 Dec 2015 19:46:00 -0500 Subject: A start on try/except/finally --HG-- branch : ast-branch --- coverage/parser.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'coverage/parser.py') diff --git a/coverage/parser.py b/coverage/parser.py index fb2cf955..4b920f10 100644 --- a/coverage/parser.py +++ b/coverage/parser.py @@ -341,8 +341,9 @@ class AstArcAnalyzer(object): handler = getattr(self, "handle_" + node_name, self.handle_default) return handler(node) - def add_body_arcs(self, body, from_line): - prev_lines = set([from_line]) + def add_body_arcs(self, body, from_line=None, prev_lines=None): + if prev_lines is None: + prev_lines = set([from_line]) for body_node in body: lineno = self.line_for_node(body_node) for prev_lineno in prev_lines: @@ -363,6 +364,7 @@ class AstArcAnalyzer(object): # TODO: listcomps hidden in lists: x = [[i for i in range(10)]] # TODO: multi-line listcomps # TODO: nested function definitions + # TODO: multiple `except` clauses def handle_Break(self, node): here = self.line_for_node(node) @@ -411,12 +413,30 @@ class AstArcAnalyzer(object): def handle_Module(self, node): raise Exception("TODO: this shouldn't happen") + def handle_Raise(self, node): + # `raise` statement jumps away, no exits from here. + return set([]) + def handle_Return(self, node): here = self.line_for_node(node) # TODO: what if self.function_start is None? self.arcs.add((here, -self.function_start)) return set([]) + def handle_Try(self, node): + start = self.line_for_node(node) + exits = self.add_body_arcs(node.body, from_line=start) + handler_exits = set() + for handler_node in node.handlers: + handler_start = self.line_for_node(handler_node) + # TODO: handler_node.name and handler_node.type + handler_exits |= self.add_body_arcs(handler_node.body, from_line=handler_start) + # TODO: node.orelse + # TODO: node.finalbody + if node.finalbody: + exits = self.add_body_arcs(node.finalbody, prev_lines=exits|handler_exits) + return exits + def handle_While(self, node): constant_test = self.is_constant_expr(node.test) start = to_top = self.line_for_node(node.test) -- cgit v1.2.1