Unexpected Error using parse_args() function of the Argumentparser object in Python

Asked

Viewed 202 times

4

In a simple code I’m doing in Python, I get the exception below, when I call the function parser_args() on the type object ArgumentParser:

Unexpected error: (<type 'exceptions.SystemExit'>, SystemExit(0,), <traceback object at 0x10c97fdd0>)

At the end I added the full Tracer.

I started writing the code now, based on the template offered by Eclipse Mars.1 plus its Pydev plugin, and there is nothing but the code below:

#!/usr/local/bin/python2.7
# encoding: utf-8
'''
br.com.cdcp.python.client -- Um Cliente TCP para comprovação de conhecimentos em programação Python

br.com.cdcp.python.client faz conexão com um sevidor que receber uma mensagem TCP,
aguarda a confirmação do envio, e armazena o token para uso futuro.

@author:     Carlos Delfino

@copyright:  2015, cdcp. All rights reserved.

@license:    GNU

@contact:    [email protected]
@deffield    updated: Updated
'''

import sys
import os

from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter

__all__ = []
__version__ = 0.1
__date__ = '2015-11-17'
__updated__ = '2015-11-17'

DEBUG = 1
TESTRUN = 0
PROFILE = 0

class CLIError(Exception):
    '''Generic exception to raise and log different fatal errors.'''
    def __init__(self, msg):
        super(CLIError).__init__(type(self))
        self.msg = "E: %s" % msg
    def __str__(self):
        return self.msg
    def __unicode__(self):
        return self.msg


def main(argv=None): # IGNORE:C0111
    '''Opções da Linha de Comando.'''

    if argv is None:
        argv = sys.argv
    else:
        sys.argv.extend(argv)

    program_name = os.path.basename(sys.argv[0])
    program_version = "v%s" % __version__
    program_build_date = str(__updated__)
    program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
    program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
    program_license = '''%s

  Created by Carlos Delfino on %s.
  Copyright 2015 cdcp. All rights reserved.

  GNU - Versão 3.0

  Distributed on an "AS IS" basis without warranties
  or conditions of any kind, either express or implied.

USAGE
''' % (program_shortdesc, str(__date__))

    try:
        # Setup argument parser
        parser = ArgumentParser(
                                description=program_license,
                                formatter_class=RawDescriptionHelpFormatter)
        parser.add_argument('-s', '--server',
                            action="store",
                            required = False)
        parser.add_argument('-p', '--port',
                            action="store",
                            required = False)
        #parser.add_argument('-v', '--version',
        #                    action='version',
        #                    version=program_version_message)

        # Process arguments
        args = parser.parse_args()

        server = args.server
        port = args.port

        msg = '''
Servidor Selecionado: %s
Porta a ser usada: %s
''' % (server,port)
        sys.stdout.write(msg)

        return 0
    except KeyboardInterrupt:
        ### handle keyboard interrupt ###
        return 0
    except Exception as e:
        if DEBUG or TESTRUN:
            raise(e)
        indent = len(program_name) * " "
        sys.stderr.write(program_name + ": " + repr(e) + "\n")
        sys.stderr.write(indent + " use --help para obter ajuda.")
        return 2
    except:
        print "Unexpected error:", sys.exc_info()
        raise

if __name__ == "__main__":
    if DEBUG:
        sys.argv.append("-h")
    if TESTRUN:
        import doctest
        doctest.testmod()
    if PROFILE:
        import cProfile
        import pstats
        profile_filename = 'br.com.cdcp.python.client_profile.txt'
        cProfile.run('main()', profile_filename)
        statsfile = open("profile_stats.txt", "wb")
        p = pstats.Stats(profile_filename, stream=statsfile)
        stats = p.strip_dirs().sort_stats('cumulative')
        stats.print_stats()
        statsfile.close()
        sys.exit(0)

    sys.exit(main())

I’m using Python 2.7, on a MAC with El Capitain.

