def test_defined(self): def f(x): if x: y = 2 # pylint: disable=unused-variable return x node, ctx = self._parse_and_analyze(f, {}) cfg.run_analyses(node, cfg.Defined(ctx)) body = node.body[0].body # only x is for sure defined at the end self._check_anno_matches(body[1], 'defined_in', 'x') # at the end of the if body both x and y are defined if_body = body[0].body self._check_anno_matches(if_body[0], 'defined_out', ('x', 'y'))
def test_nested_functions_dont_leak_definitions(self): def f(x): print(x) def g(): y = 2 return y return g() # y is not defined here node, ctx = self._parse_and_analyze(f, {}) cfg.run_analyses(node, cfg.Defined(ctx)) body = node.body[0].body self.assertEqual(anno.getanno(body[2], 'defined_in'), frozenset(map(qual_names.QN, ('x', 'g'))))
def test_nested_functions_defined(self): def f(x): y = x * 2 def g(z): return z + y return g(x) node, ctx = self._parse_and_analyze(f, {}) cfg.run_analyses(node, cfg.Defined(ctx)) body = node.body[0].body self.assertEqual(anno.getanno(body[2], 'defined_in'), frozenset(map(qual_names.QN, ('g', 'x', 'y'))))
def transform(node, context): cfg.run_analyses(node, cfg.Liveness(context)) cfg.run_analyses(node, cfg.Defined(context)) node = ControlFlowTransformer(context).visit(node) return node