Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b027011

Browse files
committed
Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType. Approved by Georg in the tracker.
1 parent 2a6ac15 commit b027011

3 files changed

Lines changed: 24 additions & 15 deletions

File tree

Lib/argparse.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ class FileType(object):
11211121
the builtin open() function.
11221122
"""
11231123

1124-
def __init__(self, mode='r', bufsize=None):
1124+
def __init__(self, mode='r', bufsize=-1):
11251125
self._mode = mode
11261126
self._bufsize = bufsize
11271127

@@ -1137,14 +1137,15 @@ def __call__(self, string):
11371137
raise ValueError(msg)
11381138

11391139
# all other arguments are used as file names
1140-
if self._bufsize:
1140+
try:
11411141
return open(string, self._mode, self._bufsize)
1142-
else:
1143-
return open(string, self._mode)
1142+
except IOError as e:
1143+
message = _("can't open '%s': %s")
1144+
raise ArgumentTypeError(message % (string, e))
11441145

11451146
def __repr__(self):
1146-
args = [self._mode, self._bufsize]
1147-
args_str = ', '.join([repr(arg) for arg in args if arg is not None])
1147+
args = self._mode, self._bufsize
1148+
args_str = ', '.join(repr(arg) for arg in args if arg != -1)
11481149
return '%s(%s)' % (type(self).__name__, args_str)
11491150

11501151
# ===========================

Lib/test/test_argparse.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import inspect
55
import os
66
import shutil
7+
import stat
78
import sys
89
import textwrap
910
import tempfile
@@ -45,14 +46,13 @@ def setUp(self):
4546

4647
def tearDown(self):
4748
os.chdir(self.old_dir)
48-
while True:
49-
try:
50-
shutil.rmtree(self.temp_dir)
51-
except WindowsError:
52-
continue
53-
else:
54-
break
49+
shutil.rmtree(self.temp_dir, True)
5550

51+
def create_readonly_file(self, filename):
52+
file_path = os.path.join(self.temp_dir, filename)
53+
with open(file_path, 'w') as file:
54+
file.write(filename)
55+
os.chmod(file_path, stat.S_IREAD)
5656

5757
class Sig(object):
5858

@@ -1446,17 +1446,19 @@ def setUp(self):
14461446
file = open(os.path.join(self.temp_dir, file_name), 'w')
14471447
file.write(file_name)
14481448
file.close()
1449+
self.create_readonly_file('readonly')
14491450

14501451
argument_signatures = [
14511452
Sig('-x', type=argparse.FileType()),
14521453
Sig('spam', type=argparse.FileType('r')),
14531454
]
1454-
failures = ['-x', '']
1455+
failures = ['-x', '', 'non-existent-file.txt']
14551456
successes = [
14561457
('foo', NS(x=None, spam=RFile('foo'))),
14571458
('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
14581459
('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
14591460
('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
1461+
('readonly', NS(x=None, spam=RFile('readonly'))),
14601462
]
14611463

14621464

@@ -1503,11 +1505,15 @@ def __eq__(self, other):
15031505
class TestFileTypeW(TempDirMixin, ParserTestCase):
15041506
"""Test the FileType option/argument type for writing files"""
15051507

1508+
def setUp(self):
1509+
super(TestFileTypeW, self).setUp()
1510+
self.create_readonly_file('readonly')
1511+
15061512
argument_signatures = [
15071513
Sig('-x', type=argparse.FileType('w')),
15081514
Sig('spam', type=argparse.FileType('w')),
15091515
]
1510-
failures = ['-x', '']
1516+
failures = ['-x', '', 'readonly']
15111517
successes = [
15121518
('foo', NS(x=None, spam=WFile('foo'))),
15131519
('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Library
4545
that for incoming headers which makes this behaviour now consistent in
4646
both incoming and outgoing direction.
4747

48+
- Issue #9509: argparse now properly handles IOErrors raised by
49+
argparse.FileType.
4850

4951
What's New in Python 3.2 Release Candidate 1
5052
============================================

0 commit comments

Comments
 (0)