From 341b3141048a72b59593d17713bf492d5e115ac2 Mon Sep 17 00:00:00 2001 From: jesopo Date: Sat, 25 Jan 2020 13:58:13 +0000 Subject: change command specs to be compiled at runtime by a decorator --- src/utils/__init__.py | 2 +- src/utils/decorators.py | 15 ++++++++++++--- src/utils/parse.py | 27 +++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 4 deletions(-) (limited to 'src/utils') diff --git a/src/utils/__init__.py b/src/utils/__init__.py index aad6f7a8..303c70c5 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -2,7 +2,7 @@ import contextlib, enum, ipaddress, multiprocessing, queue, signal, threading import typing from . import cli, consts, datetime, decorators, irc, http, parse, security -from .decorators import export, hook, kwarg +from .decorators import export, hook, kwarg, spec from .settings import (BoolSetting, FunctionSetting, IntRangeSetting, IntSetting, OptionsSetting, sensitive_format, SensitiveSetting, Setting) from .errors import (EventError, EventNotEnoughArgsError, EventResultsError, diff --git a/src/utils/decorators.py b/src/utils/decorators.py index dc4adf3a..ca47ea6e 100644 --- a/src/utils/decorators.py +++ b/src/utils/decorators.py @@ -1,4 +1,5 @@ import typing +from .parse import argument_spec BITBOT_MAGIC = "__bitbot" @@ -42,10 +43,18 @@ def export(setting: str, value: typing.Any): magic.add_export(setting, value) return module return _export_func + +def _kwarg(key: str, value: typing.Any, func: typing.Any): + magic = get_magic(func) + magic.add_kwarg(key, value) + return func + def kwarg(key: str, value: typing.Any): def _kwarg_func(func): - magic = get_magic(func) - magic.add_kwarg(key, value) - return func + return _kwarg(key, value, func) return _kwarg_func +def spec(spec: str): + def _spec_func(func): + return _kwarg("spec", argument_spec(spec), func) + return _spec_func diff --git a/src/utils/parse.py b/src/utils/parse.py index b45ca6fe..258b97dc 100644 --- a/src/utils/parse.py +++ b/src/utils/parse.py @@ -155,3 +155,30 @@ def format_token_replace(s: str, vars: typing.Dict[str, str], for i, token in tokens: s = s[:i] + vars[token.replace(sigil, "", 1)] + s[i+len(token):] return s + +class ArgumentSpecType(object): + def __init__(self, name: str, exported: str): + self.name = name + self.exported = exported + +class ArgumentSpec(object): + def __init__(self, optional: bool, types: typing.List[ArgumentSpecType]): + self.optional = optional + self.types = types + +def argument_spec(spec: str) -> typing.List[ArgumentSpec]: + out: typing.List[ArgumentSpec] = [] + for type_names_str in spec.split(" "): + optional = type_names_str[0] == "?" + type_names_str = type_names_str[1:] + + spec_types: typing.List[ArgumentSpecType] = [] + for type_name in type_names_str.split("|"): + exported_name = "" + if "~" in type_name: + exported_name = type_name + type_name = type_name.replace("~", "", 1) + + spec_types.append(ArgumentSpecType(type_name, exported_name)) + out.append(ArgumentSpec(optional, spec_types)) + return out -- cgit v1.3.1-10-gc9f91