def byframe(wrappers): """Collect objects according to the file name and line number of code where they were created. Can be printed using formatting.printsizesop.""" frames = ignoredict() for w in wrappers.values(): frame = utils.objframe(w.obj) if not frames.has_key(frame): val = (frame, 0, w) frames[frame] = val else: val = frames[frame] frames[frame] = (val[0], val[1] + w.size, val[2]) return frames
def findcreators(wrappers): """Given a set of wrappers, returns a structure which can be used to find what objects each line of code created. The structure it returns has a "members" field, which contains all scanned objects, a "size" field, which gives the total size of all objects, and a "back" field, which contains a dictionary with a structure for each function that created an object. The dict maps from (file name, line number) or None to structure. None is used when there are no functions to go back to - i.e. it was this function that started the sequence of calls that led to the creation of the object. Following a member of "back" will give a structure with "filename" and "line" fields. In this structure, the "members" field contains the objects that were created on this file/line, and the "size" field the size of those objects. The "back" field contains a dictionary with a structure for each function that had called this function to make an object. You can print these using formatting.printsizes(creators.back) where creators is the value returned by this function. """ try: from cpython.utils import objframe except ImportError: raise Exception, "Couldn't find cpython.utils.objframe - " + \ "you need a patched copy of Python, and you need to " \ "build the profiler using that copy." # First, collect all objects with the same frame traceback together. objects = {} for w in wrappers.itervalues(): traceback = objframe(w.obj) val = objects.setdefault(traceback, []) val.append(w) # Now make the structure (a trie). return _Creator(wrappers, objects, "<interpreter>", 0)