~divmod-dev/divmod.org/trunk

« back to all changes in this revision

Viewing changes to Epsilon/epsilon/spewer.py

  • Committer: Jean-Paul Calderone
  • Date: 2014-06-29 20:33:04 UTC
  • mfrom: (2749.1.1 remove-epsilon-1325289)
  • Revision ID: exarkun@twistedmatrix.com-20140629203304-gdkmbwl1suei4m97
mergeĀ lp:~exarkun/divmod.org/remove-epsilon-1325289

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
 
2
 
import sys
3
 
import signal
4
 
import threading
5
 
 
6
 
from twisted.application import service
7
 
from twisted.python import reflect, log
8
 
 
9
 
class CannotFindFunction(ValueError):
10
 
    pass
11
 
 
12
 
class Tracer(object):
13
 
    skip = object()
14
 
 
15
 
    installed = False
16
 
 
17
 
    def install(self):
18
 
        self.installed = True
19
 
        sys.settrace(self.trace)
20
 
        threading.settrace(self.trace)
21
 
 
22
 
    def uninstall(self):
23
 
        self.installed = False
24
 
        sys.settrace(None)
25
 
        threading.setttrace(None)
26
 
 
27
 
    def toggle(self):
28
 
        if self.installed:
29
 
            self.uninstall()
30
 
        else:
31
 
            self.install()
32
 
 
33
 
    def trace(self, frame, event, arg):
34
 
        r = getattr(self, 'trace_' + event.upper())(frame, arg)
35
 
        if r is self.skip:
36
 
            return None
37
 
        elif r is None:
38
 
            return self.trace
39
 
        else:
40
 
            return r
41
 
 
42
 
    def trace_CALL(self, frame, arg):
43
 
        pass
44
 
 
45
 
    def trace_LINE(self, frame, arg):
46
 
        pass
47
 
 
48
 
    def trace_RETURN(self, frame, arg):
49
 
        pass
50
 
 
51
 
    def trace_EXCEPTION(self, frame, arg):
52
 
        pass
53
 
 
54
 
 
55
 
def extractArgs(frame):
56
 
    co = frame.f_code
57
 
    dict = frame.f_locals
58
 
    n = co.co_argcount
59
 
    if co.co_flags & 4: n = n+1
60
 
    if co.co_flags & 8: n = n+1
61
 
    result = {}
62
 
    for i in range(n):
63
 
        name = co.co_varnames[i]
64
 
        result[name] = dict.get(name, "*** undefined ***")
65
 
    return result
66
 
 
67
 
 
68
 
def formatArgs(args):
69
 
    return ', '.join(['='.join((k, reflect.safe_repr(v))) for (k, v) in args.iteritems()])
70
 
 
71
 
 
72
 
class Spewer(Tracer):
73
 
    callDepth = 0
74
 
 
75
 
    def trace_CALL(self, frame, arg):
76
 
        self.callDepth += 1
77
 
 
78
 
        frameSelf = frame.f_locals.get('self')
79
 
        if frameSelf is not None:
80
 
            if hasattr(frameSelf, '__class__'):
81
 
                k = reflect.qual(frameSelf.__class__)
82
 
            else:
83
 
                k = reflect.qual(type(frameSelf))
84
 
            k = k + '.'
85
 
        else:
86
 
            k = ''
87
 
 
88
 
        print ("%X %s%s%s(%s)" % (
89
 
            id(threading.currentThread()),
90
 
            self.callDepth * ' ',
91
 
            k,
92
 
            frame.f_code.co_name,
93
 
            formatArgs(extractArgs(frame))))
94
 
 
95
 
    def trace_RETURN(self, frame, arg):
96
 
        if arg is not None:
97
 
            print ("%X %s<= %s" % (
98
 
                id(threading.currentThread()),
99
 
                self.callDepth * ' ',
100
 
                reflect.safe_repr(arg),))
101
 
        self.callDepth = max(0, self.callDepth - 1)
102
 
 
103
 
    def trace_EXCEPTION(self, frame, arg):
104
 
        print ("%X %s^- %s" % (
105
 
            id(threading.currentThread()),
106
 
            self.callDepth * ' ',
107
 
            reflect.safe_repr(arg),))
108
 
        self.callDepth = max(0, self.callDepth - 1)
109
 
 
110
 
 
111
 
class SignalService(service.Service):
112
 
    def __init__(self, sigmap):
113
 
        self.sigmap = sigmap
114
 
 
115
 
    def startService(self):
116
 
        service.Service.startService(self)
117
 
        self.oldsigmap = {}
118
 
        for sig, handler in self.sigmap.items():
119
 
            self.oldsigmap[sig] = signal.signal(sig, handler)
120
 
 
121
 
    def stopService(self):
122
 
        for sig, handler in self.oldsigmap.items():
123
 
            signal.signal(sig, handler)
124
 
        del self.oldsigmap
125
 
        service.Service.stopService(self)