root/gaphor/tags/gaphor-0.12.0/gaphor/misc/aspects.py

Revision 457, 3.6 kB (checked in by arjanmol, 4 years ago)

*** empty log message ***

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 # vim:sw=4:et
2
3 class Aspect(object):
4     """Aspect defines the aspect interface that should be implemented by
5     aspects.
6     """
7
8     def __init__(self, method):
9         """This method takes the optional arguments given to the
10         weave_method() function.
11         """
12         pass
13
14     def before(self):
15         """Code executed before the weaved method is executed.
16         """
17         pass
18
19     def after(self, retval, exc):
20         """Code executed after the weaved method has been executed.
21         """
22         pass
23
24 def weave_method(method, advice_class, *advice_args, **advice_kwargs):
25     advice = advice_class(method, *advice_args, **advice_kwargs)
26     advice_before = advice.before
27     advice_after = advice.after
28
29     def invoke_advice(*args, **kwargs):
30         advice_before()
31         try:
32             retval = method(*args, **kwargs)
33         except Exception, e:
34             advice_after(None, e)
35             raise
36         else:
37             advice_after(retval, None)
38             return retval
39
40     # Replace the method with our weaved one.
41     try:
42         class_ = method.im_class
43     except:
44         # The method is actually a simple function, wrap it in its namespace;
45         method.func_globals[method.func_name] = invoke_advice
46     else:
47         #name = method.__name__
48         setattr(class_, method.__name__, invoke_advice)
49     return invoke_advice
50
51
52 class LoggerAspect(Aspect):
53
54     def __init__(self, method):
55         self.method = method
56
57     def before(self):
58         print 'entering', self.method
59
60     def after(self, retval, exc):
61         print 'leaving', self.method,
62         if exc:
63             print 'with exception %s(%s)' % (exc.__class__, exc)
64         else:
65             print 'with return value', retval
66
67
68 class ReferenceAspect(Aspect):
69     """This reference keeps track of objects created by a method.
70     A weak reference to those objects is created and appended to reflist.
71     """
72
73     def __init__(self, method, reflist):
74         self.method = method
75         self.reflist = reflist
76
77     def after(self, retval, exc):
78         import weakref
79         if retval:
80             self.reflist.append(weakref.ref(retval))
81
82
83 class TimerAspect(Aspect):
84     """This aspect tracks the execution time of a function/method, a bit like
85     a profiler.
86     The time spend in a function/method is printed to stdout.
87     """
88
89     def __init__(self, method):
90         import time
91         self.timer = time.time
92         self.method = method
93         self.total_time_spend = 0.0
94
95     def before(self):
96         self.current_time = self.timer()
97
98     def after(self, retval, exc):
99         elapsed = self.timer() - self.current_time
100         self.total_time_spend += elapsed
101         print 'Time spend in %s: %f (total: %f)' % (self.method.__name__, elapsed, self.total_time_spend)
102
103
104 if __name__ == '__main__':
105
106     def test_func(arg1, arg2):
107         print 'test_func(): arg1:', arg1, ', arg2:', arg2
108
109     weave_method(test_func, LoggerAspect)
110     print 'testing test_func()'
111     test_func('a', 'b')
112
113     class TestClass(object):
114
115         def test_meth(self, arg1, arg2):
116             print 'TestClass.test_meth(): arg1:', arg1, ', arg2:', arg2
117
118         def test_exc(self):
119             raise ValueError, 'HELP'
120
121     #print dir(TestClass.test_meth)
122     #print TestClass.test_meth.im_class
123     #print TestClass.test_meth.im_func
124     #print TestClass.test_meth.im_self
125     weave_method(TestClass.test_meth, LoggerAspect)
126     weave_method(TestClass.test_exc, LoggerAspect)
127
128     tc = TestClass()
129     tc.test_meth(1, 2)
130     try:
131         tc.test_exc()
132     except ValueError, e:
133         print 'Caught expected exception', e
134         import traceback
135         traceback.print_exc()
136     else:
137         raise 'HUH'
Note: See TracBrowser for help on using the browser.