Ticket #21247: runtest-2.py

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

Test with modified code and which passes.

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