paul j3 <ajipa...@gmail.com> added the comment:

By defining a custom 'type' function:

    def foo(astr):
        if astr is argparse.SUPPRESS:
            raise KeyError
        return astr

I get the full traceback

   1831         def take_action(action, argument_strings, option_string=None):
   1832             seen_actions.add(action)
-> 1833             argument_values = self._get_values(action, argument_strings)

and in '_get_values' the error is produced when it calls '_get_value' (which 
runs the 'type' function):

        # optional argument produces a default when not present
        if not arg_strings and action.nargs == OPTIONAL:
            if action.option_strings:
                value = action.const
            else:
                value = action.default
            if isinstance(value, str):
 -->            value = self._get_value(action, value)
                self._check_value(action, value)
  
It identifies this as an OPTIONAL action that has received an empty argument 
list, and assigns it the action.default.

ZERO_OR_MORE * also gets the action.default, but without a _get_value() call.  
That default can be SUPPRESSed by the test at the end of take_action.

A couple of fixes come to mind: 

- add a SUPPRESS test at the start of take_action
- add a SUPPRESS test to _get_values block I quote above, maybe bypassing the 
`_get_value` call

There is a unittest case of a suppressed optional positional; it just doesn't 
also test for a failed type.

class TestDefaultSuppress(ParserTestCase):
    """Test actions with suppressed defaults"""

    argument_signatures = [
        Sig('foo', nargs='?', default=argparse.SUPPRESS)

I'm inclined go with the second choice, but the alternatives need to be 
throughly tested.

In the mean time, an 'int' type could be replaced with one that is SUPPRESS 
knowledgeable:

    def bar(astr):
        if astr is argparse.SUPPRESS:
            return astr
        else:
            return int(astr)

Note that this use of action.default is different from the normal default 
handling at the start of parse_known_args (and the end of _parse_known_args).  
It's specifically for positionals that will always be 'seen' (because an empty 
argument strings list satisfies their nargs).

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue36078>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to