Browse Source

pylightning: Wrap the plugin methods in a class

Sending around unnamed tuples is bound to cause some issues sooner or
later, so we just create a quick class that holds all the information
about a plugin method.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
pylightning-async
Christian Decker 6 years ago
parent
commit
868d24247b
No known key found for this signature in database GPG Key ID: 1416D83DC4F0E86D
  1. 45
      contrib/pylightning/lightning/plugin.py

45
contrib/pylightning/lightning/plugin.py

@ -15,6 +15,20 @@ class MethodType(Enum):
HOOK = 1
class Method(object):
"""Description of methods that are registered with the plugin.
These can be one of the following:
- RPC exposed by RPC passthrough
- HOOK registered to be called synchronously by lightningd
"""
def __init__(self, name, func, mtype=MethodType.RPCMETHOD):
self.name = name
self.func = func
self.mtype = mtype
class Plugin(object):
"""Controls interactions with lightningd, and bundles functionality.
@ -72,7 +86,8 @@ class Plugin(object):
)
# Register the function with the name
self.methods[name] = (func, MethodType.RPCMETHOD)
method = Method(name, func, MethodType.RPCMETHOD)
self.methods[name] = method
def add_subscription(self, topic, func):
"""Add a subscription to our list of subscriptions.
@ -146,7 +161,8 @@ class Plugin(object):
raise ValueError(
"Method {} was already registered".format(name, self.methods[name])
)
self.methods[name] = (func, MethodType.HOOK)
method = Method(name, func, MethodType.HOOK)
self.methods[name] = method
def hook(self, method_name):
"""Decorator to add a plugin hook to the dispatch table.
@ -198,13 +214,13 @@ class Plugin(object):
if name not in self.methods:
raise ValueError("No method {} found.".format(name))
func, _ = self.methods[name]
method = self.methods[name]
try:
result = {
'jsonrpc': '2.0',
'id': request['id'],
'result': self._exec_func(func, request)
'result': self._exec_func(method.func, request)
}
except Exception as e:
result = {
@ -269,7 +285,7 @@ class Plugin(object):
# then unstash this and call it.
if 'init' in self.methods:
self.init = self.methods['init']
self.methods['init'] = (self._init, MethodType.RPCMETHOD)
self.methods['init'] = Method('init', self._init, MethodType.RPCMETHOD)
partial = ""
for l in self.stdin:
@ -284,26 +300,25 @@ class Plugin(object):
def _getmanifest(self):
methods = []
hooks = []
for name, entry in self.methods.items():
func, typ = entry
for method in self.methods.values():
# Skip the builtin ones, they don't get reported
if name in ['getmanifest', 'init']:
if method.name in ['getmanifest', 'init']:
continue
if typ == MethodType.HOOK:
hooks.append(name)
if method.mtype == MethodType.HOOK:
hooks.append(method.name)
continue
doc = inspect.getdoc(func)
doc = inspect.getdoc(method.func)
if not doc:
self.log(
'RPC method \'{}\' does not have a docstring.'.format(name)
'RPC method \'{}\' does not have a docstring.'.format(method.name)
)
doc = "Undocumented RPC method from a plugin."
doc = re.sub('\n+', ' ', doc)
methods.append({
'name': name,
'name': method.name,
'description': doc,
})
@ -325,9 +340,9 @@ class Plugin(object):
# Swap the registered `init` method handler back in and
# re-dispatch
if self.init:
self.methods['init'], _ = self.init
self.methods['init'] = self.init
self.init = None
return self._exec_func(self.methods['init'], request)
return self._exec_func(self.methods['init'].func, request)
return None

Loading…
Cancel
Save