Is there a better way of handling this validation:
#!/usr/bin/env python
""" command.
Usage:
  command start ID
  command finish ID FILE
  command (-h | --help)
  command (-v | --version)
Arguments:
  FILE     input file
  PATH     out directory
Options:
  -h --help     Show this screen.
  -v --version  Show version.
"""
from docopt import docopt
from schema import Schema, Use, SchemaError
if __name__ == '__main__':
    args = docopt(__doc__, version='command alpha')
    # Remove False or None keys from args dict
    for k, v in args.items():
        if (not v):
            args.pop(k)
    if 'start' in args:
        args.pop('start')
        schema = Schema({
            'FILE': Use(open, error='FILE should be readable'),
            'ID': Use(int, error='ID should be an int'),
        })
    elif 'finish' in args:
        args.pop('finish')
        schema = Schema({
            'FILE': Use(open, error='FILE should be readable'),
            'ID': Use(int, error='ID should be an int'),
        })
    try:
        args = schema.validate(args)
    except SchemaError as e:
        exit(e)
    print(args)
                I would do the following:
#!/usr/bin/env python
"""Command.
Usage:
  command start ID
  command finish ID FILE
  command (-h | --help)
  command (-v | --version)
Arguments:
  ID
  FILE     input file
Options:
  -h --help     Show this screen.
  -v --version  Show version.
"""
from docopt import docopt
from schema import Schema, Use, Or, SchemaError
if __name__ == '__main__':
    args = docopt(__doc__, version='command alpha')
    id_schema = Use(int, error='ID should be an int')
    file_schema = Or(None, Use(open, error='FILE should be readable'))
    try:
        args['ID'] = id_schema.validate(args['ID'])
        args['FILE'] = file_schema.validate(args['FILE'])
    except SchemaError as e:
        exit(e)
    print(args)
Although I wish schema could express the same using single schema, not two. I will try to make it possible in future to make schemas like:
schema = Schema({'ID': Use(int, error='ID should be an int'),
                 'FILE': Or(None, Use(open, error='FILE should be readable')),
                 object: object})
by object: object meaning that I care only for 'ID' and 'FILE' and that all other keys/values could be arbitrary objects.
Since version 0.2.0, schema can now handle this case properly:
schema = Schema({'ID': Use(int, error='ID should be an int'),
                 'FILE': Or(None, Use(open, error='FILE should be readable')),
                 object: object})
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With