home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2012 January / maximum-cd-2012-01.iso / DiscContents / digsby_setup.exe / lib / util / introspect.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2011-10-05  |  31.7 KB  |  1,043 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. from __future__ import with_statement
  5. import sys
  6. import time
  7. import threading
  8. import string
  9. import logging
  10. import re
  11. import keyword
  12. import types
  13. import inspect
  14. import primitives
  15. import primitives.funcs as primitives
  16. from weakref import ref
  17. from types import GeneratorType
  18. from path import path
  19. from collections import defaultdict
  20. from traceback import print_exc
  21. import warnings
  22. import gc
  23. import operator
  24. log = logging.getLogger('util.introspect')
  25. oldvars = vars
  26.  
  27. def uncollectable(clz):
  28.     import gc
  29.     gc.collect()
  30.     return _[1]
  31.  
  32.  
  33. class debug_property(object):
  34.     
  35.     def __init__(self, fget = None, fset = None, fdel = None, doc = None):
  36.         self._debug_property__get = fget
  37.         self._debug_property__set = fset
  38.         self._debug_property__del = fdel
  39.         self.__doc__ = doc
  40.  
  41.     
  42.     def __get__(self, inst, type = None):
  43.         if inst is None:
  44.             return self
  45.         if self._debug_property__get is None:
  46.             raise AttributeError, 'unreadable attribute'
  47.         self._debug_property__get is None
  48.         
  49.         try:
  50.             return self._debug_property__get(inst)
  51.         except AttributeError:
  52.             inst is None
  53.             e = inst is None
  54.             print_exc()
  55.             raise AssertionError('attribute error during __get__')
  56.         except:
  57.             inst is None
  58.  
  59.  
  60.     
  61.     def __set__(self, inst, value):
  62.         if self._debug_property__set is None:
  63.             raise AttributeError, "can't set attribute"
  64.         self._debug_property__set is None
  65.         
  66.         try:
  67.             return self._debug_property__set(inst, value)
  68.         except AttributeError:
  69.             e = None
  70.             print_exc()
  71.             raise AssertionError('attribute error during __set__')
  72.  
  73.  
  74.     
  75.     def __delete__(self, inst):
  76.         if self._debug_property__del is None:
  77.             raise AttributeError, "can't delete attribute"
  78.         self._debug_property__del is None
  79.         
  80.         try:
  81.             return self._debug_property__del(inst)
  82.         except AttributeError:
  83.             e = None
  84.             print_exc()
  85.             raise AssertionError('attribute error during __del__')
  86.  
  87.  
  88.  
  89.  
  90. def vars(obj = None):
  91.     res = { }
  92.     if hasattr(obj, '__dict__'):
  93.         return oldvars(obj)
  94.     if hasattr(obj, '__slots__'):
  95.         return (dict,)((lambda .0: for attr in .0:
  96. (attr, getattr(obj, attr, sentinel)))(obj.__slots__))
  97.     if hasattr(obj, 'keys'):
  98.         return obj
  99.     return dict((lambda .0: for x in .0:
  100. (x, sentinel))(obj))
  101.  
  102. version_23 = sys.version_info < (2, 4)
  103.  
  104. def this_list():
  105.     d = inspect.currentframe(1).f_locals
  106.     nestlevel = 1
  107.     while '_[%d]' % nestlevel in d:
  108.         nestlevel += 1
  109.     result = d['_[%d]' % (nestlevel - 1)]
  110.     if version_23:
  111.         return result.__self__
  112.     return result
  113.  
  114.  
  115. def cannotcompile(f):
  116.     return f
  117.  
  118.  
  119. def stack_trace(level = 1, frame = None):
  120.     
  121.     try:
  122.         if frame is None:
  123.             f = sys._getframe(level)
  124.         else:
  125.             f = frame
  126.         frames = []
  127.         while f is not None:
  128.             c = f.f_code
  129.             frames.insert(0, (c.co_filename, c.co_firstlineno, c.co_name))
  130.             f = f.f_back
  131.         return frames
  132.     finally:
  133.         del f
  134.         del frame
  135.  
  136.  
  137.  
  138. def print_stack_trace(frame = None):
  139.     trace = stack_trace(2, frame)
  140.     for frame in trace:
  141.         print '  File "%s", line %d, in %s' % frame
  142.     
  143.  
  144.  
  145. def print_stack_traces():
  146.     frames = sys._current_frames().items()
  147.     for id, frame in frames:
  148.         print 'Frame %d:' % id
  149.         print_stack_trace(frame)
  150.     
  151.  
  152.  
  153. def is_all(seq, my_types = None):
  154.     if not seq:
  155.         
  156.         try:
  157.             iter(my_types)
  158.         except:
  159.             t = my_types
  160.         else:
  161.             t = my_types[0]
  162.         finally:
  163.             return (True, t)
  164.  
  165.     
  166.     if type(my_types) == type:
  167.         my_types = [
  168.             my_types]
  169.     
  170.     if my_types == None:
  171.         my_types = [
  172.             type(seq[0])]
  173.     
  174.     all = True
  175.     for elem in seq:
  176.         if type(elem) not in my_types:
  177.             all = False
  178.             break
  179.             continue
  180.     
  181.     if all:
  182.         return (all, my_types[0])
  183.     return (all, None)
  184.  
  185.  
  186. def get_func_name(level = 1):
  187.     return sys._getframe(level).f_code.co_name
  188.  
  189.  
  190. def get_func(obj, command, *params):
  191.     
  192.     try:
  193.         func = getattr(obj, command.lower())
  194.         log.debug('Finding %s.%s%s', obj.__class__.__name__, command.lower(), params)
  195.     except AttributeError:
  196.         obj.__class__.__name__(command.lower(), ', '.join, [], []([ repr(x) for x in params ]))
  197.         func = None
  198.     except:
  199.         '%s has no function to handle: %s(%s)'
  200.  
  201.     return func
  202.  
  203.  
  204. def decormethod(decorator):
  205.     
  206.     def wrapper(method):
  207.         return (lambda self: decorator(self, method, *args, **kw))
  208.  
  209.     return wrapper
  210.  
  211.  
  212. def funcToMethod(func, clas, method_name = None):
  213.     func.im_class = clas
  214.     func.im_func = func
  215.     func.im_self = None
  216.     if not method_name:
  217.         method_name = func.__name__
  218.     
  219.     clas.__dict__[method_name] = func
  220.  
  221.  
  222. def attach_method(obj, func, name = None):
  223.     if not name:
  224.         pass
  225.     name = func.__name__
  226.     cls = obj.__class__
  227.     cls.temp_foo = func
  228.     obj.__setattr__(name, cls.temp_foo)
  229.     del cls.temp_foo
  230.  
  231.  
  232. def isgeneratormethod(object):
  233.     return isinstance(getattr(object, '__self__', None), GeneratorType)
  234.  
  235. CO_VARARGS = 4
  236. CO_VARKEYWORDS = 8
  237.  
  238. def callany(func, *args):
  239.     if not callable(func):
  240.         raise TypeError, "callany's first argument must be callable"
  241.     callable(func)
  242.     CallLater = CallLater
  243.     CallLaterDelegate = CallLaterDelegate
  244.     CallbackSequence = CallbackSequence
  245.     import util.callbacks
  246.     c = func
  247.     while isinstance(c, CallLater):
  248.         c = c.cb
  249.     if isinstance(c, CallbackSequence):
  250.         c = c.__call__
  251.     
  252.     if isinstance(c, CallLaterDelegate):
  253.         return [ callany(child, *args) for child in c ]
  254.     if hasattr(c, 'im_func'):
  255.         code = c.im_func.func_code
  256.         nargs = code.co_argcount - 1
  257.         codeflags = code.co_flags
  258.     elif hasattr(c, 'func_code'):
  259.         code = c.func_code
  260.         nargs = code.co_argcount
  261.         codeflags = code.co_flags
  262.     else:
  263.         code = None
  264.         codeflags = 0
  265.         nargs = len(args)
  266.     hasargs = codeflags & CO_VARARGS
  267.     haskwargs = codeflags & CO_VARKEYWORDS
  268.     if haskwargs:
  269.         args = []
  270.         msg = 'callany given a kwarg function (%r): no arguments will be passed!' % funcinfo(c)
  271.         warnings.warn(msg)
  272.         if getattr(sys, 'DEV', False):
  273.             raise AssertionError(msg)
  274.         getattr(sys, 'DEV', False)
  275.     
  276.     if not hasargs:
  277.         args = list(args)[:nargs]
  278.         args += [
  279.             None] * (nargs - len(args))
  280.     
  281.     return func(*args)
  282.  
  283.  
  284. def pythonize(s, lower = True):
  285.     if not isinstance(s, basestring):
  286.         raise TypeError, 'Only string/unicode types can be pythonized!'
  287.     isinstance(s, basestring)
  288.     allowed = string.letters + string.digits + '_'
  289.     s = str(s).strip()
  290.     if s.startswith('__') and s.endswith('__'):
  291.         s = s[2:-2]
  292.     
  293.     if not s:
  294.         return s
  295.     s = s if s[0] in string.digits else '' + s
  296.     s = None if keyword.iskeyword(s) else '' + s
  297.     new_s = ''
  298.     for ch in s:
  299.         None += new_s if ch in allowed else '_'
  300.     
  301.     if lower:
  302.         new_s = new_s.lower()
  303.     
  304.     return new_s
  305.  
  306. attached_functions = { }
  307.  
  308. def dyn_dispatch(obj, func_name, *args, **kwargs):
  309.     func_name = pythonize(str(func_name))
  310.     if not hasattr(obj, func_name):
  311.         fn = sys._getframe(1).f_code.co_filename
  312.         d = dict(name = func_name)
  313.         d.update(kwargs)
  314.         code = str(obj.func_templ % d)
  315.         f = open(fn, 'a')
  316.         f.write(code)
  317.         f.close()
  318.         newcode = ''
  319.         code = code.replace('\n    ', '\n')
  320.         exec code
  321.         attach_method(obj, locals()[func_name])
  322.         l = attached_functions.setdefault(obj.__class__, [])
  323.         l.append(func_name)
  324.     
  325.     if func_name in attached_functions.setdefault(obj.__class__, []):
  326.         args = [
  327.             obj] + list(args)
  328.     
  329.     return getattr(obj, func_name)(*args, **kwargs)
  330.  
  331.  
  332. class CallTemplate(string.Template):
  333.     
  334.     def __init__(self, templ):
  335.         string.Template.__init__(self, templ)
  336.         self.placeholders = [ m[1] for m in re.findall(self.pattern, self.template) ]
  337.  
  338.     
  339.     def __call__(self, *args, **kws):
  340.         return self.substitute(**primitives.dictadd(zip(self.placeholders, args), kws))
  341.  
  342.  
  343. _profilers_enabled = False
  344.  
  345. def set_profilers_enabled(val):
  346.     global _profilers_enabled
  347.     _profilers_enabled = val
  348.  
  349.  
  350. def use_profiler(target, callable):
  351.     target.profiler = EnableDisableProfiler()
  352.     
  353.     def cb():
  354.         if not _profilers_enabled:
  355.             target.profiler.disable()
  356.         
  357.         callable()
  358.  
  359.     if sys.platform == 'win32':
  360.         SEHGuard = SEHGuard
  361.         import wx
  362.     else:
  363.         
  364.         SEHGuard = lambda c: c()
  365.     
  366.     def run_with_sehguard():
  367.         return SEHGuard(cb)
  368.  
  369.     target.profiler.runcall(run_with_sehguard)
  370.  
  371.  
  372. def all_profilers():
  373.     return dict((lambda .0: for thread in .0:
  374. if hasattr(thread, 'profiler'):
  375. (thread, thread.profiler)continue)(threading.enumerate()))
  376.  
  377.  
  378. def get_profile_report(profiler):
  379.     Stats = Stats
  380.     import pstats
  381.     StringIO = StringIO
  382.     import cStringIO
  383.     io = StringIO()
  384.     stats = Stats(profiler, stream = io)
  385.     io.write('\nby cumulative time:\n\n')
  386.     stats.sort_stats('cumulative').print_stats(25)
  387.     io.write('\nby number of calls:\n\n')
  388.     stats.sort_stats('time').print_stats(25)
  389.     return io.getvalue()
  390.  
  391. from cProfile import Profile
  392. Profile.report = get_profile_report
  393.  
  394. def profilereport():
  395.     s = []
  396.     for thread, profiler in all_profilers().iteritems():
  397.         s.extend([
  398.             repr(thread),
  399.             profiler.report()])
  400.     
  401.     return '\n'.join(s)
  402.  
  403.  
  404. class Memoize(object):
  405.     __slots__ = [
  406.         'func',
  407.         'cache']
  408.     
  409.     def __init__(self, func):
  410.         self.func = func
  411.         self.cache = { }
  412.  
  413.     
  414.     def __repr__(self):
  415.         return '<Memoize for %r (%d items)>' % (funcinfo(self.func), len(self.cache))
  416.  
  417.     
  418.     def __call__(self, *args, **kwargs):
  419.         key = (args, tuple(kwargs.items()))
  420.         cache = self.cache
  421.         
  422.         try:
  423.             return cache[key]
  424.         except KeyError:
  425.             return cache.setdefault(key, self.func(*args, **kwargs))
  426.  
  427.  
  428.  
  429. memoize = Memoize
  430.  
  431. memoizedprop = lambda getter: property(memoize(getter))
  432.  
  433. def print_timing(num_runs = 1):
  434.     
  435.     def wrapper1(func):
  436.         
  437.         def wrapper(*arg, **kwargs):
  438.             t1 = time.clock()
  439.             for i in range(num_runs):
  440.                 res = func(*arg, **kwargs)
  441.             
  442.             t2 = time.clock()
  443.             print '%s took %0.3fms.' % (func.func_name, (t2 - t1) * 1000 / float(num_runs))
  444.             return res
  445.  
  446.         return wrapper
  447.  
  448.     return wrapper1
  449.  
  450.  
  451. class i(int):
  452.     
  453.     def __iter__(self):
  454.         return iter(xrange(self))
  455.  
  456.  
  457.  
  458. def reload_(obj):
  459.     for klass in reversed(obj.__class__.__mro__):
  460.         if klass not in __builtins__:
  461.             reload(sys.modules[klass.__module__])
  462.             continue
  463.     
  464.     return reload2_(obj)
  465.  
  466.  
  467. def reload2_(obj):
  468.     m = sys.modules[obj.__class__.__module__]
  469.     m = reload(m)
  470.     cl = getattr(m, obj.__class__.__name__)
  471.     obj.__class__ = cl
  472.     return sys.modules[obj.__class__.__module__]
  473.  
  474.  
  475. def bitflags_enabled(map, flags):
  476.     bits = _[1]
  477.     return _[2]
  478.  
  479.  
  480. def import_module(modulePath):
  481.     aMod = sys.modules.get(modulePath, False)
  482.     if aMod is False or not isinstance(aMod, types.ModuleType):
  483.         if isinstance(modulePath, unicode):
  484.             modulePath = modulePath.encode('filesys')
  485.         
  486.         aMod = __import__(modulePath, globals(), locals(), [
  487.             ''])
  488.         sys.modules[modulePath] = aMod
  489.     
  490.     return aMod
  491.  
  492.  
  493. def import_function(fullFuncName):
  494.     if not isinstance(fullFuncName, basestring):
  495.         raise TypeError('import_function needs a string, you gave a %s' % type(fullFuncName))
  496.     isinstance(fullFuncName, basestring)
  497.     lastDot = fullFuncName.rfind(u'.')
  498.     funcName = fullFuncName[lastDot + 1:]
  499.     modPath = fullFuncName[:lastDot]
  500.     aMod = import_module(modPath)
  501.     
  502.     try:
  503.         aFunc = getattr(aMod, funcName)
  504.     except AttributeError:
  505.         e = None
  506.         log.error('%r. Module contents = %r', e, aMod.__dict__)
  507.         raise e
  508.  
  509.     return aFunc
  510.  
  511.  
  512. def base_classes(clazz):
  513.     classes = []
  514.     for cl in clazz.__bases__:
  515.         classes += [
  516.             cl] + base_classes(cl)
  517.     
  518.     return list(set(classes))
  519.  
  520. base_classes = memoize(base_classes)
  521.  
  522. def wrapfunc(obj, name, processor, avoid_doublewrap = True):
  523.     call = getattr(obj, name)
  524.     if avoid_doublewrap and getattr(call, 'processor', None) is processor:
  525.         return None
  526.     original_callable = getattr(call, 'im_func', call)
  527.     
  528.     def wrappedfunc(*args, **kwargs):
  529.         return processor(original_callable, *args, **kwargs)
  530.  
  531.     wrappedfunc.original = call
  532.     wrappedfunc.processor = processor
  533.     wrappedfunc.__name__ = getattr(call, '__name__', name)
  534.     if inspect.isclass(obj):
  535.         if hasattr(call, 'im_self'):
  536.             if call.im_self:
  537.                 wrappedfunc = classmethod(wrappedfunc)
  538.             
  539.         else:
  540.             wrappedfunc = staticmethod(wrappedfunc)
  541.     
  542.     setattr(obj, name, wrappedfunc)
  543.  
  544.  
  545. def unwrapfunc(obj, name):
  546.     setattr(obj, name, getattr(obj, name).original)
  547.  
  548.  
  549. def tracing_processor(original_callable, *args, **kwargs):
  550.     r_name = getattr(original_callable, '__name__', '<unknown>')
  551.     r_args = [ (primitives.try_this,)((lambda : repr(a)), '<%s at %s>' % (type(a), id(a))) for None in args ]
  552.     []([ '%s-%r' % x for x in kwargs.iteritems() ])
  553.     print '-> %s(%s)' % (r_name, ', '.join(r_args))
  554.     return original_callable(*args, **kwargs)
  555.  
  556.  
  557. def add_tracing(class_object, method_name):
  558.     wrapfunc(class_object, method_name, tracing_processor)
  559.  
  560.  
  561. def trace(clz):
  562.     for meth, v in inspect.getmembers(clz, inspect.ismethod):
  563.         if not meth.startswith('__'):
  564.             add_tracing(clz, meth)
  565.             continue
  566.     
  567.  
  568.  
  569. def typecounts(contains = None, objs = None):
  570.     import gc
  571.     if objs is None:
  572.         objs = gc.get_objects()
  573.     
  574.     counts = defaultdict(int)
  575.     for obj in objs:
  576.         counts[type(obj).__name__] += 1
  577.     
  578.     if contains is not None:
  579.         
  580.         contains = lambda s, ss = contains: s[0].find(ss) != -1
  581.     
  582.     return filter(contains, sorted(counts.iteritems(), key = (lambda a: a[1]), reverse = True))
  583.  
  584.  
  585. def funcinfo(func):
  586.     if not hasattr(func, 'func_code'):
  587.         return repr(func)
  588.     name = getattr(func, '__name__', getattr(getattr(func, '__class__', None), '__name__', '<UNKNOWN OBJECT>'))
  589.     c = func.func_code
  590.     filename = c.co_filename
  591.     if not isinstance(filename, str):
  592.         filename = '??'
  593.     else:
  594.         
  595.         try:
  596.             
  597.             try:
  598.                 filepath = path(c.co_filename)
  599.             except UnicodeDecodeError:
  600.                 pass
  601.  
  602.             if filepath.name == '__init__.py':
  603.                 filename = filepath.parent.name + '/' + filepath.name
  604.             else:
  605.                 filename = filepath.name
  606.         except Exception:
  607.             print_exc()
  608.  
  609.     return '<%s (%s:%s)>' % (name, filename, c.co_firstlineno)
  610.  
  611.  
  612. def leakfinder():
  613.     import wx
  614.     pprint = pprint
  615.     import pprint
  616.     typecounts = typecounts
  617.     import util
  618.     import gc
  619.     f = wx.Frame(None, pos = (30, 30), style = wx.DEFAULT_FRAME_STYLE | wx.FRAME_TOOL_WINDOW | wx.STAY_ON_TOP)
  620.     b = wx.Button(f, -1, 'memory stats')
  621.     b2 = wx.Button(f, -1, 'all functions')
  622.     b3 = wx.Button(f, -1, 'all unnamed lambdas')
  623.     sz = f.Sizer = wx.BoxSizer(wx.VERTICAL)
  624.     sz.AddMany([
  625.         b,
  626.         b2,
  627.         b3])
  628.     f.stats = { }
  629.     
  630.     def onstats(e):
  631.         new = typecounts()
  632.         news = dict(new)
  633.         for cname in news.keys():
  634.             if cname in f.stats:
  635.                 diff = news[cname] - f.stats[cname][0]
  636.                 f.stats[cname] = (news[cname], diff)
  637.                 continue
  638.             f.stats[cname] = (news[cname], 0)
  639.         
  640.         print '****' * 10
  641.         pprint(sorted(f.stats.iteritems(), key = (lambda a: a[1])))
  642.  
  643.     
  644.     def on2(e, filterName = ((None, None, None), None)):
  645.         funcs = _[1]
  646.         counts = defaultdict(int)
  647.         for f in funcs:
  648.             pass
  649.         
  650.         print '((Filename, Line Number), Count)'
  651.         pprint(sorted(list(counts.iteritems()), key = (lambda i: i[1])))
  652.  
  653.     b.Bind(wx.EVT_BUTTON, onstats)
  654.     b2.Bind(wx.EVT_BUTTON, on2)
  655.     b3.Bind((wx.EVT_BUTTON,), (lambda e: on2(e, '<lambda>')))
  656.     f.Sizer.Layout()
  657.     f.Fit()
  658.     f.Show()
  659.  
  660.  
  661. def counts(seq, groupby):
  662.     counts = defaultdict(int)
  663.     for obj in seq:
  664.         counts[groupby(obj)] += 1
  665.     
  666.     return sorted((lambda .0: for val, count in .0:
  667. (count, val))(counts.iteritems()), reverse = True)
  668.  
  669.  
  670. class InstanceTracker(object):
  671.     
  672.     def track(self):
  673.         
  674.         try:
  675.             _instances = self.__class__._instances
  676.         except AttributeError:
  677.             self.__class__._instances = [
  678.                 ref(self)]
  679.  
  680.         for wref in _instances:
  681.             if wref() is self:
  682.                 break
  683.                 continue
  684.         
  685.  
  686.     
  687.     def all(cls):
  688.         objs = []
  689.         
  690.         try:
  691.             wrefs = cls._instances
  692.         except AttributeError:
  693.             return []
  694.  
  695.         import wx
  696.         for wref in wrefs[:]:
  697.             obj = wref()
  698.             if obj is not None:
  699.                 if wx.IsDestroyed(obj):
  700.                     wrefs.remove(wref)
  701.                 else:
  702.                     objs.append(obj)
  703.             wx.IsDestroyed(obj)
  704.         
  705.         return objs
  706.  
  707.     all = classmethod(all)
  708.     
  709.     def CallAll(cls, func, *args, **kwargs):
  710.         import wx
  711.         
  712.         try:
  713.             instances = cls._instances
  714.         except AttributeError:
  715.             return None
  716.  
  717.         removeList = []
  718.         for wref in instances:
  719.             obj = wref()
  720.             if obj is not None and not wx.IsDestroyed(obj):
  721.                 
  722.                 try:
  723.                     func(obj, *args, **kwargs)
  724.                 except TypeError:
  725.                     print type(obj), repr(obj)
  726.                     raise 
  727.                 except:
  728.                     None<EXCEPTION MATCH>TypeError
  729.                 
  730.  
  731.             None<EXCEPTION MATCH>TypeError
  732.             removeList.append(wref)
  733.         
  734.         for wref in removeList:
  735.             
  736.             try:
  737.                 instances.remove(wref)
  738.             continue
  739.             except ValueError:
  740.                 continue
  741.             
  742.  
  743.         
  744.  
  745.     CallAll = classmethod(CallAll)
  746.  
  747.  
  748. class DeadObjectError(AttributeError):
  749.     pass
  750.  
  751.  
  752. class DeadObject(object):
  753.     reprStr = 'Placeholder for DELETED %s object! Please unhook all callbacks, observers, and event handlers PROPERLY.'
  754.     attrStr = 'Attribute access no longer allowed - This object has signaled that it is no longer valid!'
  755.     
  756.     def __repr__(self):
  757.         if not hasattr(self, '_name'):
  758.             self._name = '[unknown]'
  759.         
  760.         return self.reprStr % self._name
  761.  
  762.     
  763.     def __getattr__(self, *args):
  764.         if not hasattr(self, '_name'):
  765.             self._name = '[unknown]'
  766.         
  767.         raise DeadObjectError(self.attrStr % self._name)
  768.  
  769.     
  770.     def __nonzero__(self):
  771.         return 0
  772.  
  773.  
  774.  
  775. def generator_repr(g):
  776.     frame = g.gi_frame
  777.     code = frame.f_code
  778.     return '<generator %s (%s:%d) at 0x%08x>' % (code.co_name, code.co_filename, frame.f_lineno, id(g))
  779.  
  780.  
  781. def gc_diagnostics(stream = None):
  782.     import gc
  783.     import sys
  784.     import linecache
  785.     import locale
  786.     itemgetter = itemgetter
  787.     import operator
  788.     ifilterfalse = ifilterfalse
  789.     imap = imap
  790.     import itertools
  791.     getrefcount = sys.getrefcount
  792.     if stream is None:
  793.         stream = sys.stdout
  794.     
  795.     linecache.clearcache()
  796.     gc.collect()
  797.     
  798.     def w(s):
  799.         stream.write(s + '\n')
  800.  
  801.     filter_objects = ((), '')
  802.     filter_types = (type,)
  803.     objs = _[1]
  804.     itemgetter0 = itemgetter(0)
  805.     itemgetter1 = itemgetter(1)
  806.     objs.sort(key = itemgetter0)
  807.     num_objs = len(objs)
  808.     w('%d objects' % num_objs)
  809.     N = 600
  810.     notallowed = (basestring,)
  811.     import __builtin__
  812.     blacklist = set()
  813.     oldlen = 0
  814.     modlen = len(sys.modules)
  815.     while modlen != oldlen:
  816.         blacklist |= set((lambda .0: for m in .0:
  817. if m:
  818. id(m.__dict__)continue)(sys.modules.itervalues()))
  819.         for m in sys.modules.values():
  820.             if m and hasattr(m, '__docfilter__'):
  821.                 blacklist.add(id(m.__docfilter__._globals))
  822.                 continue
  823.             []
  824.         
  825.         oldlen = modlen
  826.         modlen = len(sys.modules)
  827.         continue
  828.         []
  829.     blacklist.add(id(__builtin__))
  830.     blacklist.add(id(__builtin__.__dict__))
  831.     blacklist.add(id(sys.modules))
  832.     blacklist.add(id(locale.locale_alias))
  833.     if sys.modules.get('stringprep', None) is not None:
  834.         import stringprep
  835.         blacklist.add(id(stringprep.b3_exceptions))
  836.     
  837.     blacklist.add(id(objs))
  838.     
  839.     def blacklisted(z):
  840.         if not isinstance(z, notallowed) and id(z) in blacklist:
  841.             pass
  842.         return z is blacklist
  843.  
  844.     
  845.     def blacklisted_1(z):
  846.         z = z[-1]
  847.         return blacklisted(z)
  848.  
  849.     
  850.     def large_sequence(z):
  851.         
  852.         try:
  853.             if len(z) > 300:
  854.                 pass
  855.             return not blacklisted(z)
  856.         except:
  857.             pass
  858.  
  859.  
  860.     
  861.     def saferepr(obj):
  862.         
  863.         try:
  864.             if hasattr(obj, 'gi_frame'):
  865.                 
  866.                 try:
  867.                     return generator_repr(obj)
  868.                 except Exception:
  869.                     e = None
  870.                 except:
  871.                     None<EXCEPTION MATCH>Exception
  872.                 
  873.  
  874.             None<EXCEPTION MATCH>Exception
  875.             return repr(obj)
  876.         except Exception:
  877.             e = None
  878.             
  879.             try:
  880.                 return '<%s>' % type(obj).__name__
  881.             return '<??>'
  882.  
  883.  
  884.  
  885.     num_most_reffed = min(int(num_objs * 0.05), 20)
  886.     most_reffed = ifilterfalse(blacklisted_1, reversed(objs))
  887.     w('\n\n')
  888.     w('*** top %d referenced objects' % num_most_reffed)
  889.     w('sys.getrefcount(obj), id, repr(obj)[:1000]')
  890.     for nil in xrange(num_most_reffed):
  891.         
  892.         try:
  893.             (rcount, obj) = most_reffed.next()
  894.         except StopIteration:
  895.             (((None, None),),)
  896.             (((None, None),),)
  897.             break
  898.         except:
  899.             (((None, None),),)
  900.  
  901.         w('%d %d: %s' % (rcount, id(obj), saferepr(obj)[:1000]))
  902.     
  903.     import util.gcutil as gcutil
  904.     
  905.     def safe_nameof(o):
  906.         
  907.         try:
  908.             return gcutil.nameof(o)[:200]
  909.         except:
  910.             return '[?]'
  911.  
  912.  
  913.     w('\n\n')
  914.     w('*** objects with __len__ more than %d' % N)
  915.     w('__len__(obj), repr(obj)[:1000]')
  916.     large_objs = [](_[2], key = itemgetter0, reverse = True)
  917.     for count, _id, nameof, s in large_objs:
  918.         if _id != id(objs):
  919.             w('count %d id %d: %s %s' % (count, _id, nameof, s))
  920.             continue
  921.         []
  922.     
  923.     w('\n\n')
  924.     _typecounts = typecounts(objs = imap(itemgetter1, objs))
  925.     num_types = 20
  926.     w('*** top %d instantiated types' % num_types)
  927.     builtin_names = set(__builtins__.keys())
  928.     tc_iter = (sorted, ifilterfalse)((lambda _x: builtin_names.__contains__(itemgetter0(_x))), _typecounts)
  929.     for nil in range(num_types):
  930.         
  931.         try:
  932.             (tname, tcount) = tc_iter.next()
  933.         except StopIteration:
  934.             ((((None, None),),),)
  935.             ((((None, None),),),)
  936.             break
  937.         except:
  938.             ((((None, None),),),)
  939.  
  940.         w('%d: %r' % (tcount, tname))
  941.     
  942.     funcinfos = defaultdict(int)
  943.     for refcount, obj in objs:
  944.         if callable(obj):
  945.             
  946.             try:
  947.                 finfo = funcinfo(obj)
  948.             except:
  949.                 ((((None, None),),),)
  950.                 continue
  951.  
  952.             funcinfos[finfo] += refcount
  953.             continue
  954.         ((((None, None),),),)
  955.     
  956.     num_infos = min(len(funcinfos), 20)
  957.     funcinfos = funcinfos.items()
  958.     funcinfos.sort(key = itemgetter1, reverse = True)
  959.     w('\n\n')
  960.     w('*** %d most referenced callables' % num_infos)
  961.     for i in range(num_infos):
  962.         (finfo, frcount) = funcinfos[i]
  963.         w('%d: %r' % (frcount, finfo))
  964.     
  965.     
  966.     try:
  967.         import wx
  968.     except ImportError:
  969.         pass
  970.  
  971.     w('\n\n*** top level windows')
  972.     for tlw in wx.GetTopLevelWindows():
  973.         w(' - '.join((saferepr(tlw), saferepr(tlw.Name))))
  974.     
  975.     w('\n\n*** gc.garbage')
  976.     if not gc.garbage:
  977.         w('(none)')
  978.     else:
  979.         for obj in gc.garbage:
  980.             w(saferepr(obj))
  981.         
  982.     w('\n\n*** high refcounts w/out referrers')
  983.     for refcount, obj in find_high_refcounts():
  984.         w('%d: %s' % (refcount, repr(obj)[:100]))
  985.     
  986.  
  987. HIGH_REFCOUNT = 500
  988.  
  989. def _high_refcounts(getrefcount = sys.getrefcount):
  990.     for obj in gc.get_objects():
  991.         refcount = getrefcount(obj)
  992.         if refcount > HIGH_REFCOUNT:
  993.             yield (refcount, obj)
  994.             continue
  995.     
  996.  
  997.  
  998. def find_high_refcounts(limit = 10, key = operator.itemgetter(0), getrefcount = sys.getrefcount, get_referrers = gc.get_referrers, get_objects = gc.get_objects):
  999.     blacklist = set([
  1000.         id(tuple())])
  1001.     l = []
  1002.     for refcount, obj in _high_refcounts():
  1003.         if id(obj) not in blacklist:
  1004.             delta = refcount - len(get_referrers(obj))
  1005.             if delta:
  1006.                 l.append((delta, obj))
  1007.                 l.sort(reverse = True, key = key)
  1008.                 del l[limit:]
  1009.             
  1010.         delta
  1011.     
  1012.     return l
  1013.  
  1014. import cProfile
  1015. import _lsprof
  1016.  
  1017. class EnableDisableProfiler(cProfile.Profile):
  1018.     
  1019.     def __init__(self, *a, **k):
  1020.         self.enabled = False
  1021.         _lsprof.Profiler.__init__(self, *a, **k)
  1022.  
  1023.     
  1024.     def enable(self):
  1025.         self.enabled = True
  1026.         return _lsprof.Profiler.enable(self)
  1027.  
  1028.     
  1029.     def disable(self):
  1030.         self.enabled = False
  1031.         return _lsprof.Profiler.disable(self)
  1032.  
  1033.     
  1034.     def print_stats(self, sort = -1):
  1035.         import pstats
  1036.         pstats.Stats(self, stream = sys.stderr).strip_dirs().sort_stats(sort).print_stats()
  1037.  
  1038.  
  1039. if __name__ == '__main__':
  1040.     from pprint import pprint
  1041.     pprint(typecounts('Graphics'))
  1042.  
  1043.