reftree.py (7759B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\script\util\reftree.py 2 from __future__ import print_function 3 import numbers 4 import types, blue, weakref, sys 5 try: 6 import gc 7 except: 8 gc = 'no gc availible' 9 sys.exc_clear() 10 11 def GetBlueObjects(typeName = None): 12 r = [] 13 for o in gc.get_objects(): 14 if type(o) != blue.BlueWrapper: 15 continue 16 if not typeName or typeName == o.__bluetype__: 17 r.append(o) 18 19 r.sort(lambda a, b: cmp(id(a), id(b))) 20 return r 21 22 23 class ActiveBlueObjects(object): 24 25 def __init__(self, name): 26 self.name = name 27 self.dict = weakref.WeakKeyDictionary() 28 self.count = 0 29 self.Update() 30 31 def Update(self): 32 r = weakref.WeakKeyDictionary() 33 for o in GetBlueObjects(self.name): 34 if o not in self.dict: 35 r[o] = None 36 self.dict[o] = self.count 37 38 self.count += 1 39 return r 40 41 42 def RefTree(*args): 43 depth = 3 44 if len(args) > 1: 45 depth = args[1] 46 omit = IdSet() 47 if len(args) > 2: 48 for o in args[2:]: 49 omit.Insert(o) 50 51 return RefNode(args, depth, omit) 52 53 54 def RefLeaves(*args): 55 depth = 3 56 if len(args) > 1: 57 depth = args[1] 58 omit = IdSet() 59 if len(args) > 2: 60 for o in args[2:]: 61 omit.Insert(o) 62 63 leaves = [] 64 omit.Insert(leaves) 65 RefNode(args, depth, omit, leaves=leaves) 66 return leaves 67 68 69 class RefNode(object): 70 71 def __init__(self, objtuple, depth = 3, omit = None, parent = None, leaves = None): 72 if not omit: 73 omit = IdSet() 74 self.children = [] 75 if depth: 76 depth = depth - 1 77 omit.Insert(objtuple[0]) 78 referrers = gc.get_referrers(objtuple[0]) 79 omit.Insert(referrers) 80 leaf = True 81 for r in referrers: 82 if r is objtuple or r in omit: 83 continue 84 if type(r) is types.TupleType and r[0] is objtuple[0] and r[-1] is None: 85 continue 86 tmp = (r,) 87 r = None 88 self.children.append(RefNode(tmp, depth, omit, objtuple[0], leaves)) 89 leaf = False 90 del tmp 91 92 if leaf and leaves is not None: 93 leaves.append(objtuple[0]) 94 omit.Remove(referrers) 95 del referrers 96 how = self.__Link(objtuple[0], parent) 97 if how: 98 self.repr = '%s in %s' % (how, self.__Repr(objtuple[0])) 99 else: 100 self.repr = self.__Repr(objtuple[0]) 101 102 def __str__(self): 103 return self.repr 104 105 def Print(self, indent = 0): 106 i = ' ' * indent * 4 107 print(i + str(self)) 108 indent = indent + 1 109 for c in self.children: 110 c.Print(indent) 111 112 def String(self, indent = 0): 113 i = ' ' * indent * 4 114 l = [i + str(self)] 115 indent = indent + 1 116 for c in self.children: 117 l.append(c.String(indent)) 118 119 return '\n'.join(l) 120 121 def __Link(self, item, parent): 122 t = type(item) 123 import types 124 if issubclass(t, types.DictType): 125 for k, v in item.iteritems(): 126 if v is parent: 127 return '[%s]' % repr(k) 128 129 for k in item.iterkeys(): 130 if k is parent: 131 return 'key' 132 133 elif t is types.ListType or t is types.TupleType: 134 for i in xrange(len(item)): 135 if item[i] is parent: 136 return '[%s]' % i 137 138 def __Repr(self, object): 139 t = type(object) 140 if t in (types.ListType, types.TupleType, types.DictType): 141 return '<%s object at %#x>' % (t.__name__, id(object)) 142 return repr(object) 143 144 145 class IdSet(object): 146 147 def __init__(self): 148 self.set = {} 149 150 def Insert(self, obj): 151 self.set[id(obj)] = True 152 153 def Remove(self, obj): 154 del self.set[id(obj)] 155 156 def __contains__(self, obj): 157 return id(obj) in self.set 158 159 160 def PrettyStr(obj, maxlen = 20, depth = -1, indent = 1, showid = 0, prune = 0): 161 if prune: 162 showid = 1 163 omitset = IdSet() 164 else: 165 omitset = None 166 return PPRecurse(obj, maxlen, depth, indent, showid, omitset) 167 168 169 def PrettyPrint(obj, maxlen = 20, depth = -1, indent = 1, showid = 0, prune = 0): 170 gunk = PrettyStr(obj, maxlen, depth, indent, showid, prune) 171 for line in gunk.split('\n'): 172 print(line) 173 174 175 def PPRecurse(obj, maxlen, depth, indent, showid, omitset): 176 if isinstance(obj, numbers.Real): 177 return repr(obj) 178 objType = type(obj) 179 if objType in [types.NoneType, types.StringType, types.UnicodeType]: 180 return repr(obj) 181 if (depth > 0 or depth < 0) and objType in [types.TupleType, 182 types.ListType, 183 types.DictType, 184 types.InstanceType]: 185 depth = depth - 1 186 truncate = 0 187 if objType in [types.TupleType, types.ListType, types.DictType]: 188 length = len(obj) 189 if maxlen >= 0 and length > maxlen: 190 truncate = 1 191 length = maxlen 192 if objType != types.DictType: 193 vals = obj[:length] 194 keys = None 195 if objType == types.TupleType: 196 head = '(' 197 tail = ')' 198 else: 199 head = '[' 200 tail = ']' 201 else: 202 it = obj.items() 203 it.sort() 204 keys = [ repr(key) + ' : ' for key, val in it[:length] ] 205 vals = [ val for key, val in it[:length] ] 206 head = '{' 207 tail = '}' 208 else: 209 keys = [ key for key in dir(obj) if key.find('__') != 0 and type(getattr(obj, key)) != types.MethodType ] 210 length = len(keys) 211 if maxlen >= 0 and length > maxlen: 212 truncate = 1 213 length = maxlen 214 vals = [ getattr(obj, key) for key in keys ] 215 keys = [ repr(key) + ' = ' for key in keys ] 216 head = '<inst of %s: ' % obj.__class__.__name__ 217 tail = '>' 218 if showid: 219 head += '(id %s)' % id(obj) 220 if omitset is not None: 221 if obj in omitset: 222 return head + '*skipped*' + tail 223 omitset.insert(obj) 224 if depth == 0: 225 indent = 0 226 return PPAssemble(head, keys, vals, tail, truncate, maxlen, depth, indent, showid, omitset) 227 if showid: 228 ids = '(id %s) ' % id(obj) 229 else: 230 ids = '' 231 if objType == types.InstanceType: 232 return '<%sinst of class %s>' % (ids, obj.__class__.__name__) 233 if objType == types.ClassType: 234 return '<class %s>' % obj.__name__ 235 if objType == types.ModuleType: 236 return '<module %s>' % obj.__name__ 237 return '<%s%s>' % (ids, repr(objType)) 238 239 240 def PPAssemble(head, prefixes, values, tail, ellipsis, maxlen, depth, indent, showid, omitset): 241 lines = [] 242 for i in range(len(values)): 243 if prefixes: 244 line = prefixes[i] 245 else: 246 line = '' 247 line += PPRecurse(values[i], maxlen, depth, indent, showid, omitset) 248 lines.append(line) 249 250 if ellipsis: 251 lines.append('...') 252 if indent: 253 bulk = PPIndent(',\n'.join(lines)) 254 result = '\n'.join([head, bulk, tail]) 255 else: 256 result = head + ', '.join(lines) + tail 257 return result 258 259 260 def PPIndent(text, nIndents = 1): 261 return '\n'.join([ '\t' * nIndents + line for line in text.split('\n') ]) 262 263 264 def PPIndentRest(text, nIndents = 1): 265 lines = text.split('\n') 266 return '\n'.join([lines[0]] + [ '\t' * nIndents + line for line in lines[1:] ])