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

Loading…
Cancel
Save