class_docstr: Infer symbolic type for all AST node. 
class_docstr_tok: ["Infer","symbolic","type","for","all","AST","node","."]
code: def visit_Call(self, node):
      self.generic_visit(node)
  
      func = node.func
  
      for alias in self.strict_aliases[func]:
          # this comes from a bind
          if isinstance(alias, ast.Call):
              a0 = alias.args[0]
              # by construction of the bind construct
              assert len(self.strict_aliases[a0]) == 1
              bounded_function = next(iter(self.strict_aliases[a0]))
              fake_name = deepcopy(a0)
              fake_node = ast.Call(
                  fake_name, alias.args[1:] + node.args, []
              )
              self.combiners[bounded_function].combiner(self, fake_node)
  
          # handle backward type dependencies from function calls
          else:
              self.combiners[alias].combiner(self, node)
  
      UnknownType = self.builder.UnknownType
  
      # recurring nightmare
      def last_chance():
          # maybe we can get saved if we have a hint about
          # the called function return type
          for alias in self.strict_aliases[func]:
              if alias is self.current and alias in self.result:
                  # great we have a (partial) type information
                  self.result[node] = self.result[alias]
                  return
          self.result[node] = UnknownType
  
      if self.result[node.func] is UnknownType:
          return last_chance()
  
      if any(self.result[arg] is UnknownType for arg in node.args):
          return last_chance()
  
      # special handler for getattr: use the attr name as an enum member
      if isinstance(func, ast.Attribute) and func.attr == "getattr":
          self.update_type(
              node,
              self.builder.GetAttr,
              self.result[node.args[0]],
              node.args[1].value,
          )
      # default behavior
      else:
          self.update_type(
              node,
              self.builder.ReturnType,
              self.result[func],
              *[self.result[arg] for arg in node.args],
          )
  
imports: from pythran.analyses import LazynessAnalysis, StrictAliases, YieldPoints
  from pythran.analyses import LocalNodeDeclarations, Immediates, RangeValues
  from pythran.analyses import Ancestors
  from pythran.config import cfg
  from pythran.cxxtypes import TypeBuilder, ordered_set
  from pythran.intrinsic import UserFunction, Class
  from pythran.passmanager import ModuleAnalysis
  from pythran.tables import operator_to_lambda, MODULES
  from pythran.types.conversion import pytype_to_ctype
  from pythran.types.reorder import Reorder
  from pythran.utils import attr_to_path, cxxid, isnum, isextslice
  from collections import defaultdict
  from functools import reduce
  import gast
  from itertools import islice
  from copy import deepcopy
label_desc: Use image node_id 23 for calling the Types obj's underlying member method code with example usage: obj.visit_Call(node) and returns: last_chance, last_chance