diff --git a/README.md b/README.md index 437ad86..7c16bc5 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,5 @@ but for now clone the repo #### TODO [x] flags - [x] options - - [] intergration with typing to allow to use them for typhints, ie `Optinal` + [] intergration with typing to allow to use them for typhints, ie `Optinal` \ No newline at end of file diff --git a/actioneer/action.py b/actioneer/action.py index ce8632e..da4ccfd 100644 --- a/actioneer/action.py +++ b/actioneer/action.py @@ -1,4 +1,4 @@ -from typing import Callable, Any, List, Dict +from typing import Callable, Any, List, Dict, Union from inspect import Parameter, signature from .utils import identity, bool_from_str from .argument import Argument @@ -27,7 +27,8 @@ def __init__(self, func, aliases: List[str] = [], *, overrides = { Parameter.empty: identity, - bool: bool_from_str + bool: bool_from_str, + Union: union_converter } def get_cast(self, param): @@ -47,7 +48,7 @@ def invoke(self, args: List[str] = [], ctx: List[Any] = []): if v.kind == Parameter.KEYWORD_ONLY} ctxs = {name: ctx[value] for name, value in name_annots.items()} - args = + args = self.make_cast(args) self.func(*args, **ctxs) except Exception as e: if self.error_handler: diff --git a/actioneer/typehints.py b/actioneer/typehints.py new file mode 100644 index 0000000..4348706 --- /dev/null +++ b/actioneer/typehints.py @@ -0,0 +1,22 @@ +class BaseTypehint: + def __init__(): + pass + + def __getitem__(self, keys): + self.types = keys + + def convert(self, arg): + for type in self.types: + try: + if type is None: + return None + return type(arg) + except: + pass + + +Union = BaseTypehint() + + +def a(b: Union[str, int]): + pass diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..224a779 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..f22a3ea --- /dev/null +++ b/setup.py @@ -0,0 +1,26 @@ +from distutils.core import setup +setup( + name = 'actioneer', # How you named your package folder (MyLib) + packages = ['actioneer'], # Chose the same as "name" + version = '0.5', # Start with a small number and increase it with every change you make + license='MIT', # Chose a license from here: https://help.github.com/articles/licensing-a-repository + description = 'TYPE YOUR DESCRIPTION HERE', # Give a short description about your library + author = 'YOUR NAME', # Type in your name + author_email = 'your.email@domain.com', # Type in your E-Mail + url = 'https://github.com/user/reponame', # Provide either the link to your github or to your website + download_url = 'https://github.com/user/reponame/archive/v_01.tar.gz', # I explain this later on + keywords = ['SOME', 'MEANINGFULL', 'KEYWORDS'], # Keywords that define your package best + install_requires=[ # I get to this in a second + 'validators', + 'beautifulsoup4', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', # Chose either "3 - Alpha", "4 - Beta" or "5 - Production/Stable" as the current state of your package + 'Intended Audience :: Developers', # Define that your audience are developers + 'Topic :: Software Development :: Build Tools', + 'License :: OSI Approved :: MIT License', # Again, pick a license + 'Programming Language :: Python :: 3', #Specify which pyhton versions that you want to support + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + ], +) \ No newline at end of file diff --git a/showcase.py b/showcase.py new file mode 100644 index 0000000..22a8618 --- /dev/null +++ b/showcase.py @@ -0,0 +1,39 @@ +import actioneer +import typing + + +handler = actioneer.Performer([1, True]) # inits the command handler, +# the argument is preset contexts that will be passed to the command +# you can subclass Perfomer and overwride the "split_args", "get_options" +# and "get_flags" + + +def echo(*msg, message: str, flags: actioneer.Flags, options: actioneer.Options): # kwargs will be treated as contexts that will be passed to the command, this system used the annotations to find what to set as what + print(" ".join(msg)) + print(message) + print(flags) + print(options) + raise Exception("qwertjk") + +# NOTE: all contexts are optional so you might set a context but it doesnt need to be set as a kwarg + + +echo = actioneer.Command(echo, flags=["test"], options={"channel": typing.Optional[int]}, performer=handler) # this will most likly be wrapped in other libs that use this +handler.register(echo) # adds it to the command handler + + +@handler.error +def bruh(e, *, message: str): + print(e) + print(message) + + +echo.invoke([""], ["bruh (the 'message', kwarg", actioneer.Flags({"test": True})]) +handler.run("echo hello world -test --channel 123", ["bruh"]) # there is cmd.invoke but that doesnt handle arguments, flags and options +# ^ (1) ^ (2) ^ (3) ^ (4) ^ (5) +# 1 - command name +# 2 - command args +# 3 - flag +# 4 - option +# 5 - extra command context's that can be set when being invoked, ie channel, +# message ect