Rhugga
Rhugga

Reputation: 55

Getting "AttributeError: 'tuple' object has no attribute" and fail to see why

I'm stuck using python 2.4 for this project so I'm using optparse. Getting the following error when running this code:

Traceback (most recent call last):
  File "./clientNFSLatMonME.py", line 49, in ?
    debug,verbose,interval = parseOptions()
  File "./clientNFSLatMonME.py", line 43, in parseOptions
    if (args.interval < 1) or (args.interval > MAX_INTERVAL):
AttributeError: 'tuple' object has no attribute 'interval'

Code is as follows:

MAX_INTERVAL = 1800

def parseOptions():

    parser = OptionParser()
    parser.add_option("-d", "--debug",    dest="debug",    action="store_true", help="enable additional debugging output")
    parser.add_option("-v", "--verbose",  dest="verbose",  action="store_true", help="enable additional console output")
    parser.add_option("-i", "--interval", dest="interval", action="store", type="int", default=900, help="specify the time interval, default is 900, maximum is 1800")

    args = parser.parse_args()

    if (args.interval < 1) or (args.interval > MAX_INTERVAL):
        print "Error: interval must be between 1 and " + str(MAX_INTERVAL) + ", terminating."
        system.exit(1)

    return args.debug, args.verbose, args.interval

debug,verbose,interval = parseOptions()

Upvotes: 5

Views: 4925

Answers (2)

Rafs
Rafs

Reputation: 814

I was getting a similar error to the one in the title when using -h option: AttributeError: 'tuple' object has no attribute 'strip'

% python code.py -h

args = parser.parse_args()
           ^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 1874, in parse_args
    args, argv = self.parse_known_args(args, namespace)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 1907, in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 2128, in _parse_known_args
    start_index = consume_optional(start_index)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 2068, in consume_optional
    take_action(action, args, option_string)
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 1983, in take_action
    action(self, namespace, argument_values, option_string)
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 1122, in __call__
    parser.print_help()
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 2611, in print_help
    self._print_message(self.format_help(), file)
                        ^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 2595, in format_help
    return formatter.format_help()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 287, in format_help
    help = self._root_section.format_help()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 217, in format_help
    item_help = join([func(*args) for func, args in self.items])
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 217, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
                      ^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 217, in format_help
    item_help = join([func(*args) for func, args in self.items])
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 217, in <listcomp>
    item_help = join([func(*args) for func, args in self.items])
                      ^^^^^^^^^^^
  File "/opt/homebrew/Cellar/[email protected]/3.11.11/Frameworks/Python.framework/Versions/3.11/lib/python3.11/argparse.py", line 545, in _format_action
    if action.help and action.help.strip():
                       ^^^^^^^^^^^^^^^^^
AttributeError: 'tuple' object has no attribute 'strip'

I had one malformed help arguments as a tuple and not a string:

parser.add_argument(
        "-i",
        "--inplace-pp",
        action="store_true",
        help=(
            "Postprocess in-place: update date and don't insert artificial "
            "records. Will modify existing data, but won't create new ones.",
        ),
    )

I removed the surplus , in that help option which resolved the error:

parser.add_argument(
        "-i",
        "--inplace-pp",
        action="store_true",
        help=(
            "Postprocess in-place: update date and don't insert artificial "
            "records. Will modify existing data, but won't create new ones."
        ),
    )

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1124508

The parser.parse_args() method returns a tuple, containing parsed options and the remaining arguments.

Unpack that tuple; the convention is to use options for the parsed switches and args for

options, args = parser.parse_args()

and use options to refer to parsed command line switches:

if options.interval < 1 or options.interval > MAX_INTERVAL:
    # ...

return options.debug, options.verbose, options.interval

That range check can be expressed using a chained comparison too:

if not (0 > options.interval >= MAX_INTERVAL):
    # ...

Upvotes: 9

Related Questions