- def fix(self,s):
- # Convert a module name to a syntactically correct node name
- return s.replace('.','_')
-
- def render(self):
- p,t = self.get_data()
-
- # normalise our input data
- for k,d in p.items():
- for v in d.keys():
- if not p.has_key(v):
- p[v] = {}
-
- f = self.get_output_file()
-
- f.write('digraph G {\n')
- #f.write('concentrate = true;\n')
- #f.write('ordering = out;\n')
- f.write('ranksep=1.0;\n')
- f.write('node [style=filled,fontname=Helvetica,fontsize=10];\n')
- allkd = p.items()
- allkd.sort()
- for k,d in allkd:
- tk = t.get(k)
- if self.use(k,tk):
- allv = d.keys()
- allv.sort()
- for v in allv:
- tv = t.get(v)
- if self.use(v,tv) and not self.toocommon(v,tv):
- f.write('%s -> %s' % ( self.fix(k),self.fix(v) ) )
- self.write_attributes(f,self.edge_attributes(k,v))
- f.write(';\n')
- f.write(self.fix(k))
- self.write_attributes(f,self.node_attributes(k,tk))
- f.write(';\n')
- f.write('}\n')
-
- def write_attributes(self,f,a):
- if a:
- f.write(' [')
- f.write(','.join(a))
- f.write(']')
-
- def node_attributes(self,k,type):
+class hooks (object) :
+ """
+ Modules show up if visible_mod_test(...) == True.
+
+ """
+ def __init__(self,
+ invisible_mods=INVISIBLE_MODS,
+ invisible_paths=INVISIBLE_PATHS,
+ visible_paths=VISIBLE_PATHS,
+ link_outside_visited_nodes=True,
+ ignore_builtins=True) :
+ self._invisible_mods = invisible_mods
+ self._invisible_paths = invisible_paths
+ self._visible_paths = visible_paths
+ self._link_outside_visited_nodes = link_outside_visited_nodes
+ self._ignore_builtins = ignore_builtins
+ self._entered_bonus_nodes = {} # a dict of bonus nodes already printed
+ self._debug = False
+ def continue_test(self) :
+ return True
+ def visible_mod_test(self, mod_name, dep_dict, type, path,
+ check_external_link=True) :
+ """
+ Return true if this module is interesting and should be drawn.
+ Return false if it should be completely omitted.
+ """
+ if self._invisible_name(mod_name) == True :
+ if self._debug : print "\t\tinvisible module", mod_name
+ return False
+ if self._link_outside_visited_nodes == False \
+ and check_external_link == True \
+ and mod_name != '__main__' :
+ if self.follow_edge_test('__main__', imp.PY_SOURCE, './dummy.py',
+ mod_name, type, path) == False:
+ return False # don't draw nodes we wouldn't visit
+ return True
+ def follow_edge_test(self, module_name, type, path,
+ dname, dtype, dpath):
+ if self._debug :
+ print "\ttesting edge from %s %s %s to %s %s %s" \
+ % (module_name, type, path, dname, dtype, dpath)
+ if self.visible_mod_test(dname, None, dtype, dpath,
+ check_external_link=False) == False :
+ if self._debug : print "\t\tinvisible target module"
+ return False # don't draw edges to invisible modules
+ elif dname == '__main__':
+ # references *to* __main__ are never interesting. omitting them means
+ # that main floats to the top of the page
+ if self._debug : print "\t\ttarget is __main__"
+ return False
+ elif self._invisible_path(path) == True and module_name != '__main__' :
+ # the path for __main__ seems to be it's filename
+ if self._debug : print "\t\tinvisible module parent path", path
+ return False # don't draw edges from invisible path modules
+ elif self._link_outside_visited_nodes == False \
+ and self._invisible_path(dpath) == True :
+ if self._debug : print "\t\tinvisible module path", dpath
+ return False # don't draw edges to invisible path modules
+ elif dtype == imp.PKG_DIRECTORY:
+ # don't draw edges to packages.
+ if self._debug : print "\t\tpackage"
+ return False
+ return True
+ def _invisible_name(self, mod_name) :
+ if mod_name in self._invisible_mods :
+ # nearly all modules use all of these... more or less.
+ # They add nothing to our diagram.
+ return True
+ return False
+ def _invisible_path(self, path) :
+ """
+ Paths are visible by default. Adding a regexp to invisible_paths hides
+ matching paths, unless the path matches a regexp in visible_paths, in
+ which case it is again visible.
+ """
+ if path == None and self._ignore_builtins :
+ return True # ignore modules without paths (builtins, etc)
+ if (_pathmatch(self._invisible_paths, path)
+ and not _pathmatch(self._visible_paths, path)):
+ return True
+ return False
+
+class dotformat (object) :
+ def __init__(self, colored=True, hooks_instance=None) :
+ if hooks_instance != None :
+ self._hooks = hooks_instance
+ else :
+ self._hooks = hooks()
+ self._colored = colored
+ def header(self):
+ return ('digraph G {\n'
+ #' concentrate = true;\n'
+ #' ordering = out;\n'
+ ' ranksep=1.0;\n'
+ ' node [style=filled,fontname=Helvetica,fontsize=10];\n')
+ def footer(self):
+ return '}\n'
+ def module(self, mod_name, dep_dict, type, path) :
+ name = self._fix_name(mod_name)