Verified Commit e37e43a1 authored by Gigadoc 2's avatar Gigadoc 2

make simple_cmd with args instead of data

parent 515dc9ce
......@@ -7,7 +7,7 @@ from functools import wraps
import paho.mqtt.client as mqtt
from .command import Command
from .helpers import *
from . import helpers
class Eins:
def __init__(self,
......@@ -151,15 +151,24 @@ class Eins:
def wrapper(client, userdata, message):
try:
data = json.loads(message.payload.decode("utf-8"))
given_args = list(data.keys())
given_args.append("mqtt_topic")
#XXX: split args string, check amount of required args, check
# for too much args, go
if function_args_complete(callback, given_args):
reduce_args(callback)(mqtt_topic=message.topic, **data)
else:
try:
args = data['args'].split()
except KeyError:
args = list()
try:
helpers.simple_cmd_match_args(callback, args)
if len(args) == 0:
callback()
else:
callback(*args)
except helpers.TooManyArguments:
print("Too many arguments!") #XXX: Reply with error
except helpers.NotEnoughArguments:
print("Missing an argument!") #XXX: Reply with error
except helpers.UnsupportedSignature:
print(("simple_cmds cannot have **kwargs,",
"or arguments after *args!")) #XXX: Reply with error
except json.JSONDecodeError as e:
print("Could not decode JSON: {}".format(e)) #XXX: Reply w error
......
......@@ -3,51 +3,40 @@
import inspect
from functools import wraps
def function_has_kwargs(function):
"""Tests if the given function takes "**kwargs"."""
class TooManyArguments(Exception):
"""Exception for simple_cmd helper when there are too many arguments."""
pass
sig = inspect.signature(function)
class NotEnoughArguments(Exception):
"""Exception for simple_cmd helper when there are not enough arguments."""
pass
for key in sig.parameters:
if sig.parameters[key].kind == inspect.Parameter.VAR_KEYWORD:
return True
class UnsupportedSignature(Exception):
"""Exception for simple_cmd helper when someone tries **kwargs."""
pass
return False
def simple_cmd_match_args(function, args):
"""Tests if there are enough arguments in args for the given function."""
def function_args_complete(function, args):
"""Tests if the functions arguments are satisfied with the given arguments.
"""
required_arg_count = 0
sig = inspect.signature(function)
for key in sig.parameters:
if sig.parameters[key].kind not in [inspect.Parameter.VAR_POSITIONAL,
inspect.Parameter.VAR_KEYWORD]:
if sig.parameters[key].name not in args:
if sig.parameters[key].default == inspect.Parameter.empty:
return False
return True
def reduce_args(function):
"""Wrapper for throwing away superflous arguments.
The wrapper calls the wrapped function with only those arguments which are
valid keywords for it's signature. All other parameters get thrown away.
"""
@wraps(function)
def wrapper(**old_kwargs):
sig = inspect.signature(function)
new_kwargs = {}
for key in sig.parameters:
if sig.parameters[key].kind == inspect.Parameter.VAR_KEYWORD:
# If the function takes **kwargs stop eary, as we can pass
# through any argument we want.
function(**old_kwargs)
return
new_kwargs[key] = old_kwargs[key]
function(**new_kwargs)
return wrapper
if sig.parameters[key].kind in [inspect.Parameter.VAR_KEYWORD,
inspect.Parameter.KEYWORD_ONLY]:
raise UnsupportedSignature
if sig.parameters[key].kind == inspect.Parameter.VAR_POSITIONAL:
# If the function takes *args we can exit immediately as we can
# pass anything at all.
return
if sig.parameters[key].default == inspect.Parameter.empty:
required_arg_count += 1
if len(args) == required_arg_count:
return
if len(args) < required_arg_count:
raise NotEnoughArguments
if len(args) > required_arg_count:
raise TooManyArguments
......@@ -31,8 +31,8 @@ def topic_arg(mqtt_topic):
print(mqtt_topic)
@eins.simple_cmd()
def kwargs(**kwargs):
print(kwargs)
def args(*args):
print(args)
@eins.simple_cmd()
def ètoile():
......@@ -43,8 +43,7 @@ def brøther():
print("LÂMP")
@eins.simple_cmd()
def reflector(**kwargs):
del kwargs['mqtt_topic']
eins.emit_cmd("reflector-target", **kwargs)
def reflector(*args):
eins.emit_cmd("reflector-target", args=args)
eins.run()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment