44
55"""
66import collections
7+ from functools import wraps
78
89
910class Dispatcher (collections .MutableMapping ):
@@ -27,6 +28,7 @@ def __init__(self, prototype=None):
2728 None
2829
2930 """
31+ self ._decorators = []
3032 self .method_map = dict ()
3133
3234 if prototype is not None :
@@ -36,7 +38,7 @@ def __getitem__(self, key):
3638 return self .method_map [key ]
3739
3840 def __setitem__ (self , key , value ):
39- self .method_map [key ] = value
41+ self .method_map [key ] = self . _wrap_method ( value )
4042
4143 def __delitem__ (self , key ):
4244 del self .method_map [key ]
@@ -50,8 +52,24 @@ def __iter__(self):
5052 def __repr__ (self ):
5153 return repr (self .method_map )
5254
55+ def register_decorator (self , a ):
56+ self ._decorators .extend (a if hasattr (a , '__iter__' ) else [a ])
57+
58+ def _wrap_method (self , f ):
59+ @wraps (f )
60+ def _method (* args , ** kwargs ):
61+ nf = f
62+ for deco in reversed (self ._decorators ):
63+ nf = deco (nf )
64+ return nf (* args , ** kwargs )
65+
66+ return _method
67+
5368 def add_class (self , cls ):
54- prefix = cls .__name__ .lower () + '.'
69+ if hasattr (cls , 'rpc_method_prefix' ):
70+ prefix = cls .rpc_method_prefix + '.'
71+ else :
72+ prefix = cls .__name__ .lower () + '.'
5573 self .build_method_map (cls (), prefix )
5674
5775 def add_object (self , obj ):
@@ -94,7 +112,7 @@ def mymethod(*args, **kwargs):
94112 print(args, kwargs)
95113
96114 """
97- self . method_map [name or f .__name__ ] = f
115+ self [name or f .__name__ ] = f
98116 return f
99117
100118 def build_method_map (self , prototype , prefix = '' ):
@@ -112,10 +130,19 @@ def build_method_map(self, prototype, prefix=''):
112130 Prefix of methods
113131
114132 """
133+ rpc_exports = getattr (prototype , 'rpc_exports' , None )
134+
135+ def _should_export (method ):
136+ if method .startswith ('_' ):
137+ return False
138+ if rpc_exports is None :
139+ return True
140+ return method in rpc_exports
141+
115142 if not isinstance (prototype , dict ):
116143 prototype = dict ((method , getattr (prototype , method ))
117144 for method in dir (prototype )
118- if not method . startswith ( '_' ))
145+ if _should_export ( method ))
119146
120147 for attr , method in prototype .items ():
121148 if callable (method ):
0 commit comments