From 51978e18ff2fe4f27248f598a9f4827cabefc42e Mon Sep 17 00:00:00 2001 From: Patrick Date: Mon, 11 Jul 2022 11:50:41 +0900 Subject: [PATCH] Implement basic functionality --- README.md | 15 +++++++++++- magicli.py | 56 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 13 ++++++++++ tests/test_magicli.py | 34 ++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 magicli.py create mode 100644 setup.py create mode 100644 tests/test_magicli.py diff --git a/README.md b/README.md index 3ce3297..d754225 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,16 @@ # magicli -Automatically call functions from args parsed by `docopt` \ No newline at end of file +Automatically call functions from args parsed by `docopt`. + +## Install + +`pip install git+https://git.beelm.eu/patrick/magicli` + +## Getting started + +```python +from docopt import docopt +from magicli import magicli + +args = magically(docopt(__doc__)) +``` diff --git a/magicli.py b/magicli.py new file mode 100644 index 0000000..6c658ff --- /dev/null +++ b/magicli.py @@ -0,0 +1,56 @@ +""" +# Getting started + +```python +from docopt import docopt +from magicli import magicli + +args = magically(docopt(__doc__)) +``` +""" + +import inspect +from docopt import docopt + + +def magicli(args, glbls=None): + """ + Calls all callable functions with all arguments. + """ + # Get the `globals()` dict of the file from where the function is called. + if not glbls: + glbls = inspect.currentframe().f_back.f_globals + + cleaned_args = clean_args(args) + args = args_set_in_cli(cleaned_args) + for arg in args: + if arg in glbls: + func = glbls.get(arg) + func_args = inspect.getargspec(func).args + kwargs = {arg:args[arg] for arg in args if arg in func_args} + func(**kwargs) + + return cleaned_args + + +def clean_args(args): + """ + Creates a new dict of variables converted to correct function names. + """ + return {parse_function_name(key): args[key] for key in args} + + +def parse_function_name(func): + """ + Convert variables to valid python function names. + """ + for char in ['<', '>', '-']: + func = func.strip(char) + return func.replace('-', '_') + + +def args_set_in_cli(args): + """ + Returns a list of all dictionary entries that are specified in cli. + """ + return {arg:args[arg] for arg in args if args[arg]} diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..3ec45d0 --- /dev/null +++ b/setup.py @@ -0,0 +1,13 @@ +from setuptools import setup + + +setup( + name='magicli', + version='0.1.0', + extras_require = { + 'tests': [ + 'pytest', + 'docopt', + ] + } +) diff --git a/tests/test_magicli.py b/tests/test_magicli.py new file mode 100644 index 0000000..9c4d414 --- /dev/null +++ b/tests/test_magicli.py @@ -0,0 +1,34 @@ +from magicli import clean_args +from magicli import parse_function_name +from magicli import args_set_in_cli + + +def test_clean_args(): + args = { + "": True, + "--name-2": False + } + assert clean_args(args) == { + "name_1": True, + "name_2": False + } + + +def test_parse_function_name(): + assert parse_function_name('') == 'name_1' + assert parse_function_name('--name-2') == 'name_2' + + +def test_args_set_in_cli(): + args = { + "a": True, + "b": False, + "c": None, + "d": 1, + "e": "a" + } + assert args_set_in_cli(args) == { + "a": True, + "d": 1, + "e": "a" + }