Created
March 6, 2018 09:14
-
-
Save asher-dev/5e33dd0608c79db3c166422bccea9df1 to your computer and use it in GitHub Desktop.
Simple argument parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# Requires Python 3.7+ or CPython 3.6 for ordered dict | |
# Lightweight type-checking argument parser requiring minimal boilerplate | |
# Just a coding exercise for myself, but if you like it please use it! | |
# Todo: | |
# - Boolean flags and grouping (e.g. "-o -a", "-xAd") | |
# - Required and optional arguments (e.g. "--mode quiet -n 2") | |
import sys | |
from collections import namedtuple | |
def _print_error(message): | |
print("{} : error :".format(sys.argv[0].split("/")[-1]), message) | |
def _print_usage(argument_spec): | |
arg_usage_template = " {}" * len(argument_spec) | |
arguments_string = arg_usage_template.format(*argument_spec.keys()) | |
print("Usage: python {}".format(sys.argv[0].split("/")[-1]) + arguments_string) | |
type_hint_template = "\t{{}}:\t{}\n" * len(argument_spec) | |
print(type_hint_template.format(*(func.__name__ for func in argument_spec.values())).format(*argument_spec.keys())) | |
sys.exit(1) | |
def parse_args(argument_spec): | |
""" | |
Provide an argument specification as a dictionary. The keys are named arguments, in order, with the values as their typ | |
""" | |
if len(sys.argv) > 1 and sys.argv[1] == "--help": | |
_print_usage(argument_spec) | |
if len(sys.argv) != len(argument_spec) + 1: | |
_print_error("{} arguments expected, {} given".format(len(argument_spec), len(sys.argv) - 1)) | |
_print_usage(argument_spec) | |
try: | |
named_args = dict(zip(argument_spec.keys(), sys.argv[1:])) | |
typed_args = (arg_func(named_args[arg]) for arg, arg_func in argument_spec.items()) | |
return namedtuple("Arguments", argument_spec.keys())(*typed_args) | |
except ValueError as e: | |
_print_error(e) | |
_print_usage(argument_spec) | |
if __name__ == "__main__": | |
# usage/test/demo | |
sample_argument_spec = { | |
"something": str, | |
"some_number": int, | |
"another_number": float | |
} | |
args = parse_args(sample_argument_spec) | |
print(args.something) | |
print(args.some_number) | |
print(args.another_number) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment