NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

refbrowser.py (7914B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\pympler\refbrowser.py
      2 from __future__ import print_function
      3 import gc
      4 import inspect
      5 import sys
      6 from pympler import muppy
      7 from pympler import summary
      8 from pympler.util.compat import tkinter
      9 
     10 class _Node(object):
     11 
     12     def __init__(self, o, str_func = None):
     13         self.o = o
     14         self.children = []
     15         self.str_func = str_func
     16 
     17     def __str__(self):
     18         if self.str_func is not None:
     19             return self.str_func(self.o)
     20         else:
     21             return str(self.o)
     22 
     23 
     24 class RefBrowser(object):
     25 
     26     def __init__(self, rootobject, maxdepth = 3, str_func = summary._repr, repeat = True, stream = None):
     27         self.root = rootobject
     28         self.maxdepth = maxdepth
     29         self.str_func = str_func
     30         self.repeat = repeat
     31         self.stream = stream
     32         self.ignore = []
     33         self.already_included = set()
     34         self.ignore.append(self.already_included)
     35 
     36     def get_tree(self):
     37         self.ignore.append(inspect.currentframe())
     38         return self._get_tree(self.root, self.maxdepth)
     39 
     40     def _get_tree(self, root, maxdepth):
     41         objects = gc.get_referrers(root)
     42         res = _Node(root, self.str_func)
     43         self.already_included.add(id(root))
     44         if maxdepth == 0:
     45             return res
     46         self.ignore.append(inspect.currentframe())
     47         self.ignore.append(objects)
     48         for o in objects:
     49             if isinstance(o, dict):
     50                 if any((isinstance(ref, (_Node, RefBrowser)) for ref in gc.get_referrers(o))):
     51                     continue
     52             _id = id(o)
     53             if not self.repeat and _id in self.already_included:
     54                 s = self.str_func(o)
     55                 res.children.append('%s (already included, id %s)' % (s, _id))
     56                 continue
     57             if not isinstance(o, _Node) and o not in self.ignore:
     58                 res.children.append(self._get_tree(o, maxdepth - 1))
     59 
     60         return res
     61 
     62 
     63 class StreamBrowser(RefBrowser):
     64     hline = '-'
     65     vline = '|'
     66     cross = '+'
     67     space = ' '
     68 
     69     def print_tree(self, tree = None):
     70         if tree is None:
     71             tree = self.get_tree()
     72         self._print(tree, '', '')
     73 
     74     def _print(self, tree, prefix, carryon):
     75         level = prefix.count(self.cross) + prefix.count(self.vline)
     76         len_children = 0
     77         if isinstance(tree, _Node):
     78             len_children = len(tree.children)
     79         prefix += str(tree)
     80         carryon += self.space * len(str(tree))
     81         if level == self.maxdepth or not isinstance(tree, _Node) or len_children == 0:
     82             self.stream.write(prefix + '\n')
     83             return
     84         prefix += self.hline
     85         carryon += self.space
     86         if len(tree.children) > 1:
     87             prefix += self.cross
     88             carryon += self.vline
     89         prefix += self.hline
     90         carryon += self.space
     91         if len_children > 0:
     92             self._print(tree.children[0], prefix, carryon)
     93             for b in range(1, len_children):
     94                 prefix = carryon[:-2] + self.cross + self.hline
     95                 if b == len_children - 1:
     96                     carryon = carryon[:-2] + 2 * self.space
     97                 self._print(tree.children[b], prefix, carryon)
     98                 if b == len_children - 1:
     99                     if len(carryon.strip(' ')) == 0:
    100                         return
    101                     self.stream.write(carryon[:-2].rstrip() + '\n')
    102 
    103 
    104 class ConsoleBrowser(StreamBrowser):
    105 
    106     def __init__(self, *args, **kwargs):
    107         super(ConsoleBrowser, self).__init__(*args, **kwargs)
    108         if not self.stream:
    109             self.stream = sys.stdout
    110 
    111 
    112 class FileBrowser(StreamBrowser):
    113 
    114     def print_tree(self, filename, tree = None):
    115         old_stream = self.stream
    116         self.stream = open(filename, 'w')
    117         try:
    118             super(FileBrowser, self).print_tree(tree=tree)
    119         finally:
    120             self.stream.close()
    121             self.stream = old_stream
    122 
    123 
    124 try:
    125     from idlelib import TreeWidget as _TreeWidget
    126 
    127     class _TreeNode(_TreeWidget.TreeNode):
    128 
    129         def reload_referrers(self):
    130             self.item.node = self.item.reftree._get_tree(self.item.node.o, 1)
    131             self.item._clear_children()
    132             self.expand()
    133             self.update()
    134 
    135         def print_object(self):
    136             print(self.item.node.o)
    137 
    138         def drawtext(self):
    139             _TreeWidget.TreeNode.drawtext(self)
    140             menu = tkinter.Menu(self.canvas, tearoff=0)
    141             menu.add_command(label='reload referrers', command=self.reload_referrers)
    142             menu.add_command(label='print', command=self.print_object)
    143             menu.add_separator()
    144             menu.add_command(label='expand', command=self.expand)
    145             menu.add_separator()
    146             menu.add_command(label='Close Popup Menu')
    147 
    148             def do_popup(event):
    149                 menu.post(event.x_root, event.y_root)
    150 
    151             self.label.bind('<Button-3>', do_popup)
    152 
    153             def edit(self, event = None):
    154                 pass
    155 
    156             def edit_finish(self, event = None):
    157                 pass
    158 
    159             def edit_cancel(self, event = None):
    160                 pass
    161 
    162 
    163     class _ReferrerTreeItem(_TreeWidget.TreeItem, tkinter.Label):
    164 
    165         def __init__(self, parentwindow, node, reftree):
    166             _TreeWidget.TreeItem.__init__(self)
    167             tkinter.Label.__init__(self, parentwindow)
    168             self.node = node
    169             self.parentwindow = parentwindow
    170             self.reftree = reftree
    171 
    172         def _clear_children(self):
    173             new_children = []
    174             for child in self.node.children:
    175                 if not isinstance(child, _TreeNode):
    176                     new_children.append(child)
    177 
    178             self.node.children = new_children
    179 
    180         def GetText(self):
    181             return str(self.node)
    182 
    183         def GetIconName(self):
    184             if not self.IsExpandable():
    185                 return 'python'
    186 
    187         def IsExpandable(self):
    188             if not isinstance(self.node, _Node):
    189                 return False
    190             elif len(self.node.children) > 0:
    191                 return True
    192             else:
    193                 return muppy._is_containerobject(self.node.o)
    194 
    195         def GetSubList(self):
    196             sublist = []
    197             children = self.node.children
    198             if len(children) == 0 and muppy._is_containerobject(self.node.o):
    199                 self.node = self.reftree._get_tree(self.node.o, 1)
    200                 self._clear_children()
    201                 children = self.node.children
    202             for child in children:
    203                 item = _ReferrerTreeItem(self.parentwindow, child, self.reftree)
    204                 sublist.append(item)
    205 
    206             return sublist
    207 
    208 
    209 except ImportError:
    210     _TreeWidget = None
    211 
    212 def gui_default_str_function(o):
    213     return summary._repr(o) + '(id=%s)' % id(o)
    214 
    215 
    216 class InteractiveBrowser(RefBrowser):
    217 
    218     def __init__(self, rootobject, maxdepth = 3, str_func = gui_default_str_function, repeat = True):
    219         if tkinter is None:
    220             raise ImportError('InteractiveBrowser requires Tkinter to be installed.')
    221         RefBrowser.__init__(self, rootobject, maxdepth, str_func, repeat)
    222 
    223     def main(self, standalone = False):
    224         window = tkinter.Tk()
    225         sc = _TreeWidget.ScrolledCanvas(window, bg='white', highlightthickness=0, takefocus=1)
    226         sc.frame.pack(expand=1, fill='both')
    227         item = _ReferrerTreeItem(window, self.get_tree(), self)
    228         node = _TreeNode(sc.canvas, None, item)
    229         node.expand()
    230         if standalone:
    231             window.mainloop()
    232 
    233 
    234 superlist = []
    235 root = 'root'
    236 for i in range(3):
    237     tmp = [root]
    238     superlist.append(tmp)
    239 
    240 def foo(o):
    241     return str(type(o))
    242 
    243 
    244 def print_sample():
    245     cb = ConsoleBrowser(root, str_func=foo)
    246     cb.print_tree()
    247 
    248 
    249 def write_sample():
    250     fb = FileBrowser(root, str_func=foo)
    251     fb.print_tree('sample.txt')
    252 
    253 
    254 if __name__ == '__main__':
    255     write_sample()