@@ -63,7 +63,7 @@ def __init__(self, library, host='127.0.0.1', port=8270, port_file=None,
6363 ``Stop Remote Server`` keyword.
6464 """
6565 SimpleXMLRPCServer .__init__ (self , (host , int (port )), logRequests = False )
66- self ._library = RemoteLibrary (library )
66+ self ._library = RemoteLibraryFactory (library )
6767 self ._allow_stop = allow_stop
6868 self ._shutdown = False
6969 self ._register_functions ()
@@ -141,33 +141,48 @@ def get_keyword_documentation(self, name):
141141 return self ._library .get_keyword_documentation (name )
142142
143143
144- class RemoteLibrary (object ):
144+ def RemoteLibraryFactory (library ):
145+ if inspect .ismodule (library ):
146+ return StaticRemoteLibrary (library )
147+ get_keyword_names = dynamic_method (library , 'get_keyword_names' )
148+ if not get_keyword_names :
149+ return StaticRemoteLibrary (library )
150+ run_keyword = dynamic_method (library , 'run_keyword' )
151+ if not run_keyword :
152+ return HybridRemoteLibrary (library , get_keyword_names )
153+ return DynamicRemoteLibrary (library , get_keyword_names , run_keyword )
154+
155+
156+ def dynamic_method (library , underscore_name ):
157+ tokens = underscore_name .split ('_' )
158+ camelcase_name = tokens [0 ] + '' .join (t .title () for t in tokens [1 :])
159+ for name in underscore_name , camelcase_name :
160+ method = getattr (library , name , None )
161+ if method and is_function_or_method (method ):
162+ return method
163+ return None
164+
165+
166+ def is_function_or_method (item ):
167+ return inspect .isfunction (item ) or inspect .ismethod (item )
168+
169+
170+ class StaticRemoteLibrary (object ):
145171
146172 def __init__ (self , library ):
147173 self ._library = library
148174
149175 def get_keyword_names (self ):
150- get_kw_names = (getattr (self ._library , 'get_keyword_names' , None ) or
151- getattr (self ._library , 'getKeywordNames' , None ))
152- if self ._is_function_or_method (get_kw_names ):
153- names = get_kw_names ()
154- else :
155- names = [attr for attr in dir (self ._library ) if attr [0 ] != '_' and
156- self ._is_function_or_method (getattr (self ._library , attr ))]
157- return names
158-
159- def _is_function_or_method (self , item ):
160- return inspect .isfunction (item ) or inspect .ismethod (item )
176+ return [name for name , value in inspect .getmembers (self ._library )
177+ if name [0 ] != '_' and is_function_or_method (value )]
161178
162179 def run_keyword (self , name , args , kwargs = None ):
163180 kw = self ._get_keyword (name )
164181 return KeywordRunner (kw ).run_keyword (args , kwargs )
165182
166183 def _get_keyword (self , name ):
167184 kw = getattr (self ._library , name , None )
168- if not self ._is_function_or_method (kw ):
169- return None
170- return kw
185+ return kw if is_function_or_method (kw ) else None
171186
172187 def get_keyword_arguments (self , name ):
173188 kw = self ._get_keyword (name )
@@ -196,6 +211,45 @@ def get_keyword_documentation(self, name):
196211 return inspect .getdoc (self ._get_keyword (name )) or ''
197212
198213
214+ class HybridRemoteLibrary (StaticRemoteLibrary ):
215+
216+ def __init__ (self , library , get_keyword_names ):
217+ StaticRemoteLibrary .__init__ (self , library )
218+ self .get_keyword_names = get_keyword_names
219+
220+
221+ class DynamicRemoteLibrary (HybridRemoteLibrary ):
222+
223+ def __init__ (self , library , get_keyword_names , run_keyword ):
224+ HybridRemoteLibrary .__init__ (self , library , get_keyword_names )
225+ self ._run_keyword = run_keyword
226+ self ._supports_kwargs = self ._get_kwargs_support (run_keyword )
227+ self ._get_keyword_arguments \
228+ = dynamic_method (library , 'get_keyword_arguments' )
229+ self ._get_keyword_documentation \
230+ = dynamic_method (library , 'get_keyword_documentation' )
231+
232+ def _get_kwargs_support (self , run_keyword ):
233+ spec = inspect .getargspec (run_keyword )
234+ return len (spec .args ) > 3 # self, name, args, kwargs=None
235+
236+ def run_keyword (self , name , args , kwargs = None ):
237+ args = [name , args , kwargs ]
238+ return KeywordRunner (self ._run_keyword ).run_keyword (args )
239+
240+ def get_keyword_arguments (self , name ):
241+ if self ._get_keyword_arguments :
242+ return self ._get_keyword_arguments (name )
243+ if self ._supports_kwargs :
244+ return ['*varargs' , '**kwargs' ]
245+ return ['*varargs' ]
246+
247+ def get_keyword_documentation (self , name ):
248+ if self ._get_keyword_documentation :
249+ return self ._get_keyword_documentation (name )
250+ return ''
251+
252+
199253class KeywordRunner (object ):
200254
201255 def __init__ (self , keyword ):
0 commit comments