""" issue 11588 proposed test case: output_group = parser.add_mutually_exclusive_group(required=True) output_group.add_argument("-o", "--outfile") outdir_group = output_group.add_necessarily_inclusive_group() outdir_group.add_argument("-O", "--outdir") outfile_group = outdir_group.add_mutually_exclusive_group(required=True) outfile_group.add_argument("-p", "--outpattern") outfile_group.add_argument("-s", "--outsuffix") The usage should then look like: (-o FILE | (-O DIR & (-p PATTERN | -s SUFFIX)) """ """ Implementation using parser.register('cross_tests',...) and hand crafted test functions """ import argparse usage = '(-o FILE | (-O DIR & (-p PATTERN | -s SUFFIX))' parser = argparse.ArgumentParser(usage=usage) a_file= parser.add_argument("-o", "--outfile", metavar='FILE') a_dir = parser.add_argument("-O", "--outdir", metavar='DIR') a_pat = parser.add_argument("-p", "--outpattern", metavar='PATTERN') a_suf = parser.add_argument("-s", "--outsuffix", metavar='SUFFIX') # hand crafted tests def pat_or_suf(parser, seen_actions, *args): if 2==len(seen_actions.intersection([a_pat, a_suf])): parser.error('only one of PATTERN and SUFFIX allowed') parser.register('cross_tests', 'pat_or_suf', pat_or_suf) def dir_inclusive(parser, seen_actions, *args): if a_dir in seen_actions: if 0==len(seen_actions.intersection([a_pat, a_suf])): parser.error('DIR requires PATTERN or SUFFIX') parser.register('cross_tests', 'dir_inclusive', dir_inclusive) def file_or_dir(parser, seen_actions, *args): if a_file in seen_actions: cnt = len(seen_actions.intersection([a_dir, a_pat, a_suf])) if cnt>0: parser.error('FILE cannot have DIR, PATTERN or SUFFIX') elif a_dir not in seen_actions: parser.error('require FILE or DIR') parser.register('cross_tests', 'file_or_dir', file_or_dir) parser.parse_args()