This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author paul.j3
Recipients bethard, chris.jerdonek, paul.j3, r.david.murray
Date 2013-04-17.07:11:50
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1366182711.34.0.1809538844.issue16878@psf.upfronthosting.co.za>
In-reply-to
Content
In this example:

    >>> p.add_argument('--foo', nargs='*', default=None)
    >>> p.parse_args([])
    Namespace(foo=None)
    >>> p.parse_args(['--foo'])
    Namespace(foo=[])

'p.parse_args([])' just assigns the default to 'foo' in the Namespace.

"p.parse_args(['--foo'])" invokes 'take_action(<dest='foo'>,[]).  That is, it 'assigns' an empty array to 'foo'.   The same thing would happen if 'foo' was a positional.  

'take_action' then passes these arguments to '_get_values'.  That is where the differences between '?' and '*' arise.

The key pieces of code in '_get_values' when arg_strings==[] are:

        # optional argument produces a default when not present
        if not arg_strings and action.nargs == OPTIONAL:
            ....value = action.default
            # and evaluate 'value' if is a string

        # when nargs='*' on a positional, if there were no command-line
        # args, use the default if it is anything other than None
        elif (not arg_strings and action.nargs == ZERO_OR_MORE ...):
            if action.default is not None:
                value = action.default
            else:
                value = arg_strings # i.e. []

In other words, if nargs='?', the attribute gets its default value.  But for '*', this is true only if the default is not None.

So in:

parse([], nargs='?')                # get the default value: None
parse([], nargs='*')                # default is None, get arg_strings []
parse([], nargs='*', default=None)  # same case
parse([], nargs='*', default=False) # default is not None, get default
parse([], nargs='*', default=0)     # same case

I tried changing the _get_values() so '*' got the default (like '?' does), and got 54 failures when running test_argparse.py.
History
Date User Action Args
2013-04-17 07:11:51paul.j3setrecipients: + paul.j3, bethard, r.david.murray, chris.jerdonek
2013-04-17 07:11:51paul.j3setmessageid: <1366182711.34.0.1809538844.issue16878@psf.upfronthosting.co.za>
2013-04-17 07:11:51paul.j3linkissue16878 messages
2013-04-17 07:11:50paul.j3create