This is the result of how default values are handled with '?' (and '*') nargs.
At the start of nested `take_action` function (which handles all actions) is this code:
argument_values = self._get_values(action, argument_strings)
# error if this argument is not allowed with other previously
# seen arguments, assuming that actions that use the default
# value don't really count as "present"
if argument_values is not action.default:
seen_non_default_actions.add(action)
for conflict_action in action_conflicts.get(action, []):
if conflict_action in seen_non_default_actions:
msg = _('not allowed with argument %s')
action_name = _get_action_name(conflict_action)
raise ArgumentError(action, msg % action_name)
'get_values' gets the values for this action. A bare '-b' will be given its 'default'.
An optional positional is always 'seen', since an empty list satisfies its 'nargs'. 'get_values' assigns the default instead. This code in take_action allows us to include such positionals in a mutually exclusive group.
This handing of the '?' optional is a byproduct of that code. Normally we provide both a 'default' and a 'const' with such an argument, giving us a 3-way switch (default, const or user-value). If either 'default' or 'const' is provided, your '-b' will behave as expected.
I have a feeling that trying to document this edge case will just make things more confusing.
|