@@ -64,24 +64,34 @@ def __init__(self, channel, methods=None, name=None, context=None,
64
64
65
65
@staticmethod
66
66
def _zerorpc_filter_methods (cls , self , methods ):
67
- if hasattr (methods , '__getitem__' ):
67
+ getattr_ = getattr (methods , '__getattr__' , None )
68
+ if getattr_ is None and hasattr (methods , '__getitem__' ):
68
69
return methods
69
70
server_methods = set (getattr (self , k ) for k in dir (cls ) if not
70
71
k .startswith ('_' ))
71
- return dict ((k , getattr (methods , k ))
72
+ r = dict ((k , getattr (methods , k ))
72
73
for k in dir (methods )
73
74
if callable (getattr (methods , k ))
74
75
and not k .startswith ('_' )
75
76
and getattr (methods , k ) not in server_methods
76
77
)
78
+ if getattr_ is not None :
79
+ def functor (method , * args , ** kargs ):
80
+ '''Dynamically resolve methods
81
+
82
+ Some methods are dynamically resolved and so can't be infererd.
83
+ '''
84
+ return getattr_ (method )(* args , ** kargs )
85
+ r ['*' ] = functor
86
+ return r
77
87
78
88
def close (self ):
79
89
self .stop ()
80
90
self ._multiplexer .close ()
81
91
82
92
def _zerorpc_inspect (self , method = None , long_doc = True ):
83
93
if method :
84
- methods = {method : self ._methods [ method ] }
94
+ methods = {method : self ._get_method ( method ) }
85
95
else :
86
96
methods = dict ((m , f ) for m , f in self ._methods .items ()
87
97
if not m .startswith ('_' ))
@@ -97,15 +107,26 @@ def _inject_builtins(self):
97
107
if not m .startswith ('_' )]
98
108
self ._methods ['_zerorpc_name' ] = lambda : self ._name
99
109
self ._methods ['_zerorpc_ping' ] = lambda : ['pong' , self ._name ]
100
- self ._methods ['_zerorpc_help' ] = lambda m : self ._methods [ m ] .__doc__
110
+ self ._methods ['_zerorpc_help' ] = lambda m : self ._get_method ( m ) .__doc__
101
111
self ._methods ['_zerorpc_args' ] = \
102
- lambda m : self ._methods [ m ] ._zerorpc_args ()
112
+ lambda m : self ._get_method ( m ) ._zerorpc_args ()
103
113
self ._methods ['_zerorpc_inspect' ] = self ._zerorpc_inspect
104
114
105
- def __call__ (self , method , * args ):
106
- if method not in self ._methods :
115
+ def _get_method (self , method ):
116
+ f = self ._methods .get (method , None )
117
+ if f is None :
118
+ wilcard = self ._methods .get ('*' , None )
119
+ if wilcard is not None :
120
+ def f (* args , ** kargs ):
121
+ return wilcard (method , * args , ** kargs )
122
+ if not isinstance (f , DecoratorBase ):
123
+ f = rep (f )
124
+ if f is None :
107
125
raise NameError (method )
108
- return self ._methods [method ](* args )
126
+ return f
127
+
128
+ def __call__ (self , method , * args ):
129
+ return self ._get_method (method )(* args )
109
130
110
131
def _print_traceback (self , protocol_v1 ):
111
132
exc_type , exc_value , exc_traceback = sys .exc_info ()
@@ -132,9 +153,8 @@ def _async_task(self, initial_event):
132
153
event = bufchan .recv ()
133
154
try :
134
155
self ._context .middleware_load_task_context (event .header )
135
- functor = self ._methods .get (event .name , None )
136
- if functor is None :
137
- raise NameError (event .name )
156
+ functor = self ._get_method (event .name )
157
+ print type (functor ), functor
138
158
functor .pattern .process_call (self ._context , bufchan , event , functor )
139
159
except LostRemote :
140
160
self ._print_traceback (protocol_v1 )
0 commit comments