11

argumentparser can take file type argument and leave the file open directly, for example:

parser.add_argument('infile', nargs='?', type=argparse.FileType('r'))
args = parser.parse_args().__dict__
input = args['infile'].readlines()

do I need to close args['infile'] in my program? Would argumentparser close it for me? I didn't find anywhere mention this in the documentations.

Sawyer
  • 15,581
  • 27
  • 88
  • 124

3 Answers3

5

NO, it does not close the filetype object.. see this

The problem here is that FileType may return stdin or stdout, so it can’t just always close the file object.

A great number of unclosed file handles may cause problem to some OSes, but that’s it. On the plus side, the fact that argparse accepts for its type argument any callable that can check and convert a string input is simple, clean and works.

Also look at this

avasal
  • 14,350
  • 4
  • 31
  • 47
  • 2
    So, since argparse doesn't close the file, wouldn't it simply be better to use this solution: https://stackoverflow.com/a/18863004/1903852 – Joris Kinable Jul 06 '17 at 17:40
1

Some digging in the source reveals that it doesn't close it for you. That makes sense, as it also has to open files for writing, and you probably wouldn't want it to close those.

khagler
  • 3,996
  • 29
  • 40
  • I wouldn't want to close that even after writing? – Sawyer Dec 07 '12 at 16:14
  • 2
    You'd want to close it _yourself_, but you wouldn't want argparse to close it, because then it would be closed immediately, before you had a chance to use it--which would make it pointless for argparse to have opened it to begin with. – khagler Dec 07 '12 at 16:57
1

I seem to have stumbled onto a clear and concise way to close argparse files:

parser = argparse.ArgumentParser(description='Hello!')
parser.add_argument('src_file', 
    type=argparse.FileType('r', encoding='Windows-1252'), help='Input .txt file')
parser.add_argument('dst_file', 
    type=argparse.FileType('w', encoding='Windows-1252'), help='Output .foo file')
args = parser.parse_args()
# do your thing...
args.src_file.close()
args.dst_file.close()
#close(args.src_file)  don't do this... gives error

This is with Python 3.10.4; googling the PEPs for this 'feature', nothing was found.

So either this:

  • Has existed all along but nobody knew,
  • Was added at some point but not mentioned,
  • Or it doesn't actually close the file (and doesn't give any error.)*

*The Python debugger in Code/Win10 reports the <_io.TextIOWrapper>'s closed boolean does change to True from this .close(), so it seems to be working as expected.

rdtsc
  • 1,044
  • 10
  • 17