Issue 25436: argparse.ArgumentError missing error message in repr (original) (raw)

ArgumentError's init() fails to call super(), meaning that the base exception doesn’t get a message, and thus repr() always returns “argparse.ArgumentError()” with no message.

Not very helpful if that repr gets logged, or included in another error message :-(

I've attached a patch that fixes this, and adds corresponding tests.

The short repr is produced in Python2.7, but not 3.5.

Your test case:

action = argparse._StoreAction(['--file], dest='file_path')
error = argparse.ArgumentError(action, 'File not found.')
print(str(error))
print(repr(error))

With Python3.5 this displays:

argument --file: File not found.

ArgumentError(_StoreAction(option_strings=['--file'],
   dest='file_path', nargs=None, const=None, default=None,
   type=None, choices=None, help=None, metavar=None), 
   'File not found.')

In Python2.7 the repr() produces:

ArgumentError()

Your patch changes the repr to:

ArgumentError('File not found.', '--file')

I think you could achieve the same effect by defining a __repr__ method for ArgumentError.

By the way, to produce such an Action, you would normally use:

parser.add_argument('--file')

'--file=/foo/bar' is not a good argument option flag. The code may accept it, but it will confuse your users.


Normally an ArgumentError is raised during parsing, and is caught at the end of parse_known_args with:

    except ArgumentError:
        err = _sys.exc_info()[1]
        self.error(str(err))

So its str() is passed on the the parser.error method (and on to parser.exit). Normally a user, or developer's code will not see this error class.

The purpose of ArgumentError is to clearly identify a class of error, and to add the Action identity to the error message. It's part of the API so custom Action classes can use it to pass errors through the normal parsing error system.

Can you make a better case for needing an improved repr? How would it be logged or otherwise be made visible to users and/or developers?

Paul,

Thanks for your comprehensive reply. I agree with everything you've said and the reason I've taken so long to reply is that I've been racking my brains to remember exactly how I came across this scenario.

I did at some point see an ArgumentError but I've forgotten the exact scenario. Since I can't see any of our internal codebase explicitly raising an ArgumentError, then I can only assume this must have just been a frustration I encountered when debugging into argparse code.

So I'll reformulate the question: Do you think it's worthwhile to make ArgumentError's repr() more useful for the purposes of interactive debugging alone?

Regards, Dani

PS: I agree with your suggestion that you could achieve the same effect by defining a __repr__ method for ArgumentError. I just thought that calling super() was more idiomatic.