Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType. Approved by Georg in the tracker.

This commit is contained in:
Steven Bethard 2011-01-24 20:40:15 +00:00
parent cdb8388cad
commit f8583acb53
3 changed files with 25 additions and 14 deletions

View file

@ -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):
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)
# =========================== # ===========================

View file

@ -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):
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):
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):
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'))),

View file

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