class_docstr: Gathers the callees of each function required for type inference.
  
  This analyse produces a directed graph with functions as nodes and edges
  between nodes when a function might call another.
  
  Check usual behavior.
  >>> import gast as ast
  >>> from pythran import passmanager
  >>> pm = passmanager.PassManager("test")
  >>> node = ast.parse('''
  ... def foo(n):
  ...     return 1 if copy(n) else copy(n)
  ... def copy(n):
  ...     return n == 2''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  3
  
  foo result depend on : NoDeps and copy
  copy result depend on : NoDeps
  
  Check that content assignment is a dependency.
  >>> node = ast.parse('''
  ... def foo(n):
  ...     n[1] = copy(n)
  ...     return 1 if copy(n) else n
  ... def copy(n):
  ...     return n == 2''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  3
  
  foo result depend on : NoDeps and copy
  copy result depend on : NoDeps
  
  Check augassign add a dependencies but don't remove the old one.
  >>> node = ast.parse('''
  ... def bar(n):
  ...     return n
  ... def foo(n):
  ...     n[1] = copy(n)
  ...     n[1] += bar(1)
  ...     return 1 if copy(n) else n
  ... def copy(n):
  ...     return n == 2''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  5
  
  bar result depend on : NoDeps
  foo result depend on : NoDeps, bar and copy
  copy depend on : NoDeps
  
  Check a if statement handle both branches
  >>> node = ast.parse('''
  ... def bar(n):
  ...     return n
  ... def foo(n):
  ...     if n:
  ...         n = bar()
  ...     else:
  ...         n = 4
  ...     return 1 or n''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  3
  
  Check we do not add everything from a conditional statement.
  >>> node = ast.parse('''
  ... def bar(n):
  ...     return n
  ... def foo(n):
  ...     if n:
  ...         n = bar()
  ...         n = 3
  ...     else:
  ...         n = 4
  ...     return 1 or n''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  2
  
  bar result depend on : NoDeps
  foo result depend on : NoDeps only
  
  Check dependency on for target variable
  >>> node = ast.parse('''
  ... def bar(n):
  ...     return builtins.range(n)
  ... def foo(n):
  ...     for i in bar(n):
  ...         i = 2
  ...     return i''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  2
  
  bar result depend on : NoDeps
  foo result depend on : NoDeps
  
  Check dependency on for target variable with no deps if we don't start
  >>> node = ast.parse('''
  ... def bar(n):
  ...     return builtins.range(n)
  ... def foo(n):
  ...     i = 4
  ...     for i in bar(n):
  ...         pass
  ...     return i''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  3
  
  bar result depend on : NoDeps
  foo result depend on : NoDeps and bar
  
  Check dependency on for target variable with deps
  >>> node = ast.parse('''
  ... def bar(n):
  ...     return builtins.range(n)
  ... def foo(n):
  ...     for i in bar(n):
  ...         pass
  ...     return i''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  2
  
  bar result depend on : NoDeps
  foo result depend on : NoDeps and bar
  
  Check conditional without else branch.
  >>> node = ast.parse('''
  ... def foo(n):
  ...     res = 3
  ...     if n:
  ...         res = foo(n - 1)
  ...     return res''')
  >>> res = pm.gather(TypeDependencies, node)
  >>> len(res.edges)
  2
  
  foo result depend on : NoDeps and foo
  
  FIXME : We should use CFG to perform better function dependencies.
  
  Check conditional without break
  >> node = ast.parse('''
  .. def bar2(n):
  ..     return builtins.range(n)
  .. def bar(n):
  ..     return builtins.range(n)
  .. def foo(n):
  ..     for i in bar(n):
  ..         if i:
  ..             j = bar(n)
  ..             break
  ..         j = bar2(n)
  ..     return j''')
  >> res = pm.gather(TypeDependencies, node)
  >> len(res.edges)
  4
  
  bar result depend on : NoDeps
  bar2 result depend on : NoDeps
  foo result depend on : bar ad bar2
class_docstr_tok: ["Gathers","the","callees","of","each","function","required","for","type","inference",".","This","analyse","produces","a","directed","graph","with","functions","as","nodes","and","edges","between","nodes","when","a","function","might","call","another",".","Check","usual","behavior",".",">",">",">","import","gast","as","ast",">",">",">","from","pythran","import","passmanager",">",">",">","pm","=","passmanager.PassManager","(","``","test","''",")",">",">",">","node","=","ast.parse","(","``","'","...","def","foo","(","n",")",":","...","return","1","if","copy","(","n",")","else","copy","(","n",")","...","def","copy","(","n",")",":","...","return","n","==","2","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","3","foo","result","depend","on",":","NoDeps","and","copy","copy","result","depend","on",":","NoDeps","Check","that","content","assignment","is","a","dependency",".",">",">",">","node","=","ast.parse","(","``","'","...","def","foo","(","n",")",":","...","n","[","1","]","=","copy","(","n",")","...","return","1","if","copy","(","n",")","else","n","...","def","copy","(","n",")",":","...","return","n","==","2","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","3","foo","result","depend","on",":","NoDeps","and","copy","copy","result","depend","on",":","NoDeps","Check","augassign","add","a","dependencies","but","do","n't","remove","the","old","one",".",">",">",">","node","=","ast.parse","(","``","'","...","def","bar","(","n",")",":","...","return","n","...","def","foo","(","n",")",":","...","n","[","1","]","=","copy","(","n",")","...","n","[","1","]","+=","bar","(","1",")","...","return","1","if","copy","(","n",")","else","n","...","def","copy","(","n",")",":","...","return","n","==","2","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","5","bar","result","depend","on",":","NoDeps","foo","result","depend","on",":","NoDeps",",","bar","and","copy","copy","depend","on",":","NoDeps","Check","a","if","statement","handle","both","branches",">",">",">","node","=","ast.parse","(","``","'","...","def","bar","(","n",")",":","...","return","n","...","def","foo","(","n",")",":","...","if","n",":","...","n","=","bar","(",")","...","else",":","...","n","=","4","...","return","1","or","n","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","3","Check","we","do","not","add","everything","from","a","conditional","statement",".",">",">",">","node","=","ast.parse","(","``","'","...","def","bar","(","n",")",":","...","return","n","...","def","foo","(","n",")",":","...","if","n",":","...","n","=","bar","(",")","...","n","=","3","...","else",":","...","n","=","4","...","return","1","or","n","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","2","bar","result","depend","on",":","NoDeps","foo","result","depend","on",":","NoDeps","only","Check","dependency","on","for","target","variable",">",">",">","node","=","ast.parse","(","``","'","...","def","bar","(","n",")",":","...","return","builtins.range","(","n",")","...","def","foo","(","n",")",":","...","for","i","in","bar","(","n",")",":","...","i","=","2","...","return","i","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","2","bar","result","depend","on",":","NoDeps","foo","result","depend","on",":","NoDeps","Check","dependency","on","for","target","variable","with","no","deps","if","we","do","n't","start",">",">",">","node","=","ast.parse","(","``","'","...","def","bar","(","n",")",":","...","return","builtins.range","(","n",")","...","def","foo","(","n",")",":","...","i","=","4","...","for","i","in","bar","(","n",")",":","...","pass","...","return","i","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","3","bar","result","depend","on",":","NoDeps","foo","result","depend","on",":","NoDeps","and","bar","Check","dependency","on","for","target","variable","with","deps",">",">",">","node","=","ast.parse","(","``","'","...","def","bar","(","n",")",":","...","return","builtins.range","(","n",")","...","def","foo","(","n",")",":","...","for","i","in","bar","(","n",")",":","...","pass","...","return","i","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","2","bar","result","depend","on",":","NoDeps","foo","result","depend","on",":","NoDeps","and","bar","Check","conditional","without","else","branch",".",">",">",">","node","=","ast.parse","(","``","'","...","def","foo","(","n",")",":","...","res","=","3","...","if","n",":","...","res","=","foo","(","n","-","1",")","...","return","res","''","'",")",">",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">",">","len","(","res.edges",")","2","foo","result","depend","on",":","NoDeps","and","foo","FIXME",":","We","should","use","CFG","to","perform","better","function","dependencies",".","Check","conditional","without","break",">",">","node","=","ast.parse","(","``","'","..","def","bar2","(","n",")",":","..","return","builtins.range","(","n",")","..","def","bar","(","n",")",":","..","return","builtins.range","(","n",")","..","def","foo","(","n",")",":","..","for","i","in","bar","(","n",")",":","..","if","i",":","..","j","=","bar","(","n",")","..","break","..","j","=","bar2","(","n",")","..","return","j","''","'",")",">",">","res","=","pm.gather","(","TypeDependencies",",","node",")",">",">","len","(","res.edges",")","4","bar","result","depend","on",":","NoDeps","bar2","result","depend","on",":","NoDeps","foo","result","depend","on",":","bar","ad","bar2"]
docstr: Add edge from all possible callee to current function.
  
  Gather all the function call that led to the creation of the
  returned expression and add an edge to each of this function.
  
  When visiting an expression, one returns a list of frozensets. Each
  element of the list is linked to a possible path, each element of a
  frozenset is linked to a dependency.
docstr_tok: ["Add","edge","from","all","possible","callee","to","current","function",".","Gather","all","the","function","call","that","led","to","the","creation","of","the","returned","expression","and","add","an","edge","to","each","of","this","function",".","When","visiting","an","expression",",","one","returns","a","list","of","frozensets",".","Each","element","of","the","list","is","linked","to","a","possible","path",",","each","element","of","a","frozenset","is","linked","to","a","dependency","."]
code: def visit_Return(self, node):
      """
      Add edge from all possible callee to current function.
  
      Gather all the function call that led to the creation of the
      returned expression and add an edge to each of this function.
  
      When visiting an expression, one returns a list of frozensets. Each
      element of the list is linked to a possible path, each element of a
      frozenset is linked to a dependency.
      """
      if not node.value:
          # Yielding function can't return values
          return
      for dep_set in self.visit(node.value):
          if dep_set:
              for dep in dep_set:
                  self.result.add_edge(dep, self.current_function)
          else:
              self.result.add_edge(
                  TypeDependencies.NoDeps, self.current_function
              )
  
imports: import gast
  import itertools
  import os
  from pythran.analyses import GlobalDeclarations
  from pythran.errors import PythranInternalError
  from pythran.passmanager import ModuleAnalysis
  from pythran.types.conversion import PYTYPE_TO_CTYPE_TABLE
  from pythran.utils import get_variable
  from pythran.typing import List, Set, Dict, NDArray, Tuple, Pointer, Fun
  from pythran.graph import DiGraph
label_desc: Use image node_id 5 for calling the TypeDependencies obj's underlying member method code with example usage: obj.visit_Return(node) without return types