[issue41359] argparse mutually exclusive group does not exclude in some cases

2020-07-21 Thread paul j3


paul j3  added the comment:

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.

--

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41359] argparse mutually exclusive group does not exclude in some cases

2020-07-21 Thread Karthikeyan Singaravelan


Change by Karthikeyan Singaravelan :


--
nosy: +paul.j3, rhettinger

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com



[issue41359] argparse mutually exclusive group does not exclude in some cases

2020-07-21 Thread Krzysiek


New submission from Krzysiek :

The documentation for `ArgumentParser.add_mutually_exclusive_group` states: 
"argparse will make sure that only one of the arguments in the mutually 
exclusive group was present on the command line".

This is not the case in certain circumstances:

```python
import argparse

parser = argparse.ArgumentParser()
group = parser.add_mutually_exclusive_group()
group.add_argument('-a')
group.add_argument('-b', nargs='?')

parser.parse_args('-a a -b'.split())
```

The above code does not produce any error, even though both exclusive arguments 
are present.

My guess is that the check for mutual exclusion is not done during processing 
of each command line argument, but rather afterwards. It seems the check only 
ensures at most one argument from group is not `None`.

The issue exists at least on Python 2.7.13, 3.6, 3.7.5, 3.8, and 3.10.

--
components: Library (Lib)
messages: 374065
nosy: kkarbowiak
priority: normal
severity: normal
status: open
title: argparse mutually exclusive group  does not exclude in some cases
type: behavior
versions: Python 3.10

___
Python tracker 

___
___
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com