Search code examples
pythoncommand-line-argumentsgetopt

Are there other ways of validating command line args in python3?


Are there other more efficient ways of validating command line args without external modules and argparse?

import sys
import getopt

argv = sys.argv[1:]
try:
    opts, args = getopt.getopt(argv, "h", ["help", "version", "number="])
except getopt.GetoptError as error:
    print(error)
    exit(1)
if args:
    exit(1)
print(opts)
print(args)

So here's how i would do it, but is it ok? I'm new to python and trying to use as many python features as i can


Solution

  • You should check out Python's built-in argparse. It takes a lot of the hassle out of manually parsing a complex commands from the command line. You can force certain arguments to be a certain type or value.

    Example usage:

    import sys
    import argparse
    
    PHASES = ['clean', 'package', 'install', 'test', 'deploy']
    ALT_PHASES = ['docs', 'demos', 'update']
    
    parser = argparse.ArgumentParser()
    parser.add_argument(
        'phase',
        help="the target phase",
        choices=PHASES + ALT_PHASES
    )
    parser.add_argument(
        '--skip-demos',
        help="skip packaging and deployment of demos",
        action='store_const',
        const=str
    )
    parser.add_argument(
        '--skip-docs',
        help="skip generation and deployment of user's guide",
        action='store_const',
        const=str
    )
    parser.add_argument(
        '--skip-tests',
        help="skip tests",
        action='store_const',
        const=str
    )
    parser.add_argument(
        '--skip-wheels',
        help="skip wheel generation",
        action="store_const",
        const=str
    )
    parser.add_argument(
        '--update',
        help="update the source code in the virtual environment; do not make the wheels",
        action="store_const",
        const=str
    )
    
    def main(args):
        parsed_args = parser.parse_args(args)
        print(parsed_args.phase) # prints the phase
    
    
    if __name__ == "__main__":
        main(sys.argv[1:])
    

    Example output when entering an invalid argument:

    $ python3 build.py hello
    usage: build.py [-h] [--skip-demos] [--skip-docs] [--skip-tests]
                    [--skip-wheels] [--docs-branch DOCS_BRANCH]
                    [--skip-formatting] [--int-tests] [--update]
                    {clean,package,install,test,deploy,docs,demos,update}
    build.py: error: argument phase: invalid choice: 'hello' (choose from 'clean', 'package', 'install', 'test', 'deploy', 'docs', 'demos', 'update')