Skip to content

Instantly share code, notes, and snippets.

@jeremyBanks
Created September 6, 2009 07:54
Show Gist options
  • Save jeremyBanks/181705 to your computer and use it in GitHub Desktop.
Save jeremyBanks/181705 to your computer and use it in GitHub Desktop.
[2010-01] simple python script template

This is a template intended for use as the starting point of simple command-line Python scripts. It wraps the main function, passing on the arguments the script was called with and using the function's return value as the exit code. If an invalid number of arguments are provided, it generates and displays a usage string from the function's argument list and docstring.

Here are some examples that should demonstrate exactly how this works.

def main():
	pass

$ ./hello.py too many arguments
usage: ./hello.py

With an argument:

def main(directory):
	pass

$ ./something.py too many arguments
usage: ./something.py directory

With a default argument:

def main(name, age=None):
	pass

$ ./add_member.py # no arguments
usage: ./add_member.py name [age]

With only default arguments:

def main(subject="all", verbosity=0):
	pass

$ ./help.py # no arguments
usage: ./help.py [subject [verbosity]]

With a docstring and capturing extra arguments:

def main(no, more, contrived=None, *examples):
    """I promise."""
	pass

$ ./example.py yes
usage: ./example.py no more [contrived [examples...]]

I promise.
#!/usr/bin/env python3.1
import sys
def main():
print("Hello world.")
def __main(function, path, user_args):
"""Wraps a main function to display a usage message when necessary."""
co = function.__code__
num_args = co.co_argcount
if function.__defaults__ is not None:
min_args = num_args - len(function.__defaults__)
else:
min_args = num_args
if co.co_flags & 0x04: # function captures extra arguments with *
max_args = None
else:
max_args = num_args
if min_args <= len(user_args) and (max_args is None or
max_args >= len(user_args)):
return(function(*user_args))
if max_args == 0:
sys.stderr.write("Usage: {path}\n".format(path=path))
else:
arg_list = list()
optionals = 0
for index in range(num_args):
if index < min_args:
arg_list.append(co.co_varnames[index])
else:
arg_list.append("[" + co.co_varnames[index])
optionals += 1
if max_args is None:
arg_list.append("[" + co.co_varnames[num_args] + "...")
optionals += 1
sys.stderr.write("Usage: {path} {args}{optional_closes}\n".format
(path=path,
args=" ".join(arg_list),
optional_closes="]" * optionals))
if function.__doc__:
sys.stderr.write("\n")
sys.stderr.write(function.__doc__)
sys.stderr.write("\n")
return(1)
if __name__ == "__main__":
sys.exit(__main(main, sys.argv[0], sys.argv[1:]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment