def test_hash(): symchain_set = set() symchain_set.add(get_attrsub_symbol_chain('f.read()')) symchain_set.add(get_attrsub_symbol_chain('f.read')) symchain_set.add('f') symchain_set.add(('f', 'read')) assert len(symchain_set) == 4
def visit_Subscript(self, node: ast.Subscript): if not self.inside_attrsub: self.ref_set.add(get_attrsub_symbol_chain(node)) with self.attrsub_context(): self.visit(node.value) with self.attrsub_context(inside=False): self.visit(node.slice)
def visit_Subscript(self, node: ast.Subscript): if not self.inside_attrsub: self._add_attrsub_to_live_if_eligible(get_attrsub_symbol_chain(node)) with self.attrsub_context(): self.visit(node.value) with self.attrsub_context(inside=False): self.visit(node.slice)
def visit_Assign_or_AugAssign_target( self, target_node: 'Union[ast.Attribute, ast.Name, ast.Subscript, ast.expr]' ): if isinstance(target_node, ast.Name): self.dead.add(target_node.id) elif isinstance(target_node, (ast.Attribute, ast.Subscript)): self.dead.add(get_attrsub_symbol_chain(target_node)) else: logger.warning('unsupported type for node %s' % target_node)
def visit_Call(self, node: ast.Call): with self.args_context(): self.generic_visit(node.args) for kwarg in node.keywords: self.visit(kwarg.value) self.ref_set.add(get_attrsub_symbol_chain(node)) if isinstance(node.func, (ast.Attribute, ast.Subscript)): with self.attrsub_context(): self.visit(node.func) else: self.visit(node.func)
def visit_Call(self, node): extra_to_add = [] if isinstance(node.func, (ast.Attribute, ast.Subscript)): extra_to_add.append(get_attrsub_symbol_chain(node)) to_visit = [node.args, node.keywords] else: to_visit = node temp = self.to_add_set self.to_add_set = [] self.generic_visit(to_visit) self.to_add_set, temp = temp, self.to_add_set temp = TiedTuple(set(_flatten(temp)) | set(_flatten(extra_to_add))) self.to_add_set.append(temp)
def visit_Assign_target( self, target_node: Union[ast.Attribute, ast.Name, ast.Subscript, ast.Tuple, ast.List, ast.expr] ): if isinstance(target_node, ast.Name): self.dead.add(target_node.id) elif isinstance(target_node, (ast.Attribute, ast.Subscript)): self.dead.add(get_attrsub_symbol_chain(target_node)) if isinstance(target_node, ast.Subscript): with self.live_context(): self.visit(target_node.slice) elif isinstance(target_node, (ast.Tuple, ast.List)): for elt in target_node.elts: self.visit_Assign_target(elt) elif isinstance(target_node, ast.Starred): self.visit_Assign_target(target_node.value) else: logger.warning('unsupported type for node %s' % target_node)
def visit_Attribute_or_Subscript(self, node): # TODO: we'll ignore args inside of inner calls, e.g. f.g(x, y).h self.to_add_set.append(get_attrsub_symbol_chain(node))
def visit_Attribute(self, node: ast.Attribute): if not self.inside_attrsub: self.ref_set.add(get_attrsub_symbol_chain(node)) with self.attrsub_context(): self.visit(node.value)
def visit_Attribute(self, node: ast.Attribute): if not self.inside_attrsub: self._add_attrsub_to_live_if_eligible(get_attrsub_symbol_chain(node)) with self.attrsub_context(): self.visit(node.value)
def test_basic(): node = ast.parse('a.b.c.d.e.f').body[0].value symchain = get_attrsub_symbol_chain(node) assert symchain.symbols == ('a', 'b', 'c', 'd', 'e', 'f') assert symchain.call_points == ()
def test_calls_at_endpoints(): node = ast.parse('a().b.c().d.e.f()').body[0].value symchain = get_attrsub_symbol_chain(node) assert symchain.symbols == (Cp('a'), 'b', Cp('c'), 'd', 'e', Cp('f')) assert symchain.call_points == (Cp('a'), Cp('c'), Cp('f'))