You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

getopt.py 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. """Parser for command line options.
  2. This module helps scripts to parse the command line arguments in
  3. sys.argv. It supports the same conventions as the Unix getopt()
  4. function (including the special meanings of arguments of the form `-'
  5. and `--'). Long options similar to those supported by GNU software
  6. may be used as well via an optional third argument. This module
  7. provides a single function and an exception:
  8. getopt() -- Parse command line options
  9. GetoptError -- exception (class) raised with 'opt' attribute, which is the
  10. option involved with the exception.
  11. """
  12. # Long option support added by Lars Wirzenius <liw@iki.fi>.
  13. # Gerrit Holl <gerrit@nl.linux.org> moved the string-based exceptions
  14. # to class-based exceptions.
  15. __all__ = ["GetoptError","error","getopt"]
  16. class GetoptError(Exception):
  17. opt = ''
  18. msg = ''
  19. def __init__(self, msg, opt):
  20. self.msg = msg
  21. self.opt = opt
  22. Exception.__init__(self, msg, opt)
  23. def __str__(self):
  24. return self.msg
  25. error = GetoptError # backward compatibility
  26. def getopt(args, shortopts, longopts = []):
  27. """getopt(args, options[, long_options]) -> opts, args
  28. Parses command line options and parameter list. args is the
  29. argument list to be parsed, without the leading reference to the
  30. running program. Typically, this means "sys.argv[1:]". shortopts
  31. is the string of option letters that the script wants to
  32. recognize, with options that require an argument followed by a
  33. colon (i.e., the same format that Unix getopt() uses). If
  34. specified, longopts is a list of strings with the names of the
  35. long options which should be supported. The leading '--'
  36. characters should not be included in the option name. Options
  37. which require an argument should be followed by an equal sign
  38. ('=').
  39. The return value consists of two elements: the first is a list of
  40. (option, value) pairs; the second is the list of program arguments
  41. left after the option list was stripped (this is a trailing slice
  42. of the first argument). Each option-and-value pair returned has
  43. the option as its first element, prefixed with a hyphen (e.g.,
  44. '-x'), and the option argument as its second element, or an empty
  45. string if the option has no argument. The options occur in the
  46. list in the same order in which they were found, thus allowing
  47. multiple occurrences. Long and short options may be mixed.
  48. """
  49. opts = []
  50. if type(longopts) == type(""):
  51. longopts = [longopts]
  52. else:
  53. longopts = list(longopts)
  54. while args and args[0].startswith('-') and args[0] != '-':
  55. if args[0] == '--':
  56. args = args[1:]
  57. break
  58. if args[0][:2] == '--':
  59. opts, args = do_longs(opts, args[0][2:], longopts, args[1:])
  60. else:
  61. opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:])
  62. return opts, args
  63. def do_longs(opts, opt, longopts, args):
  64. try:
  65. i = opt.index('=')
  66. except ValueError:
  67. optarg = None
  68. else:
  69. opt, optarg = opt[:i], opt[i+1:]
  70. has_arg, opt = long_has_args(opt, longopts)
  71. if has_arg:
  72. if optarg is None:
  73. if not args:
  74. raise GetoptError('option --%s requires argument' % opt, opt)
  75. optarg, args = args[0], args[1:]
  76. elif optarg:
  77. raise GetoptError('option --%s must not have an argument' % opt, opt)
  78. opts.append(('--' + opt, optarg or ''))
  79. return opts, args
  80. # Return:
  81. # has_arg?
  82. # full option name
  83. def long_has_args(opt, longopts):
  84. possibilities = [o for o in longopts if o.startswith(opt)]
  85. if not possibilities:
  86. raise GetoptError('option --%s not recognized' % opt, opt)
  87. # Is there an exact match?
  88. if opt in possibilities:
  89. return 0, opt
  90. elif opt + '=' in possibilities:
  91. return 1, opt
  92. # No exact match, so better be unique.
  93. if len(possibilities) > 1:
  94. # XXX since possibilities contains all valid continuations, might be
  95. # nice to work them into the error msg
  96. raise GetoptError('option --%s not a unique prefix' % opt, opt)
  97. assert len(possibilities) == 1
  98. unique_match = possibilities[0]
  99. has_arg = unique_match.endswith('=')
  100. if has_arg:
  101. unique_match = unique_match[:-1]
  102. return has_arg, unique_match
  103. def do_shorts(opts, optstring, shortopts, args):
  104. while optstring != '':
  105. opt, optstring = optstring[0], optstring[1:]
  106. if short_has_arg(opt, shortopts):
  107. if optstring == '':
  108. if not args:
  109. raise GetoptError('option -%s requires argument' % opt, opt)
  110. optstring, args = args[0], args[1:]
  111. optarg, optstring = optstring, ''
  112. else:
  113. optarg = ''
  114. opts.append(('-' + opt, optarg))
  115. return opts, args
  116. def short_has_arg(opt, shortopts):
  117. for i in range(len(shortopts)):
  118. if opt == shortopts[i] != ':':
  119. return shortopts[i+1:i+2] == ':'
  120. raise GetoptError('option -%s not recognized' % opt, opt)
  121. if __name__ == '__main__':
  122. import sys
  123. print getopt(sys.argv[1:], "a:b", ["alpha=", "beta"])