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_Attribute(self, node):
      parent_types = self.visit(node.value)
  
      # Attempt to use the static value if known.
      parent_value = anno.Static.VALUE.of(node.value, None)
      if parent_value is not None:
          static_value = getattr(parent_value, node.attr, NO_VALUE)
  
          if static_value is NO_VALUE:
              # Unexpected failure to resolve attribute. Ask the resolver about the
              # full name instead.
              types, static_value = self.resolver.res_name(
                  self.namespace, self.types_in, anno.Basic.QN.of(node)
              )
              anno.setanno(node, anno.Static.VALUE, static_value)
              if __debug__:
                  self._check_set(types)
              return types
  
      else:
          # Fall back to the type if that is known.
          if parent_types is None:
              return None
  
          inferred_values = [
              getattr(t, node.attr, None) for t in parent_types
          ]
          if not inferred_values:
              return None
  
          static_value = inferred_values[0]
          if static_value is None:
              return None
  
          if any(v is not static_value for v in inferred_values[1:]):
              # Static value not stable, assume it's dynamic.
              return None
  
      types = self.resolver.res_value(self.namespace, static_value)
      anno.setanno(node, anno.Static.VALUE, static_value)
  
      if __debug__:
          self._check_set(types)
  
      return types
  
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 10 for calling the StmtInferrer obj's underlying member method code with example usage: obj.visit_Attribute(node) and returns: types, types, None, None, None, None