Skip to content

Add optional keyword argument exit_on_error to argparse.ArgumentParser #54147

Closed

Description

@jayt
mannequin
BPO 9938
Nosy @rhettinger, @ezio-melotti, @merwok, @bitdancer, @IIIIllllIIIIllllIIIIllllIIIIllllIIIIll, @matrixise, @wm75, @zvyn, @miss-islington, @shihai1991
PRs
  • bpo-9938: Add optional keyword argument exit_on_error to argparse.ArgumentParser #15362
  • Files
  • issue9938.patch
  • issue9938_with_test.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2019-09-12.10:57:30.263>
    created_at = <Date 2010-09-24.14:31:29.200>
    labels = ['easy', 'type-feature', 'library', '3.9']
    title = 'Add optional keyword argument exit_on_error to argparse.ArgumentParser'
    updated_at = <Date 2019-09-12.11:21:54.018>
    user = 'https://bugs.python.org/jayt'

    bugs.python.org fields:

    activity = <Date 2019-09-12.11:21:54.018>
    actor = 'shihai1991'
    assignee = 'docs@python'
    closed = True
    closed_date = <Date 2019-09-12.10:57:30.263>
    closer = 'matrixise'
    components = ['Library (Lib)']
    creation = <Date 2010-09-24.14:31:29.200>
    creator = 'jayt'
    dependencies = []
    files = ['21793', '22172']
    hgrepos = []
    issue_num = 9938
    keywords = ['patch', 'easy']
    message_count = 21.0
    messages = ['117287', '121531', '124116', '124128', '124219', '134549', '136082', '137184', '149545', '191973', '191974', '191975', '191978', '191997', '192147', '294384', '347804', '350092', '352103', '352104', '352118']
    nosy_count = 17.0
    nosy_names = ['rhettinger', 'bethard', 'ezio.melotti', 'eric.araujo', 'r.david.murray', 'docs@python', 'jayt', 'xuanji', 'tanqazx', 'paul.j3', 'a_b', 'matrixise', 'wolma', 'zvyn', 'Sourav Singh', 'miss-islington', 'shihai1991']
    pr_nums = ['15362']
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue9938'
    versions = ['Python 3.9']

    Activity

    1. jayt commented on Sep 24, 2010

      jaytmannequin
      MannequinAuthor

      I want to create a custom interactive shell where I continually do
      parse_args. Like the following:
      parser = argparse.ArgumentParser()
      command = raw_input()
      while(True):
      args = parser.parse_args(shlex.split(command))
      # Do some magic stuff
      command = raw_input()
      The problem is that if I give it invalid input, it errors and exits
      with a help message.

      I learned from argparse-users group that you can override the exit method like the following:

      class MyParser(ArgumentParser): 
        def exit(self, status=0, message=None): 
          # do whatever you want here 

      I would be nice to have this usage documented perhaps along with best practices for doing help messages in this scenario.

    2. added
      docsDocumentation in the Doc dir
      on Sep 24, 2010
    3. merwok commented on Nov 19, 2010

      @merwok
      Member

      Do you want to work on a patch?

      (Aside: you may want to learn about the cmd and shlex modules for read-eval-print-loop programs :)

    4. tanqazx commented on Dec 16, 2010

      tanqazxmannequin
      Mannequin

      I am also trying to use argparse interactively, but in this case by combining it with the cmd module. So I'm doing something like below:

      class MyCmd(cmd.Cmd):
      
          parser = argparse.ArgumentParser(prog='addobject')
          parser.add_argument('attribute1')
          parser.add_argument('attribute2')
          parser.add_argument('attribute3')
      
          def do_addobject(self, line):
              args = MyCmd.parser.parse_args(line.split())
              newobject = object(args.attribute1, args.attribute2, args.attribute3)
              myobjects.append(newobject)

      I'm faced with the same problem that when given invalid input, parse_args exits the program completely, instead of exiting just to the Cmd shell.

      I have the feeling that this use case is sufficiently common such that it would be good if people did not have to override the exit method themselves, and instead an alternative to parse_args was provided that only raises exceptions for the surrounding code to handle rather than exiting the program entirely.

    5. merwok commented on Dec 16, 2010

      @merwok
      Member

      You can always catch SystemExit.

    6. bethard commented on Dec 17, 2010

      bethardmannequin
      Mannequin

      In the short term, just catch the SystemExit.

      In the slightly longer term, we could certainly provide a subclass, say, ErrorRaisingArgumentParser, that overrides .exit and .error to do nothing but raise an exception with the message they would have printed. We'd probably have to introduce a new Exception subclass though, maybe ArgumentParserExit or something like that.

      Anyway if you're interested in this, please file a new ticket (preferably with a patch). Regardless of whether we ever provide the subclass, we certainly need to patch the documentation to tell people how to override error and exit.

    7. IIIIllllIIIIllllIIIIllllIIIIllllIIIIll commented on Apr 27, 2011

      IIIIllllIIIIllllIIIIllllIIIIllllIIIIllmannequin
      Mannequin

      I don't think it's best to create a new subclass to throw an ArgumentParserExit exception; if I read the stack trace I'd see that an ArgumentError was thrown, then caught, then an ArgumentParserExit was thrown, which IMHO is confusing. In the current design, parse_known_errors catches an ArgumentError and then exits. I propose that the user be optionally allowed to turn off the handling of ArgumentError and to handle it himself instead through an exit_on_argument_error flag.

      Attached patch does this. Also I think this issue falls under component 'Lib' too.

    8. ezio-melotti commented on May 16, 2011

      @ezio-melotti
      Member

      FWIW unittest had a similar issue and it's been solved adding an 'exit' argument to unittest.main() 0.

      I think using an attribute here might be fine.
      The patch contains some trailing whitespace that should be removed, also it might be enough to name the attribute "exit_on_error".
      It should also include tests to check that the attribute is set with the correct default value and that it doesn't raise SystemExit when the attribute is False.

    9. IIIIllllIIIIllllIIIIllllIIIIllllIIIIll commented on May 29, 2011

      IIIIllllIIIIllllIIIIllllIIIIllllIIIIllmannequin
      Mannequin

      Updated previous patch with test cases and renamed exit_on_argument_error flag to exit_on_error.

    10. bethard commented on Dec 15, 2011

      bethardmannequin
      Mannequin

      Looks good to me.

    11. ab commented on Jun 28, 2013

      abmannequin
      Mannequin

      What is the status of this? If the patch looks good, then will it be pushed into 3.4?

    12. 3 remaining items

    13. bitdancer commented on Jun 28, 2013

      @bitdancer
      Member

      Yes, I think opening a new issue at this point might be a good idea. The reason is that there are a changes either in place or pending in other issues that involve the parse_know_args code, so a new patch is probably required regardless.

      I wish I had time to review and commit all the argparse patches, but so far I haven't gotten to them. They are on my todo list somewhere, though :)

    14. paulj3 commented on Jul 1, 2013

      paulj3mannequin
      Mannequin

      The exit and error methods are mentioned in the 3.4 documentation, but there are no examples of modifying them.

      16.4.5.9. Exiting methods
      ArgumentParser.exit(status=0, message=None)
      ArgumentParser.error(message)
      

      test_argparse.py has a subclass that redefines these methods, though I think it is more complex than necessary.

          class ErrorRaisingArgumentParser(argparse.ArgumentParser):

      In http://bugs.python.org/file30204/test_intermixed.py , part of http://bugs.python.org/issue14191 , which creates a parser mode that is closer to optparse in style, I simply use:

          def error(self, message):
              usage = self.format_usage()
              raise Exception('%s%s'%(usage, message))
          ArgumentParser.error = error

      to catch errors.

      https://github.com/nodeca/argparse a Javascript port of argparse, adds a 'debug' option to the ArgumentParser, that effectively redefines this error method. They use that extensively in testing.

      Another approach is to trap the sysexit. Ipython does that when argparse is run interactively.

      Even the simple try block works, though the SystemExit 2 has no information about the error.

      try:
          args = parser.parse_args('X'.split())
      except SystemExit as e:
          print(e)
      

      Finally, plac ( https://pypi.python.org/pypi/plac ) is a pypi package that is built on argparse. It has a well developed interactive mode, and integrates threads and multiprocessing.

    15. SouravSingh commented on May 24, 2017

      SouravSinghmannequin
      Mannequin

      I would like to send a patch for the issue. How do I start

    16. zvyn commented on Jul 13, 2019

      zvynmannequin
      Mannequin

      This issue is a duplicate of bpo-9112 which was resolved by commit 9375492

    17. shihai1991 commented on Aug 21, 2019

      @shihai1991
      Member

      It is a good idea. So I update this title and add PR 15362.

      I am not sure there have a problem of xuanli's CLA or not~

    18. added and removed
      docsDocumentation in the Doc dir
      on Aug 21, 2019
    19. changed the title [-]Documentation for argparse interactive use[/-] [+]Improving interactive use of argparse[/+] on Aug 21, 2019
    20. changed the title [-]Improving interactive use of argparse[/-] [+]Add optional kwargs to argparse[/+] on Aug 23, 2019
    21. changed the title [-]Add optional kwargs to argparse[/-] [+]Add optional keyword argument exit_on_error to argparse.ArgumentParser[/+] on Sep 11, 2019
    22. miss-islington commented on Sep 12, 2019

      @miss-islington
      Contributor

      New changeset f545638 by Miss Islington (bot) (Hai Shi) in branch 'master':
      bpo-9938: Add optional keyword argument exit_on_error to argparse.ArgumentParser (GH-15362)
      f545638

    23. matrixise commented on Sep 12, 2019

      @matrixise
      Member

      Thank you for your PR and for your time, I have merged the PR into master.

    24. shihai1991 commented on Sep 12, 2019

      @shihai1991
      Member

      Stéphane, thanks for your good comment. Some argparse's bpo is too old ;)

    25. transferred this issue fromon Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Labels

      3.9 (EOL)end of lifeeasystdlibStandard Library Python modules in the Lib/ directorytype-featureA feature request or enhancement

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions