views:

267

answers:

4

I am trying to pass '-f nameoffile' to the program when I call it from the command line. I got this from the python sites documentation but when I pass '-f filename' or '--file=filename' it throws the error that I didnt pass enough arguments. If i pass -h the programs responds how it should and gives me the help. Any ideas? I imagine its something simple that I am overlooking. Any and all help is great, thanks, Justin.

[justin87@el-beasto-loco python]$ python openall.py -f chords.tar 
Usage: openall.py [options] arg

openall.py: error: incorrect number of arguments
[justin87@el-beasto-loco python]$ 


#!/usr/bin/python

import tarfile
import os
import zipfile
from optparse import OptionParser

def check_tar(file):
    if tarfile.is_tarfile(file):
        return True

def open_tar(file):
    try:
        tar = tarfile.open(file)
        tar.extractall()
        tar.close()
    except tarfile.ReadError:
        print "File is somehow invalid or can not be handled by tarfile"
    except tarfile.CompressionError:
        print "Compression method is not supported or data cannot be decoded"
    except tarfile.StreamError:
        print "Is raised for the limitations that are typical for stream-like TarFile objects."
    except tarfile.ExtractError:
        print "Is raised for non-fatal errors when using TarFile.extract(), but only if TarFile.errorlevel== 2."

def check_zip(file):
    if zipfile.is_zipfile(file):
        return True

def open_zip(file):
    try:
        zip = zipfile.ZipFile(file)
        zip.extractall()
        zip.close()
        #open the zip

        print "GOT TO OPENING"
    except zipfile.BadZipfile:
        print "The error raised for bad ZIP files (old name: zipfile.error)."
    except zipfile.LargeZipFile:
        print "The error raised when a ZIP file would require ZIP64 functionality but that has not been enabled."

rules = ((check_tar, open_tar),
         (check_zip, open_zip)
         )

def checkall(file):           
    for checks, extracts in rules:
        if checks(file):
            return extracts(file)

def main():
    usage = "usage: %prog [options] arg"
    parser = OptionParser(usage)
    parser.add_option("-f", "--file", dest="filename",
                      help="read data from FILENAME")

    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")

    file = options.filename
    checkall(file)

if __name__ == '__main__':
    main()
+1  A: 

After parsing the options out of the argument list, you check that you were passed an argument. This is independent of the argument to -f. It sounds like you're just not passing this argument. Since you also don't actually use this argument, you should probably just remove the check on len(args).

Thomas Wouters
+2  A: 

Your problem is probably the if len(args) != 1:. That is looking for an additional argument (i.e. not an option). If you remove that check and look at your options dictionary you should see {'filename': 'blah'}.

ezod
+1  A: 

Your input filename isn't an option to the program, it's an argument:

def main():
    usage = "Usage: %prog [options] FILE"
    description = "Read data from FILE."
    parser = OptionParser(usage, description=description)

    (options, args) = parser.parse_args()
    if len(args) != 1:
        parser.error("incorrect number of arguments")

    file = args[0]
    checkall(file)

You can usually tell the difference because options generally have sensible defaults while arguments don't.

Roger Pate
A: 

You should set the 'action' attribute in the 'add_option()' method to 'store', this tells the optparse object to store the argument immediately following the option flag, though this is the default behavior. The value following the flag will then be stored in 'options.filename' and not in args. I also think that the

if len(args) != 1:

is also an issue, you will get the same message if len(args) is greater than or less than 1.

lewisblackfan