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.

classification
Title: argparse.ArgumentError missing error message in __repr__
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 2.7
process
Status: closed Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: berker.peksag, dfortunov, paul.j3
Priority: normal Keywords: patch

Created on 2015-10-18 19:29 by dfortunov, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
cpython_ArgumentError_repr.patch dfortunov, 2015-10-18 19:29 review
Messages (4)
msg253160 - (view) Author: Daniel Fortunov (dfortunov) * Date: 2015-10-18 19:29
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.
msg253193 - (view) Author: paul j3 (paul.j3) * (Python triager) Date: 2015-10-19 21:17
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?
msg257124 - (view) Author: Daniel Fortunov (dfortunov) * Date: 2015-12-28 18:25
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.
msg341879 - (view) Author: Daniel Fortunov (dfortunov) * Date: 2019-05-08 14:39
As Paul points out, Python 3 gives a more sensible default repr so this becomes a non-issue.

Closing...
History
Date User Action Args
2022-04-11 14:58:22adminsetgithub: 69622
2019-05-08 14:39:52dfortunovsetstatus: open -> closed

stage: patch review -> resolved
messages: + msg341879
versions: + Python 2.7, - Python 3.4, Python 3.5, Python 3.6
2015-12-28 18:25:10dfortunovsetmessages: + msg257124
2015-10-19 21:17:15paul.j3setnosy: + paul.j3
messages: + msg253193
2015-10-18 19:49:24berker.peksagsetnosy: + berker.peksag
stage: patch review
type: behavior

versions: + Python 3.4, Python 3.5, Python 3.6
2015-10-18 19:29:45dfortunovcreate