I’ve tried so much for Eclipse Mars.1, for the Python console, and for the command line running the file directly.

Below follows the complete Tracer:

Traceback (most recent call last):
  File "/Users/extracbd/workspace/cdcp/workspace-entrevista-carlos-delfino/Client-Python/src/br/com/cdcp/python/client.py", line 197, in <module>
    exitCode = main()
  File "/Users/extracbd/workspace/cdcp/workspace-entrevista-carlos-delfino/Client-Python/src/br/com/cdcp/python/client.py", line 134, in main
    args = parseArgs(argv)
  File "/Users/extracbd/workspace/cdcp/workspace-entrevista-carlos-delfino/Client-Python/src/br/com/cdcp/python/client.py", line 95, in parseArgs
    args = parser.parse_args()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1701, in parse_args
    args, argv = self.parse_known_args(args, namespace)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1733, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1939, in _parse_known_args
    start_index = consume_optional(start_index)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1879, in consume_optional
    take_action(action, args, option_string)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 1807, in take_action
    action(self, namespace, argument_values, option_string)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 997, in __call__
    parser.exit()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py", line 2362, in exit
    _sys.exit(status)
SystemExit: 0
  • 1

    Could put the full traceback?

  • @Palaces, I found, I’m editing.

  • I have already made some tests and adjustments here, I changed the installation version, to Python 3.5, but unfortunately the syntax I use, and the raw_input() function did not work in this version, I went back to version 2.7.10 and the previous problem continues.

  • I haven’t had much time to think about it, but from what I’ve seen, the exception occurred only when the -h flag is passed. I may be talking some crazy shit, but I think she makes an exception that shouldn’t be made. Note that in traceback, code 0 appears as the end of the application, which indicates that everything went well. Anyway, speculation only...

  • Pablo agree with you, was waiting for another answer, to confirm this suspicion that was presented with this log. Well, in case I will then put the parser blog in an isolated Try to ignore this Exception. It would be interesting if you put your remarks as a response. so I can thank you for your help with a vote.

  • As soon as I finish analyzing the Python code responsible for dealing with -h I put out a real answer. For now it remains as a comment.

  • All right, no more speculation.

Show 2 more comments

1 answer

2


Well, following my hypothesis, I went to look in the same Python code, to see how it works. After all it is very simple.

The class _Helpaction is recorded as the action that must be taken when the argument -h or --help is passed on the command line. This class defines the method __call__, which, when executed, calls the method exit of the parser which is passed as argument.

The method Exit called belongs to the class ArgumentParser and he does nothing more than call the method exit module sys.

At the root of all evils, the Python documentation about the sys module, says this method does nothing more than generate an exception SystemExit and that therefore she will be caught if she has a finally or one last except like the one you put.

The last paragraph of the documentation is even clearer, which, translated freely, is thus:

In view of the fact that exit() at the end of the day, there is only one exception, it will only finish the process if it is called from the main thread and if the exception is not intercepted.

To get around this problem and keep an exception that ensures that all errors have been caught, you can put a condition that if it is SystemExit argument-ridden 0, you can finish the program quietly without printing anything or logging something.

Or, a simpler solution, you can rely on the module argparse to handle the exceptions and simply take away the management of the block’s arguments try:

# ...
parser = ArgumentParser(
    description=program_license,
    formatter_class=RawDescriptionHelpFormatter)
parser.add_argument(
    '-s', '--server',
    action="store",
    required = False)
parser.add_argument(
    '-p', '--port',
    action="store",
    required = False)

# Process arguments
args = parser.parse_args()

server = args.server
port = args.port

try:
    msg = '''
Servidor Selecionado: %s
Porta a ser usada: %s
''' % (server,port)
    sys.stdout.write(msg)
    # ...
  • Thank you. based on these placements I will seek the definitive solution.

  • I put an example of a simple solution, which I think is appropriate for your case.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.