diff options
| author | Steven Bethard <steven.bethard@gmail.com> | 2011-01-24 20:40:15 (GMT) |
|---|---|---|
| committer | Steven Bethard <steven.bethard@gmail.com> | 2011-01-24 20:40:15 (GMT) |
| commit | f8583acb534432097671e79eb4110b9861dd2e17 (patch) | |
| tree | 1287cc0567d1e65b5b6edfc868a5fa0f577f7cff | |
| parent | cdb8388cad74e0f2910d5b43531daf6271467292 (diff) | |
| download | cpython-f8583acb534432097671e79eb4110b9861dd2e17.zip cpython-f8583acb534432097671e79eb4110b9861dd2e17.tar.gz cpython-f8583acb534432097671e79eb4110b9861dd2e17.tar.bz2 | |
Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType. Approved by Georg in the tracker.
| -rw-r--r-- | Lib/argparse.py | 13 | ||||
| -rw-r--r-- | Lib/test/test_argparse.py | 23 | ||||
| -rw-r--r-- | Misc/NEWS | 3 |
3 files changed, 25 insertions, 14 deletions
diff --git a/Lib/argparse.py b/Lib/argparse.py index 78f4dcb..75cc28a 100644 --- a/Lib/argparse.py +++ b/Lib/argparse.py @@ -1109,7 +1109,7 @@ class FileType(object): the builtin open() function. """ - def __init__(self, mode='r', bufsize=None): + def __init__(self, mode='r', bufsize=-1): self._mode = mode self._bufsize = bufsize @@ -1125,14 +1125,15 @@ class FileType(object): raise ValueError(msg) # all other arguments are used as file names - if self._bufsize: + try: return open(string, self._mode, self._bufsize) - else: - return open(string, self._mode) + except IOError as e: + message = _("can't open '%s': %s") + raise ArgumentTypeError(message % (string, e)) def __repr__(self): - args = [self._mode, self._bufsize] - args_str = ', '.join([repr(arg) for arg in args if arg is not None]) + args = self._mode, self._bufsize + args_str = ', '.join(repr(arg) for arg in args if arg != -1) return '%s(%s)' % (type(self).__name__, args_str) # =========================== diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py index 3e71f57..50a6d49 100644 --- a/Lib/test/test_argparse.py +++ b/Lib/test/test_argparse.py @@ -4,6 +4,7 @@ import codecs import inspect import os import shutil +import stat import sys import textwrap import tempfile @@ -46,14 +47,13 @@ class TempDirMixin(object): def tearDown(self): os.chdir(self.old_dir) - while True: - try: - shutil.rmtree(self.temp_dir) - except WindowsError: - continue - else: - break + shutil.rmtree(self.temp_dir, True) + 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): @@ -1451,17 +1451,19 @@ class TestFileTypeR(TempDirMixin, ParserTestCase): file = open(os.path.join(self.temp_dir, file_name), 'w') file.write(file_name) file.close() + self.create_readonly_file('readonly') argument_signatures = [ Sig('-x', type=argparse.FileType()), Sig('spam', type=argparse.FileType('r')), ] - failures = ['-x', '-x bar'] + failures = ['-x', '-x bar', 'non-existent-file.txt'] successes = [ ('foo', NS(x=None, spam=RFile('foo'))), ('-x foo bar', 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)), + ('readonly', NS(x=None, spam=RFile('readonly'))), ] @@ -1510,11 +1512,16 @@ class WFile(object): class TestFileTypeW(TempDirMixin, ParserTestCase): """Test the FileType option/argument type for writing files""" + def setUp(self): + super(TestFileTypeW, self).setUp() + self.create_readonly_file('readonly') + argument_signatures = [ Sig('-x', type=argparse.FileType('w')), Sig('spam', type=argparse.FileType('w')), ] failures = ['-x', '-x bar'] + failures = ['-x', '-x bar', 'readonly'] successes = [ ('foo', NS(x=None, spam=WFile('foo'))), ('-x foo bar', NS(x=WFile('foo'), spam=WFile('bar'))), @@ -140,6 +140,9 @@ Library OSError exception when The OS had been told to ignore SIGCLD in our process or otherwise not wait for exiting child processes. +- Issue #9509: argparse now properly handles IOErrors raised by + argparse.FileType. + Extension Modules ----------------- |
