Ticket #21247: runtest-1.py

File runtest-1.py, 3.0 KB (added by Graham Dumpleton, 11 years ago)

Test with original code and which fails.

Line 
1from functools import wraps, update_wrapper, WRAPPER_ASSIGNMENTS
2
3def method_decorator(decorator):
4 """
5 Converts a function decorator into a method decorator
6 """
7 # 'func' is a function at the time it is passed to _dec, but will eventually
8 # be a method of the class it is defined it.
9 def _dec(func):
10 def _wrapper(self, *args, **kwargs):
11 @decorator
12 def bound_func(*args2, **kwargs2):
13 return func(self, *args2, **kwargs2)
14 # bound_func has the signature that 'decorator' expects i.e. no
15 # 'self' argument, but it is a closure over self so it can call
16 # 'func' correctly.
17 return bound_func(*args, **kwargs)
18 # In case 'decorator' adds attributes to the function it decorates, we
19 # want to copy those. We don't have access to bound_func in this scope,
20 # but we can cheat by using it on a dummy function.
21 @decorator
22 def dummy(*args, **kwargs):
23 pass
24 update_wrapper(_wrapper, dummy)
25 # Need to preserve any existing attributes of 'func', including the name.
26 update_wrapper(_wrapper, func)
27
28 return _wrapper
29 update_wrapper(_dec, decorator)
30 # Change the name to aid debugging.
31 _dec.__name__ = 'method_decorator(%s)' % decorator.__name__
32 return _dec
33
34def my_wrapper_1(wrapped):
35 def _wrapper(arg1, arg2):
36 print('_wrapper', arg1, arg2)
37 return wrapped(arg1, arg2)
38 return _wrapper
39
40@my_wrapper_1
41def function(arg1, arg2):
42 print('function', arg1, arg2)
43 return arg1, arg2
44
45function(1, 2)
46
47my_method_wrapper_1 = method_decorator(my_wrapper_1)
48
49class my_bound_wrapper_2(object):
50 def __init__(self, wrapped):
51 self.wrapped = wrapped
52 self.__name__ = wrapped.__name__
53 def __call__(self, arg1, arg2):
54 print('my_bound_wrapper_2.__call__', arg1, arg2)
55 return self.wrapped(arg1, arg2)
56 def __get__(self, instance, owner):
57 print('my_bound_wrapper_2.__get__', instance, owner)
58 return self
59
60class my_desc_wrapper_2(object):
61 def __init__(self, wrapped):
62 self.wrapped = wrapped
63 self.__name__ = wrapped.__name__
64 def __get__(self, instance, owner):
65 print('my_desc_wrapper_2.__get__', instance, owner)
66 return my_bound_wrapper_2(self.wrapped.__get__(instance, owner))
67
68class Class(object):
69
70 @my_method_wrapper_1
71 def method_1(self, arg1, arg2):
72 print('Class.method_1', self, arg1, arg2)
73 return arg1, arg2
74
75 @my_desc_wrapper_2
76 def method_2(self, arg1, arg2):
77 print('Class.method_2', arg1, arg2)
78 return arg1, arg2
79
80 @my_method_wrapper_1
81 @my_desc_wrapper_2
82 def method_3(self, arg1, arg2):
83 print('Class.method_3', arg1, arg2)
84 return arg1, arg2
85
86 @my_method_wrapper_1
87 @my_method_wrapper_1
88 def method_4(self, arg1, arg2):
89 print('Class.method_4', self, arg1, arg2)
90 return arg1, arg2
91
92c = Class()
93
94c.method_1(1, 2)
95c.method_2(1, 2)
96c.method_3(1, 2)
97c.method_4(1, 2)
Back to Top