def test_intersect(self): self.assertEqual( intersect([set('ab'), set('bc'), set('bb')]), set(['b']), ) self.assertEqual( intersect([set('ab'), set('bc'), set('ac')]), set(), ) with self.assertRaises(StopIteration): intersect([])
def visitTryExcept(self, node): # If we are code after a 'try' block, then it either succeeded or # handled its own exception. So either the 'try' and 'else' blocks ran, # or some of the 'try' and one of the handlers ran. If we treat the # 'try' and 'else' blocks as one, then we can say that # 'try'/'except'/'else' produces unconditional locals when the same # name is local to 'try'/'else' and every handler. All other bindings # are conditional. # Visit children body_v = walk([node.body, node.else_], NameFinder()) # (A handler is (type, name, body) where 'type' and 'name' can be None) handler_vs = [ walk(h, NameFinder()) for h in node.handlers ] assert all(not v.conditional_locals for v in handler_vs) # Free names come from 'try', 'else', and names in 'except' that aren't # bound by the exception name. Since 'handlers' bundles each 'except' # body with its exception name, the bindings are already computed. self._see_unbound(body_v.free | union(v.free for v in handler_vs)) # Unconditional locals only come from locals in both the 'try'/'else' # body and every 'except' body. All other locals are conditional. locals = body_v.locals & intersect(v.locals for v in handler_vs) conditional_locals = \ (body_v.all_locals() | union(v.all_locals() for v in handler_vs)) \ - locals self._bind(locals) self._bind_conditional(conditional_locals)
def visitIf(self, node): unzip = lambda l: map(list, zip(*l)) # Gather children tests, bodies = unzip(node.tests) bodies.append(node.else_) # Visit children tests_v = walk(tests, NameFinder()) body_vs = [ walk(b, NameFinder()) for b in bodies ] assert not (tests_v.locals or tests_v.conditional_locals) # Free names come from tests and bodies self._see_unbound(tests_v.free | union(v.free for v in body_vs)) # Unconditional locals come from locals that appear in every body # including 'else'. (If we have no 'else', then its empty visitor will # nullify the intersection.) locals = intersect(v.locals for v in body_vs) # Conditional locals come from conditional locals plus the rest of the # unconditional locals conditional_locals = union(v.all_locals() for v in body_vs) - locals self._bind(locals) self._bind_conditional(conditional_locals)
def visitTryExcept(self, node): # If we are code after a 'try' block, then it either succeeded or # handled its own exception. So either the 'try' and 'else' blocks ran, # or some of the 'try' and one of the handlers ran. If we treat the # 'try' and 'else' blocks as one, then we can say that # 'try'/'except'/'else' produces unconditional locals when the same # name is local to 'try'/'else' and every handler. All other bindings # are conditional. # Visit children body_v = walk([node.body, node.else_], NameFinder()) # (A handler is (type, name, body) where 'type' and 'name' can be None) handler_vs = [walk(h, NameFinder()) for h in node.handlers] assert all(not v.conditional_locals for v in handler_vs) # Free names come from 'try', 'else', and names in 'except' that aren't # bound by the exception name. Since 'handlers' bundles each 'except' # body with its exception name, the bindings are already computed. self._see_unbound(body_v.free | union(v.free for v in handler_vs)) # Unconditional locals only come from locals in both the 'try'/'else' # body and every 'except' body. All other locals are conditional. locals = body_v.locals & intersect(v.locals for v in handler_vs) conditional_locals = \ (body_v.all_locals() | union(v.all_locals() for v in handler_vs)) \ - locals self._bind(locals) self._bind_conditional(conditional_locals)
def visitIf(self, node): unzip = lambda l: map(list, zip(*l)) # Gather children tests, bodies = unzip(node.tests) bodies.append(node.else_) # Visit children tests_v = walk(tests, NameFinder()) body_vs = [walk(b, NameFinder()) for b in bodies] assert not (tests_v.locals or tests_v.conditional_locals) # Free names come from tests and bodies self._see_unbound(tests_v.free | union(v.free for v in body_vs)) # Unconditional locals come from locals that appear in every body # including 'else'. (If we have no 'else', then its empty visitor will # nullify the intersection.) locals = intersect(v.locals for v in body_vs) # Conditional locals come from conditional locals plus the rest of the # unconditional locals conditional_locals = union(v.all_locals() for v in body_vs) - locals self._bind(locals) self._bind_conditional(conditional_locals)