argparse and filetypes

Robert Kern robert.kern at gmail.com
Tue Mar 22 14:09:09 EDT 2011


On 3/22/11 9:06 AM, Bradley Hintze wrote:
> Hi,
>
> I just started with argparse. I want to simply check the extension of
> the file that the user passes to the program. I get a ''file' object
> has no attribute 'rfind'' error when I use
> os.path.splitext(args.infile).  Here is my code.
>
> import argparse, sys, os
>
> des = 'Get restraint definitions from probe.'
> parser = argparse.ArgumentParser(description=des)
> parser.add_argument('infile', nargs='?', type=argparse.FileType('r'))
> # parser.add_argument('outfile', nargs='?', type=argparse.FileType('w'),
>                     # default=sys.stdout)
>
> args = parser.parse_args()
> # print args.infile.readlines()
> print basename, extension = os.path.splitext(args.infile)
>
> There may be a better way to check extensions using argparse.

The type= argument should be a callable that either coerces the string to an 
appropriate object or raises a ValueError if the string is unacceptable. 
FileType() is a convenient callable for opening readable or writable files; when 
called, it returns a regular file object, not the filename, as you saw from the 
exception you got. It does not do any validation.

You can add validation very easily:

class TxtFile(argparse.FileType):
     def __call__(self, string):
         base, ext = os.path.splitext(string)
         if ext != '.txt':
             raise ValueError('%s should have a .txt extension' % string)
         return super(TxtFile, self).__call__(string)

...
parser.add_argument('infile', type=TxtFile('r'))

-- 
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco




More information about the Python-list mailing list