def __init__(self, name, log=False, limit=None, threaded=False): Job.__init__(self, name) self._log = log self._limit = limit # set up our data structures self._visitedIds = set() self._id2pathStr = {} self._id2container = {} self._type2id2len = {} self._instanceDictIds = set() # for breadth-first searching self._queue = Queue() jobMgr.add(self) if threaded == False: jobMgr.finish(self)
class ContainerReport(Job): notify = directNotify.newCategory("ContainerReport") # set of containers that should not be included in the report PrivateIds = set() def __init__(self, name, log=False, limit=None, threaded=False): Job.__init__(self, name) self._log = log self._limit = limit # set up our data structures self._visitedIds = set() self._id2pathStr = {} self._id2container = {} self._type2id2len = {} self._instanceDictIds = set() # for breadth-first searching self._queue = Queue() jobMgr.add(self) if threaded == False: jobMgr.finish(self) def destroy(self): del self._queue del self._instanceDictIds del self._type2id2len del self._id2container del self._id2pathStr del self._visitedIds del self._limit del self._log def finished(self): if self._log: self.destroy() def run(self): ContainerReport.PrivateIds.update(set([ id(ContainerReport.PrivateIds), id(self._visitedIds), id(self._id2pathStr), id(self._id2container), id(self._type2id2len), id(self._queue), id(self._instanceDictIds), ])) # push on a few things that we want to give priority # for the sake of the variable-name printouts try: base except: pass else: self._enqueueContainer( base.__dict__, 'base') try: simbase except: pass else: self._enqueueContainer( simbase.__dict__, 'simbase') self._queue.push(__builtins__) self._id2pathStr[id(__builtins__)] = '' while len(self._queue) > 0: # yield up here instead of at the end, since we skip back to the # top of the while loop from various points yield None parentObj = self._queue.pop() #print '%s: %s, %s' % (id(parentObj), type(parentObj), self._id2pathStr[id(parentObj)]) isInstanceDict = False if id(parentObj) in self._instanceDictIds: isInstanceDict = True try: if parentObj.__class__.__name__ == 'method-wrapper': continue except: pass if type(parentObj) in (types.StringType, types.UnicodeType): continue if type(parentObj) in (types.ModuleType, types.InstanceType): child = parentObj.__dict__ if self._examine(child): assert (self._queue.back() is child) self._instanceDictIds.add(id(child)) self._id2pathStr[id(child)] = str(self._id2pathStr[id(parentObj)]) continue if type(parentObj) is types.DictType: key = None attr = None keys = parentObj.keys() try: keys.sort() except TypeError, e: self.notify.warning('non-sortable dict keys: %s: %s' % (self._id2pathStr[id(parentObj)], repr(e))) for key in keys: try: attr = parentObj[key] except KeyError, e: self.notify.warning('could not index into %s with key %s' % (self._id2pathStr[id(parentObj)], key)) if id(attr) not in self._visitedIds: self._visitedIds.add(id(attr)) if self._examine(attr): assert (self._queue.back() is attr) if parentObj is __builtins__: self._id2pathStr[id(attr)] = key else: if isInstanceDict: self._id2pathStr[id(attr)] = self._id2pathStr[id(parentObj)] + '.%s' % key else: self._id2pathStr[id(attr)] = self._id2pathStr[id(parentObj)] + '[%s]' % safeRepr(key) del key del attr continue if type(parentObj) is not types.FileType: try: itr = iter(parentObj) except: pass else: try: index = 0 while 1: try: attr = itr.next() except: # some custom classes don't do well when iterated attr = None break if id(attr) not in self._visitedIds: self._visitedIds.add(id(attr)) if self._examine(attr): assert (self._queue.back() is attr) self._id2pathStr[id(attr)] = self._id2pathStr[id(parentObj)] + '[%s]' % index index += 1 del attr except StopIteration, e: pass del itr continue