summaryrefslogtreecommitdiff
path: root/doc/source/parse_args.rst
blob: 4e460be03f6925a166687e2ddf30519783ebcf3d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
The parse_args() method
=========================

.. method:: parse_args([args], [namespace])

   Convert the strings to objects and assign them as attributes of the namespace. Return the populated namespace.
   
   Previous calls to :meth:`add_argument` determine exactly what objects are created and how they are assigned. See the documentation for :meth:`add_argument` for details.
   
   By default, the arg strings are taken from ``sys.argv``, and a new empty ``Namespace`` object is created for the attributes.

Option value syntax
-------------------

The :meth:`parse_args` method supports several ways of specifying the value of an option (if it takes one). In the simplest case, the option and its value are passed as two separate arguments::

  >>> parser = argparse.ArgumentParser(prog='PROG')
  >>> parser.add_argument('-x')
  >>> parser.add_argument('--foo')
  >>> parser.parse_args('-x X'.split())
  Namespace(foo=None, x='X')
  >>> parser.parse_args('--foo FOO'.split())
  Namespace(foo='FOO', x=None)

For long options (options with names longer than a single character), you may also pass the option and value as a single command line argument, using ``=`` to separate them::

  >>> parser.parse_args('--foo=FOO'.split())
  Namespace(foo='FOO', x=None)

For short options (options only one character long), you may simply concatenate the option and its value::

  >>> parser.parse_args('-xX'.split())
  Namespace(foo=None, x='X')

You can also combine several short options together, using only a single ``-`` prefix, as long as only the last option (or none of them) requires a value::

  >>> parser = argparse.ArgumentParser(prog='PROG')
  >>> parser.add_argument('-x', action='store_true')
  >>> parser.add_argument('-y', action='store_true')
  >>> parser.add_argument('-z')
  >>> parser.parse_args('-xyzZ'.split())
  Namespace(x=True, y=True, z='Z')


Invalid arguments
-----------------

While parsing the command-line, ``parse_args`` checks for a variety of errors, including ambiguous options, invalid types, invalid options, wrong number of positional arguments, etc. When it encounters such an error, it exits and prints the error along with a usage message::

  >>> parser = argparse.ArgumentParser(prog='PROG')
  >>> parser.add_argument('--foo', type=int)
  >>> parser.add_argument('bar', nargs='?')
  
  >>> # invalid type
  >>> parser.parse_args(['--foo', 'spam'])
  usage: PROG [-h] [--foo FOO] [bar]
  PROG: error: argument --foo: invalid int value: 'spam'
  
  >>> # invalid option
  >>> parser.parse_args(['--bar'])
  usage: PROG [-h] [--foo FOO] [bar]
  PROG: error: no such option: --bar
  
  >>> # wrong number of arguments
  >>> parser.parse_args(['spam', 'badger'])
  usage: PROG [-h] [--foo FOO] [bar]
  PROG: error: extra arguments found: badger


Arguments containing ``"-"``
----------------------------

The ``parse_args`` method attempts to give errors whenever the user has clearly made a mistake, but some situations are inherently ambiguous. For example, the command-line arg ``'-1'`` could either be an attempt to specify an option or an attempt to provide a positional argument. The ``parse_args`` method is cautious here: positional arguments may only begin with ``'-'`` if they look like negative numbers and there are no options in the parser that look like negative numbers::

  >>> parser = argparse.ArgumentParser(prog='PROG')
  >>> parser.add_argument('-x')
  >>> parser.add_argument('foo', nargs='?')
  
  >>> # no negative number options, so -1 is a positional argument
  >>> parser.parse_args(['-x', '-1'])
  Namespace(foo=None, x='-1')
  
  >>> # no negative number options, so -1 and -5 are positional arguments
  >>> parser.parse_args(['-x', '-1', '-5'])
  Namespace(foo='-5', x='-1')
  
  >>> parser = argparse.ArgumentParser(prog='PROG')
  >>> parser.add_argument('-1', dest='one')
  >>> parser.add_argument('foo', nargs='?')
  
  >>> # negative number options present, so -1 is an option
  >>> parser.parse_args(['-1', 'X'])
  Namespace(foo=None, one='X')
  
  >>> # negative number options present, so -2 is an option
  >>> parser.parse_args(['-2'])
  usage: PROG [-h] [-1 ONE] [foo]
  PROG: error: no such option: -2
  
  >>> # negative number options present, so both -1s are options
  >>> parser.parse_args(['-1', '-1'])
  usage: PROG [-h] [-1 ONE] [foo]
  PROG: error: argument -1: expected one argument

If you have positional arguments that must begin with ``'-'`` and don't look like negative numbers, you can insert the pseudo-argument ``'--'`` which tells ``parse_args`` that everything after that is a positional argument::

  >>> parser.parse_args(['--', '-f'])
  Namespace(foo='-f', one=None)


Argument abbreviations
----------------------

The :meth:`parse_args` method allows you to abbreviate long options if the abbreviation is unambiguous::

  >>> parser = argparse.ArgumentParser(prog='PROG')
  >>> parser.add_argument('-bacon')
  >>> parser.add_argument('-badger')
  >>> parser.parse_args('-bac MMM'.split())
  Namespace(bacon='MMM', badger=None)
  >>> parser.parse_args('-bad WOOD'.split())
  Namespace(bacon=None, badger='WOOD')
  >>> parser.parse_args('-ba BA'.split())
  usage: PROG [-h] [-bacon BACON] [-badger BADGER]
  PROG: error: ambiguous option: -ba could match -badger, -bacon

As you can see above, you will get an error if you pick a prefix that could refer to more than one option.


Beyond ``sys.argv``
-------------------

Sometimes it may be useful to have an ArgumentParser parse args other than those of ``sys.argv``.  This can be accomplished by passing a list of strings to ``parse_args``.  You may have noticed that the examples in the argparse documentation have made heavy use of this calling style - it is much easier to use at the interactive prompt::

  >>> parser = argparse.ArgumentParser()
  >>> parser.add_argument(
  ...     'integers', metavar='int', type=int, choices=xrange(10),
  ...  nargs='+', help='an integer in the range 0..9')
  >>> parser.add_argument(
  ...     '--sum', dest='accumulate', action='store_const', const=sum,
  ...   default=max, help='sum the integers (default: find the max)')
  >>> parser.parse_args(['1', '2', '3', '4'])
  Namespace(accumulate=<built-in function max>, integers=[1, 2, 3, 4])
  >>> parser.parse_args('1 2 3 4 --sum'.split())
  Namespace(accumulate=<built-in function sum>, integers=[1, 2, 3, 4])


Custom namespaces
-----------------

It may also be useful to have an ArgumentParser assign attributes to an already existing object, rather than the newly-created Namespace object that is normally used. This can be achieved by specifying the ``namespace=`` keyword argument::

  >>> class C(object):
  ...     pass
  ...    
  >>> c = C()
  >>> parser = argparse.ArgumentParser()
  >>> parser.add_argument('--foo')
  >>> parser.parse_args(args=['--foo', 'BAR'], namespace=c)
  >>> c.foo
  'BAR'