def visit_Call()

in gcpdiag/runbook/__init__.py [0:0]


  def visit_Call(self, node):
    if isinstance(node.func,
                  ast.Attribute) and node.func.attr in ('add_child', 'add_step',
                                                        'add_start', 'add_end'):
      child = None
      if len(node.args) == 1:
        node.keywords.append(ast.keyword('step', node.args[0]))
      if len(node.args) == 2:
        node.keywords.append(ast.keyword('parent', node.args[0]))
        node.keywords.append(ast.keyword('child', node.args[1]))
      if node.keywords:
        for kw in node.keywords:
          arg_name = kw.arg
          step = kw.value
          if arg_name == 'parent':
            p = find_class_globally(self.instances[step.id])
            p = p() if isinstance(p, type) else p
            self.parent.setdefault(self.instances[step.id], p)
          if arg_name in ('child', 'step'):
            if isinstance(step, ast.Name) and step.id in self.instances:
              # Map variable name to class instance if possible
              clazz = self.instances.get(step.id)
              if not clazz:
                clazz = find_class_globally(step.id)
                if not clazz:
                  continue
              clazz = clazz() if isinstance(clazz, type) else clazz
              self.instances.setdefault(step.id, clazz)
              child = clazz  # This is a direct class name
            elif isinstance(step, ast.Call) and hasattr(step.func, 'id'):
              clazz = self.instances.get(step.func.id)
              if not clazz:
                clazz = find_class_globally(step.func.id)
                if not clazz:
                  continue
              clazz = clazz() if isinstance(clazz, type) else clazz
              self.instances.setdefault(step.func.id, clazz)
              child = clazz  # This is a direct class name
            # if argument of call is instantiated directly and has module attr.
            elif isinstance(step, ast.Call) and hasattr(step.func, 'attr'):
              clazz = self.instances.get(step.func.attr)
              if not clazz:
                clazz = find_class_globally(step.func.attr)
                if not clazz:
                  continue
              clazz = clazz() if isinstance(clazz, type) else clazz
              self.instances.setdefault(step.func.attr, clazz)
              child = clazz  # This is a direct class name

      if node.func.attr in ('add_start'):
        self.tree.add_start(child)
        self.visit_ast_nodes(child.__class__)

      if node.func.attr in ('add_end'):
        self.tree.add_end(child)
        self.visit_ast_nodes(child.__class__)

      if node.func.attr in ('add_step'):
        _, p = self.parent.popitem()
        self.tree.add_step(parent=p, child=child)
        self.visit_ast_nodes(child.__class__)

      if node.func.attr in ('add_child'):
        o = self.instances.get(self.current_class)
        self.tree.add_step(parent=o, child=child)
        self.generic_visit(node)