from sizer import sizes import itertools from set import * class ignored(object): """Any subtype of this is ignored by the scanner.""" pass class ignoredict(dict, ignored): pass class ignorelist(list, ignored): pass class ignoretuple(tuple, ignored): pass class ObjectWrapper(ignored): """A wrapper which contains as much useful information as we can find about a single object. Fields defined by this class: id - the id of the object being counted. type - a wrapper to the class of the object. size - the size of the object on its own. The wrapper is immutable. Annotations that want to add other fields should instead use decorator classes.""" # This is to save space in each wrapper. __slots__ = ["id", "type", "size"] def __init__(self, obj): """Constructor. Does not fill out much because it will only be called once.""" self.id = id(obj) self.size = 0 self.type = type(obj) def handles(self): """Returns an iterator that yields handles to objects referenced by this one. You can pass the handle to get_child or get_time. The handle None is reserved for this class.""" yield None def children(self): """"ReturnsĀ an iterator that yields the ids of all the objects referenced by this one.""" return itertools.imap(self.get_child, self.handles()) def get_child(self, handle): """Given a handle to a child, return its id. Raises KeyError if the handle is invalid.""" if handle is None: return self.type else: raise KeyError, \ "invalid argument to get_child: " + str(handle) def get_time(self, handle): """Given a handle to a child, return the earliest time (as a sequence number, not clock time) at which the child could been present in the parent object. Wrappers which don't know can return 0, as that's the smallest sequence number. Raises KeyError if the handle is invalid.""" if handle is None: return 0 else: raise KeyError, \ "invalid argument to get_time: " + str(handle) def __str__(self): return "wrap " + self.show() def __repr__(self): return "wrap " + self.show() def show(self, default = True): """Return a string representation of the object. If default is false, will not include information from the default implementation (type, address and so on).""" if default: return self.type.__name__ + " at " + hex(self.id) else: return "" ZeroObject = ObjectWrapper sizes.instance[ignored] = ZeroObject