From f3ce7457b193ac12e59228397aafed331a9a0917 Mon Sep 17 00:00:00 2001 From: Till Maas Date: Feb 04 2020 13:37:06 +0000 Subject: [PATCH 1/2] Add doc string for virtual methods --- diff --git a/koji/__init__.py b/koji/__init__.py index aa4371e..49950ae 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -2175,6 +2175,8 @@ def is_conn_error(e): class VirtualMethod(object): + # cache for api documentation + _apidoc = None # some magic to bind an XML-RPC method to an RPC server. # supports "nested" methods (e.g. examples.getStateName) # supports named arguments (if server does) @@ -2186,6 +2188,31 @@ class VirtualMethod(object): def __call__(self, *args, **opts): return self.__func(self.__name, args, opts) + @property + def __doc__(self): + # try to fetch API docs + if VirtualMethod._apidoc is None: + try: + VirtualMethod._apidoc = dict( + [(f["name"], f) for f in self.__func("_listapi", [], {})] + ) + except: + VirtualMethod._apidoc = {} + + funcdoc = VirtualMethod._apidoc.get(self.__name) + if funcdoc: + # add argument description to docstring since the + # call signature is not updated, yet + argdesc = funcdoc["name"] + funcdoc["argdesc"] + "\n" + doc = funcdoc["doc"] + if doc: + return argdesc + doc + else: + return argdesc + else: + return None + + def grab_session_options(options): """Convert optparse options to a dict that ClientSession can handle; From fa007c3dfc598817a4eeb298ff35189c45735e36 Mon Sep 17 00:00:00 2001 From: Tomas Kopecek Date: Feb 04 2020 14:36:50 +0000 Subject: [PATCH 2/2] move _apidoc cache to session Fixes: https://pagure.io/koji/issue/1533 --- diff --git a/koji/__init__.py b/koji/__init__.py index 49950ae..d088f88 100644 --- a/koji/__init__.py +++ b/koji/__init__.py @@ -2175,31 +2175,35 @@ def is_conn_error(e): class VirtualMethod(object): - # cache for api documentation - _apidoc = None # some magic to bind an XML-RPC method to an RPC server. # supports "nested" methods (e.g. examples.getStateName) # supports named arguments (if server does) - def __init__(self, func, name): + def __init__(self, func, name, session=None): self.__func = func self.__name = name + self.__session = session + def __getattr__(self, name): return type(self)(self.__func, "%s.%s" % (self.__name, name)) + def __call__(self, *args, **opts): return self.__func(self.__name, args, opts) @property def __doc__(self): + if self.__session is None: + # There could be potentially session-less object + return None # try to fetch API docs - if VirtualMethod._apidoc is None: + if self.__session._apidoc is None: try: - VirtualMethod._apidoc = dict( + self.__session._apidoc = dict( [(f["name"], f) for f in self.__func("_listapi", [], {})] ) except: - VirtualMethod._apidoc = {} + self.__session._apidoc = {} - funcdoc = VirtualMethod._apidoc.get(self.__name) + funcdoc = self.__session._apidoc.get(self.__name) if funcdoc: # add argument description to docstring since the # call signature is not updated, yet @@ -2213,7 +2217,6 @@ class VirtualMethod(object): return None - def grab_session_options(options): """Convert optparse options to a dict that ClientSession can handle; If options is already a dict, filter out meaningless and None value items""" @@ -2259,6 +2262,7 @@ class ClientSession(object): opts = {} else: opts = opts.copy() + self._apidoc = None self.baseurl = baseurl self.opts = opts self.authtype = None @@ -2822,7 +2826,9 @@ class ClientSession(object): def __getattr__(self, name): #if name[:1] == '_': # raise AttributeError("no attribute %r" % name) - return VirtualMethod(self._callMethod, name) + if name == '_apidoc': + return self.__dict__['_apidoc'] + return VirtualMethod(self._callMethod, name, self) def fastUpload(self, localfile, path, name=None, callback=None, blocksize=None, overwrite=False, volume=None): if blocksize is None: @@ -3081,7 +3087,7 @@ class MultiCallSession(object): self._calls = [] def __getattr__(self, name): - return VirtualMethod(self._callMethod, name) + return VirtualMethod(self._callMethod, name, self._session) def _callMethod(self, name, args, kwargs=None, retry=True): """Add a new call to the multicall"""