import colorsys
from hashlib import md5
+import logging
import imp
from os import popen, getuid # for finding C extension dependencies with system calls
from pwd import getpwuid
import sys
+LOG = logging.getLogger('get_css')
+LOG.setLevel(logging.DEBUG)
+_STREAM_HANDLER = logging.StreamHandler()
+_STREAM_HANDLER.setLevel(logging.CRITICAL)
+_STREAM_HANDLER.setFormatter(
+ logging.Formatter('%(levelname)s - %(message)s'))
+LOG.addHandler(_STREAM_HANDLER)
+
USER=getpwuid(getuid())[0] # get effective user name
INVISIBLE_MODS=('__future__','copy','doctest','glob','optparse','os','qt','re',
Return false if it should be completely omitted.
"""
if self._invisible_name(mod_name) == True :
- if self._debug : print "\t\tinvisible module", mod_name
+ LOG.debug('invisible module %s' % mod_name)
return False
if self._link_outside_visited_nodes == False \
and check_external_link == True \
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)
+ LOG.debug('testing 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"
+ LOG.debug('invisible 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__"
+ LOG.debug('target 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
+ LOG.debug('invisible module parent path %s' % 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
+ LOG.debug('invisible module path %s' % 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"
+ LOG.debug('package')
return False
return True
def _invisible_name(self, mod_name) :
else :
self._hooks = hooks()
self.reset()
- self._debug=False
def render(self, ifile, root_module='__main__'):
depgraph,types,paths = self.get_data(ifile)
while True :
if self._hooks.continue_test() == False :
- if self.debug : print '\t\tcontinue_test() False'
+ LOG.debug('continue_test() False')
break
mod = self.next_module_target()
if mod == None :
- if self._debug : print '\t\tout of modules'
+ LOG.debug('out of modules')
break # out of modules
# I don't know anything about the underlying implementation,
# but I assume `key in dict` is more efficient than `key in list`
type = types[mod]
path = paths[mod]
if self._hooks.visible_mod_test(mod, deps, type, path) == False :
- if self._debug : print '\t\tinvisible module'
+ LOG.debug('invisible module')
continue
f.write(self._dotformat.module(mod, deps, type, path))
ds = deps.keys() # now we want a consistent ordering,
for d in ds :
if self._hooks.follow_edge_test(mod, type, path,
d, types[d], paths[d]) :
- if self._debug : print '\t\tfollow to %s' % d
+ LOG.debug('follow to %s' % d)
#print "%s, %s, %s, %s, %s, %s, %s" % (mod, deps, type, path, d, types[d], paths[d])
f.write(self._dotformat.edge(mod, deps, type, path,
d, types[d], paths[d]))
self.add_module_target(d)
else :
- if self._debug : print "\t\tdon't follow to %s" % d
+ LOG.debug("don't follow to %s" % d)
f.write(self._dotformat.footer())
types[dep] = None
if not dep in paths :
paths[dep] = None
- if self._debug :
- print "Adding dummy entry for missing module '%s'" \
- % dep
+ LOG.debug("Adding dummy entry for missing module '%s'"%dep)
return (depgraph, types, paths)
# keep a list of modules for a breadth-first search.
def add_module_target(self, target_module) :
if not target_module in self._modules_entered :
# add to the back of the stack
- if self._debug : print '\tpush', target_module
+ LOG.debug('push %s' % target_module)
self._modules_todo.append(target_module)
self._modules_entered.append(target_module)
# otherwise, it's already on the list, so don't worry about it.
def next_module_target(self) :
if len(self._modules_todo) > 0 :
- if self._debug : print '\tpop', self._modules_todo[0]
+ LOG.debug('pop %s' % self._modules_todo[0])
return self._modules_todo.pop(0) # remove from front of the list
else :
return None # no more modules! we're done.
usage = '%prog [options]'
p = OptionParser(usage=usage, description=__doc__)
+ p.add_option('-v', '--verbose', default=0, action='count',
+ help='Increment verbosity.')
p.add_option('-m', '--mono', dest='color', default=True,
action='store_false', help="Don't use color.")
p.add_option('-i', '--input', dest='input', default='-',
help="Path to input file ('-' for stdin, %default).")
options,args = p.parse_args()
+ log_level = logging.CRITICAL - 10*options.verbose
+ _STREAM_HANDLER.setLevel(log_level)
+
# Fancyness with shared hooks instance so we can do slick thinks like
# printing all modules just inside an invisible zone, since we'll need
# the dotformatter to know which nodes are visible.
hk = hooks(link_outside_visited_nodes=False)
- #hk._debug = True
dt = dotformat_Cext(colored=options.color, hooks_instance=hk)
py = pydepgraphdot(hooks_instance=hk, dotformat_instance=dt)
- #py._debug = True
if options.input == '-':
ifile = sys.stdin