Skip to content

Instantly share code, notes, and snippets.

@asher-dev
Created March 6, 2018 09:14
Show Gist options
  • Save asher-dev/5e33dd0608c79db3c166422bccea9df1 to your computer and use it in GitHub Desktop.
Save asher-dev/5e33dd0608c79db3c166422bccea9df1 to your computer and use it in GitHub Desktop.
Simple argument parser
#!/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