mirror of
https://github.com/python/cpython.git
synced 2025-09-18 14:40:43 +00:00
Issue #9509: make argarse properly handle IOErrors raised by argparse.FileType. Approved by Georg in the tracker.
This commit is contained in:
parent
cdb8388cad
commit
f8583acb53
3 changed files with 25 additions and 14 deletions
|
@ -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)
|
||||||
|
|
||||||
# ===========================
|
# ===========================
|
||||||
|
|
|
@ -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'))),
|
||||||
|
|
|
@ -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
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue