class_docstr: Gather aliasing informations across nodes
  
  As a result, each node from the module is associated to a set of node or
  Intrinsic to which it *may* alias to.
class_docstr_tok: ["Gather","aliasing","informations","across","nodes","As","a","result",",","each","node","from","the","module","is","associated","to","a","set","of","node","or","Intrinsic","to","which","it","*","may","*","alias","to","."]
code: def call_return_alias(self, node):
      def interprocedural_aliases(func, args):
          arg_aliases = [self.result[arg] or {arg} for arg in args]
          return_aliases = set()
          for args_combination in product(*arg_aliases):
              for ra in func.return_alias(args_combination):
                  if isinstance(ra, ast.Subscript):
                      if isinstance(ra.value, ContainerOf):
                          return_aliases.update(ra.value.containees)
                          continue
                  return_aliases.add(ra)
          return return_aliases
  
      def full_args(func, call):
          args = call.args
          if isinstance(func, ast.FunctionDef):
              extra = len(func.args.args) - len(args)
              if extra:
                  tail = [
                      deepcopy(n) for n in func.args.defaults[extra:]
                  ]
                  for arg in tail:
                      self.visit(arg)
                  args = args + tail
          return args
  
      func = node.func
      aliases = set()
  
      if node.keywords:
          # too soon, we don't support keywords in interprocedural_aliases
          pass
      elif isinstance(func, ast.Attribute):
          _, signature = methods.get(
              func.attr, functions.get(func.attr, [(None, None)])[0]
          )
          if signature:
              args = full_args(signature, node)
              aliases = interprocedural_aliases(signature, args)
  
      elif isinstance(func, ast.Name):
          func_aliases = self.result[func]
          for func_alias in func_aliases:
              if hasattr(func_alias, "return_alias"):
                  args = full_args(func_alias, node)
                  aliases.update(
                      interprocedural_aliases(func_alias, args)
                  )
              else:
                  pass  # better thing to do ?
      for a in aliases:
          if a not in self.result:
              self.add(a)
      return aliases or self.get_unbound_value_set()
  
imports: from pythran.analyses.global_declarations import GlobalDeclarations
  from pythran.intrinsic import Intrinsic, Class, UnboundValue
  from pythran.passmanager import ModuleAnalysis
  from pythran.tables import functions, methods, MODULES
  from pythran.unparse import Unparser
  from pythran.conversion import demangle
  import pythran.metadata
  from pythran.utils import isnum
  from pythran.syntax import PythranSyntaxError
  import gast
  from copy import deepcopy
  from itertools import product
  import io
label_desc: Use image node_id 12 for calling the Aliases obj's underlying member method code with example usage: obj.call_return_alias(node) and returns: unknown, return_aliases, args