Kaydet (Commit) f8583acb authored tarafından Steven Bethard's avatar Steven Bethard

Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType.…

Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType. Approved by Georg in the tracker.
üst cdb8388c
...@@ -1109,7 +1109,7 @@ class FileType(object): ...@@ -1109,7 +1109,7 @@ class FileType(object):
the builtin open() function. the builtin open() function.
""" """
def __init__(self, mode='r', bufsize=None): def __init__(self, mode='r', bufsize=-1):
self._mode = mode self._mode = mode
self._bufsize = bufsize self._bufsize = bufsize
...@@ -1125,14 +1125,15 @@ class FileType(object): ...@@ -1125,14 +1125,15 @@ class FileType(object):
raise ValueError(msg) raise ValueError(msg)
# all other arguments are used as file names # all other arguments are used as file names
if self._bufsize: try:
return open(string, self._mode, self._bufsize) return open(string, self._mode, self._bufsize)
else: except IOError as e:
return open(string, self._mode) message = _("can't open '%s': %s")
raise ArgumentTypeError(message % (string, e))
def __repr__(self): def __repr__(self):
args = [self._mode, self._bufsize] args = self._mode, self._bufsize
args_str = ', '.join([repr(arg) for arg in args if arg is not None]) args_str = ', '.join(repr(arg) for arg in args if arg != -1)
return '%s(%s)' % (type(self).__name__, args_str) return '%s(%s)' % (type(self).__name__, args_str)
# =========================== # ===========================
......
...@@ -4,6 +4,7 @@ import codecs ...@@ -4,6 +4,7 @@ import codecs
import inspect import inspect
import os import os
import shutil import shutil
import stat
import sys import sys
import textwrap import textwrap
import tempfile import tempfile
...@@ -46,14 +47,13 @@ class TempDirMixin(object): ...@@ -46,14 +47,13 @@ class TempDirMixin(object):
def tearDown(self): def tearDown(self):
os.chdir(self.old_dir) os.chdir(self.old_dir)
while True: shutil.rmtree(self.temp_dir, True)
try:
shutil.rmtree(self.temp_dir)
except WindowsError:
continue
else:
break
def create_readonly_file(self, filename):
file_path = os.path.join(self.temp_dir, filename)
with open(file_path, 'w') as file:
file.write(filename)
os.chmod(file_path, stat.S_IREAD)
class Sig(object): class Sig(object):
...@@ -1451,17 +1451,19 @@ class TestFileTypeR(TempDirMixin, ParserTestCase): ...@@ -1451,17 +1451,19 @@ class TestFileTypeR(TempDirMixin, ParserTestCase):
file = open(os.path.join(self.temp_dir, file_name), 'w') file = open(os.path.join(self.temp_dir, file_name), 'w')
file.write(file_name) file.write(file_name)
file.close() file.close()
self.create_readonly_file('readonly')
argument_signatures = [ argument_signatures = [
Sig('-x', type=argparse.FileType()), Sig('-x', type=argparse.FileType()),
Sig('spam', type=argparse.FileType('r')), Sig('spam', type=argparse.FileType('r')),
] ]
failures = ['-x', '-x bar'] failures = ['-x', '-x bar', 'non-existent-file.txt']
successes = [ successes = [
('foo', NS(x=None, spam=RFile('foo'))), ('foo', NS(x=None, spam=RFile('foo'))),
('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))), ('-x foo bar', NS(x=RFile('foo'), spam=RFile('bar'))),
('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))), ('bar -x foo', NS(x=RFile('foo'), spam=RFile('bar'))),
('-x - -', NS(x=sys.stdin, spam=sys.stdin)), ('-x - -', NS(x=sys.stdin, spam=sys.stdin)),
('readonly', NS(x=None, spam=RFile('readonly'))),
] ]
...@@ -1510,11 +1512,16 @@ class WFile(object): ...@@ -1510,11 +1512,16 @@ class WFile(object):
class TestFileTypeW(TempDirMixin, ParserTestCase): class TestFileTypeW(TempDirMixin, ParserTestCase):
"""Test the FileType option/argument type for writing files""" """Test the FileType option/argument type for writing files"""
def setUp(self):
super(TestFileTypeW, self).setUp()
self.create_readonly_file('readonly')
argument_signatures = [ argument_signatures = [
Sig('-x', type=argparse.FileType('w')), Sig('-x', type=argparse.FileType('w')),
Sig('spam', type=argparse.FileType('w')), Sig('spam', type=argparse.FileType('w')),
] ]
failures = ['-x', '-x bar'] failures = ['-x', '-x bar']
failures = ['-x', '-x bar', 'readonly']
successes = [ successes = [
('foo', NS(x=None, spam=WFile('foo'))), ('foo', NS(x=None, spam=WFile('foo'))),
('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))),
......
...@@ -140,6 +140,9 @@ Library ...@@ -140,6 +140,9 @@ Library
OSError exception when The OS had been told to ignore SIGCLD in our process OSError exception when The OS had been told to ignore SIGCLD in our process
or otherwise not wait for exiting child processes. or otherwise not wait for exiting child processes.
- Issue #9509: argparse now properly handles IOErrors raised by
argparse.FileType.
Extension Modules Extension Modules
----------------- -----------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment