]> granicus.if.org Git - python/commitdiff
Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType. Appro...
authorSteven Bethard <steven.bethard@gmail.com>
Mon, 24 Jan 2011 20:40:15 +0000 (20:40 +0000)
committerSteven Bethard <steven.bethard@gmail.com>
Mon, 24 Jan 2011 20:40:15 +0000 (20:40 +0000)
Lib/argparse.py
Lib/test/test_argparse.py
Misc/NEWS

index 78f4dcb228774210b52552c04d21a2f9208d6e28..75cc28a0433fe413d070f466e2fc4ab9bde35d0a 100644 (file)
@@ -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)
 
 # ===========================
index 3e71f57d2c2869bb4eb25e00e6459c10bb5dfb0b..50a6d493905239a23c64896d368faea392cb182c 100644 (file)
@@ -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'))),
index f77b60354e189ab6a249e739b10287f91e890fe7..42ce636bc2e3a8ad367c7335e7f91d8f697571e6 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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
 -----------------