Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

argparse and filetypes

48 views
Skip to first unread message

Bradley Hintze

unread,
Mar 22, 2011, 10:06:41 AM3/22/11
to Python
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.

Any help will be appreciated.
Thanks,
Bradley

--
Bradley J. Hintze
Graduate Student
Duke University
School of Medicine

Alex Willmer

unread,
Mar 22, 2011, 10:48:42 AM3/22/11
to
On Mar 22, 2:06 pm, Bradley Hintze <bradle...@aggiemail.usu.edu>
wrote:

> 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)

Because you specified type=argparse.FileType('r') argparse has created
args.infile as a file object (e.g. open('/some/path/data.dat', 'r')),
not as a string containing the path. So type(args.infile) ==
type(file) and args.infile.readlines() returns the contents of that
file.

If you wish to check the file extension of the path in question I
suggest you remove type=argparse.FileType('r'), argparse will create
args.infile as a string containing that path. To open the file call
open(args.infile, 'r'), this will return the file object.

Alex Willmer

unread,
Mar 22, 2011, 11:52:37 AM3/22/11
to
On Mar 22, 2:06 pm, Bradley Hintze <bradle...@aggiemail.usu.edu>
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).

Addendum, some file objects have a name attribute (which I hadn't
noticed until today):

file.name
If the file object was created using open(), the name of the file.
Otherwise, some string that indicates the source of the file object,
of the form <...>. This is a read-only attribute and may not be
present on all file-like objects.

http://docs.python.org/library/stdtypes.html#file-objects

Robert Kern

unread,
Mar 22, 2011, 2:09:09 PM3/22/11
to pytho...@python.org
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

0 new messages