class_docstr: Runs type inference on a single AST statement.
  
  This visitor annotates most nodes with type information. It also sets types
  for the symbols modified by this statement in its types_out property.
  
  Note: this inferrer is able to capture side effects of functions, however,
  these side effects will not be applied to the current expression. Doing so
  would create too much of a dependence on the runtime's internal rules about
  execution order.
  Example:
  
    def f():
      nonlocal a
      a = 1
      return a
  
    a = 0.0
    b = f() + a  # a = float; side effect of f() ignored
    print(a)  # a = int; side effect of f() accounted for
code: def visit_Call(self, node):
      self.visit(node.func)
  
      f_name = anno.Basic.QN.of(node.func)
      arg_types = [self.visit(a) for a in node.args]
      keyword_types = [self.visit(kw.value) for kw in node.keywords]
  
      if f_name in self.scope.bound:
          # Local function, use local type definitions, if available.
          f_type = self.types_in.types.get(f_name, None)
          if f_type is None:
              # No static type info available, nothing more to do.
              ret_type, side_effects = None, None
          else:
              ret_type, side_effects = self._resolve_typed_callable(
                  f_type, arg_types, keyword_types
              )
  
      else:
          # Nonlocal function, resolve externally.
          f_type = anno.Static.TYPES.of(node.func, None)
          ret_type, side_effects = self.resolver.res_call(
              self.namespace,
              self.types_in.types,
              node,
              f_type,
              arg_types,
              keyword_types,
          )
  
      if __debug__:
          self._check_set(ret_type)
          if side_effects:
              if not isinstance(side_effects, dict):
                  raise ValueError(
                      "side effects must be dict, got {}".format(
                          side_effects
                      )
                  )
              for k, v in side_effects.items():
                  if not isinstance(k, qual_names.QN):
                      raise ValueError(
                          "side effect keys must be QNs, got {}".format(
                              k
                          )
                      )
                  self._check_set(v)
  
      if side_effects:
          self.new_symbols.update(side_effects)
      return ret_type
  
imports: import itertools
  from typing import Any, Callable, Dict, Set
  import gast
  from tensorflow.python.autograph.pyct import anno
  from tensorflow.python.autograph.pyct import cfg
  from tensorflow.python.autograph.pyct import qual_names
  from tensorflow.python.autograph.pyct import transformer
  from tensorflow.python.autograph.pyct.static_analysis import activity
  from tensorflow.python.autograph.pyct.static_analysis import annos
label_desc: Use image node_id 13 for calling the StmtInferrer obj's underlying member method code with example usage: obj.visit_Call(node) and returns: ret_type