Fixed #30137 -- Replaced OSError aliases with the canonical OSError.

Used more specific errors (e.g. FileExistsError) as appropriate.
This commit is contained in:
Jon Dufresne 2019-01-28 07:01:35 -08:00 committed by Tim Graham
parent 7444f32527
commit 7785e03ba8
33 changed files with 60 additions and 69 deletions

View File

@ -173,7 +173,7 @@ class CommonPasswordValidator:
try:
with gzip.open(str(password_list_path)) as f:
common_passwords_lines = f.read().decode().splitlines()
except IOError:
except OSError:
with open(str(password_list_path)) as f:
common_passwords_lines = f.readlines()

View File

@ -13,8 +13,7 @@ logger = logging.getLogger('django.contrib.gis')
try:
from django.conf import settings
lib_path = settings.GDAL_LIBRARY_PATH
except (AttributeError, EnvironmentError,
ImportError, ImproperlyConfigured):
except (AttributeError, ImportError, ImproperlyConfigured, OSError):
lib_path = None
if lib_path:

View File

@ -23,8 +23,7 @@ def load_geos():
try:
from django.conf import settings
lib_path = settings.GEOS_LIBRARY_PATH
except (AttributeError, EnvironmentError,
ImportError, ImproperlyConfigured):
except (AttributeError, ImportError, ImproperlyConfigured, OSError):
lib_path = None
# Setting the appropriate names for the GEOS-C library.

View File

@ -94,7 +94,7 @@ class SessionStore(SessionBase):
session_data = {}
self.delete()
self.create()
except (IOError, SuspiciousOperation):
except (OSError, SuspiciousOperation):
self._session_key = None
return session_data
@ -166,7 +166,7 @@ class SessionStore(SessionBase):
finally:
if not renamed:
os.unlink(output_file_name)
except (OSError, IOError, EOFError):
except (EOFError, OSError):
pass
def exists(self, session_key):

View File

@ -93,7 +93,7 @@ class HashedFilesMixin:
raise ValueError("The file '%s' could not be found with %r." % (filename, self))
try:
content = self.open(filename)
except IOError:
except OSError:
# Handle directory paths and fragments
return name
try:
@ -380,7 +380,7 @@ class ManifestFilesMixin(HashedFilesMixin):
try:
with self.open(self.manifest_name) as manifest:
return manifest.read().decode()
except IOError:
except OSError:
return None
def load_manifest(self):

View File

@ -35,7 +35,7 @@ def file_move_safe(old_file_name, new_file_name, chunk_size=1024 * 64, allow_ove
If that fails, stream manually from one file to another in pure Python.
If the destination file exists and ``allow_overwrite`` is ``False``, raise
``IOError``.
``FileExistsError``.
"""
# There's no reason to move if we don't have to.
if _samefile(old_file_name, new_file_name):
@ -43,7 +43,7 @@ def file_move_safe(old_file_name, new_file_name, chunk_size=1024 * 64, allow_ove
try:
if not allow_overwrite and os.access(new_file_name, os.F_OK):
raise IOError("Destination file %s exists and allow_overwrite is False" % new_file_name)
raise FileExistsError('Destination file %s exists and allow_overwrite is False.' % new_file_name)
os.rename(old_file_name, new_file_name)
return

View File

@ -246,7 +246,7 @@ class FileSystemStorage(Storage):
# was created concurrently.
pass
if not os.path.isdir(directory):
raise IOError("%s exists and is not a directory." % directory)
raise FileExistsError('%s exists and is not a directory.' % directory)
# There's a potential race condition between get_available_name and
# saving the file; it's possible that two threads might return the

View File

@ -50,7 +50,7 @@ if os.name == 'nt':
self.close_called = True
try:
self.file.close()
except (OSError, IOError):
except OSError:
pass
try:
self.unlink(self.name)

View File

@ -1,6 +1,5 @@
"""SMTP email backend class."""
import smtplib
import socket
import ssl
import threading
@ -69,7 +68,7 @@ class EmailBackend(BaseEmailBackend):
if self.username and self.password:
self.connection.login(self.username, self.password)
return True
except (smtplib.SMTPException, socket.error):
except OSError:
if not self.fail_silently:
raise

View File

@ -19,7 +19,7 @@ def is_writable(path):
try:
with open(path, 'a'):
os.utime(path, None)
except (IOError, OSError):
except OSError:
return False
return True

View File

@ -137,7 +137,7 @@ class Command(BaseCommand):
handler = self.get_handler(*args, **options)
run(self.addr, int(self.port), handler,
ipv6=self.use_ipv6, threading=threading, server_cls=self.server_cls)
except socket.error as e:
except OSError as e:
# Use helpful error messages instead of ugly tracebacks.
ERRORS = {
errno.EACCES: "You don't have permission to access that port.",

View File

@ -257,7 +257,7 @@ class TemplateCommand(BaseCommand):
self.stdout.write("Downloading %s\n" % display_url)
try:
the_path, info = urlretrieve(url, path.join(tempdir, filename))
except IOError as e:
except OSError as e:
raise CommandError("couldn't download URL %s to %s: %s" %
(url, filename, e))
@ -312,7 +312,7 @@ class TemplateCommand(BaseCommand):
try:
archive.extract(filename, tempdir)
return tempdir
except (archive.ArchiveException, IOError) as e:
except (archive.ArchiveException, OSError) as e:
raise CommandError("couldn't extract file %s to %s: %s" %
(filename, tempdir, e))

View File

@ -51,8 +51,8 @@ def get_internal_wsgi_application():
def is_broken_pipe_error():
exc_type, exc_value = sys.exc_info()[:2]
return issubclass(exc_type, socket.error) and exc_value.args[0] == 32
exc_type, _, _ = sys.exc_info()
return issubclass(exc_type, BrokenPipeError)
class WSGIServer(simple_server.WSGIServer):
@ -171,7 +171,7 @@ class WSGIRequestHandler(simple_server.WSGIRequestHandler):
self.handle_one_request()
try:
self.connection.shutdown(socket.SHUT_WR)
except (socket.error, AttributeError):
except (AttributeError, OSError):
pass
def handle_one_request(self):

View File

@ -22,7 +22,7 @@ RAISE_ERROR = object()
host_validation_re = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9\.:]+\])(:\d+)?$")
class UnreadablePostError(IOError):
class UnreadablePostError(OSError):
pass
@ -284,7 +284,7 @@ class HttpRequest:
try:
self._body = self.read()
except IOError as e:
except OSError as e:
raise UnreadablePostError(*e.args) from e
self._stream = BytesIO(self._body)
return self._body
@ -339,14 +339,14 @@ class HttpRequest:
self._read_started = True
try:
return self._stream.read(*args, **kwargs)
except IOError as e:
except OSError as e:
raise UnreadablePostError(*e.args) from e
def readline(self, *args, **kwargs):
self._read_started = True
try:
return self._stream.readline(*args, **kwargs)
except IOError as e:
except OSError as e:
raise UnreadablePostError(*e.args) from e
def __iter__(self):

View File

@ -251,13 +251,13 @@ class HttpResponseBase:
signals.request_finished.send(sender=self._handler_class)
def write(self, content):
raise IOError("This %s instance is not writable" % self.__class__.__name__)
raise OSError('This %s instance is not writable' % self.__class__.__name__)
def flush(self):
pass
def tell(self):
raise IOError("This %s instance cannot tell its position" % self.__class__.__name__)
raise OSError('This %s instance cannot tell its position' % self.__class__.__name__)
# These methods partially implement a stream-like object interface.
# See https://docs.python.org/library/io.html#io.IOBase
@ -272,7 +272,7 @@ class HttpResponseBase:
return False
def writelines(self, lines):
raise IOError("This %s instance is not writable" % self.__class__.__name__)
raise OSError('This %s instance is not writable' % self.__class__.__name__)
class HttpResponse(HttpResponseBase):

View File

@ -293,7 +293,7 @@ class CsrfViewMiddleware(MiddlewareMixin):
if request.method == "POST":
try:
request_csrf_token = request.POST.get('csrfmiddlewaretoken', '')
except IOError:
except OSError:
# Handle a broken connection before we've completed reading
# the POST data. process_view shouldn't raise any
# exceptions, so we'll ignore and serve the user a 403

View File

@ -99,7 +99,7 @@ class DjangoTranslation(gettext_module.GNUTranslations):
self._add_local_translations()
if self.__language == settings.LANGUAGE_CODE and self.domain == 'django' and self._catalog is None:
# default lang should have at least one translation file available.
raise IOError("No translation files found for default language %s." % settings.LANGUAGE_CODE)
raise OSError('No translation files found for default language %s.' % settings.LANGUAGE_CODE)
self._add_fallback(localedirs)
if self._catalog is None:
# No catalogs found for this language, set an empty catalog.

View File

@ -357,7 +357,7 @@ class ExceptionReporter:
try:
with open(filename, 'rb') as fp:
source = fp.read().splitlines()
except (OSError, IOError):
except OSError:
pass
if source is None:
return None, [], None, []

View File

@ -114,7 +114,7 @@ over a large number of objects. If files are not manually closed after
accessing them, the risk of running out of file descriptors may arise. This
may lead to the following error::
IOError: [Errno 24] Too many open files
OSError: [Errno 24] Too many open files
File storage

View File

@ -867,7 +867,7 @@ class DateTimePickerSeleniumTests(AdminWidgetSeleniumTestCase):
for language_code, language_name in settings.LANGUAGES:
try:
catalog = gettext.translation('djangojs', path, [language_code])
except IOError:
except OSError:
continue
if month_string in catalog._catalog:
month_name = catalog._catalog[month_string]

View File

@ -1448,8 +1448,8 @@ class FileBasedCacheTests(BaseCacheTests, TestCase):
self.assertEqual(cache.get('foo', 'baz'), 'baz')
def test_get_does_not_ignore_non_filenotfound_exceptions(self):
with mock.patch('builtins.open', side_effect=IOError):
with self.assertRaises(IOError):
with mock.patch('builtins.open', side_effect=OSError):
with self.assertRaises(OSError):
cache.get('foo')
def test_empty_cache_file_considered_expired(self):

View File

@ -441,12 +441,12 @@ class CsrfViewMiddlewareTestMixin:
def test_post_data_read_failure(self):
"""
#20128 -- IOErrors during POST data reading should be caught and
treated as if the POST data wasn't there.
OSErrors during POST data reading are caught and treated as if the
POST data wasn't there (#20128).
"""
class CsrfPostRequest(HttpRequest):
"""
HttpRequest that can raise an IOError when accessing POST data
HttpRequest that can raise an OSError when accessing POST data
"""
def __init__(self, token, raise_error):
super().__init__()
@ -464,7 +464,7 @@ class CsrfViewMiddlewareTestMixin:
self.raise_error = raise_error
def _load_post_and_files(self):
raise IOError('error reading input data')
raise OSError('error reading input data')
def _get_post(self):
if self.raise_error:

View File

@ -482,9 +482,9 @@ class FileStorageTests(SimpleTestCase):
f1 = ContentFile('chunks fails')
def failing_chunks():
raise IOError
raise OSError
f1.chunks = failing_chunks
with self.assertRaises(IOError):
with self.assertRaises(OSError):
self.storage.save('error.file', f1)
def test_delete_no_name(self):

View File

@ -548,16 +548,13 @@ class DirectoryCreationTests(SimpleTestCase):
self.obj.testfile.save('foo.txt', SimpleUploadedFile('foo.txt', b'x'), save=False)
def test_not_a_directory(self):
"""The correct IOError is raised when the upload directory name exists but isn't a directory"""
# Create a file with the upload directory name
open(UPLOAD_TO, 'wb').close()
self.addCleanup(os.remove, UPLOAD_TO)
with self.assertRaises(IOError) as exc_info:
msg = '%s exists and is not a directory.' % UPLOAD_TO
with self.assertRaisesMessage(FileExistsError, msg):
with SimpleUploadedFile('foo.txt', b'x') as file:
self.obj.testfile.save('foo.txt', file, save=False)
# The test needs to be done on a specific string as IOError
# is raised even without the patch (just not early enough)
self.assertEqual(exc_info.exception.args[0], "%s exists and is not a directory." % UPLOAD_TO)
class MultiParserTests(SimpleTestCase):

View File

@ -355,8 +355,9 @@ class FileMoveSafeTests(unittest.TestCase):
handle_a, self.file_a = tempfile.mkstemp()
handle_b, self.file_b = tempfile.mkstemp()
# file_move_safe should raise an IOError exception if destination file exists and allow_overwrite is False
with self.assertRaises(IOError):
# file_move_safe() raises OSError if the destination file exists and
# allow_overwrite is False.
with self.assertRaises(FileExistsError):
file_move_safe(self.file_a, self.file_b, allow_overwrite=False)
# should allow it and continue on if allow_overwrite is True

View File

@ -1747,13 +1747,10 @@ class TranslationFilesMissing(SimpleTestCase):
gettext_module.find = lambda *args, **kw: None
def test_failure_finding_default_mo_files(self):
'''
Ensure IOError is raised if the default language is unparseable.
Refs: #18192
'''
"""OSError is raised if the default language is unparseable."""
self.patchGettextFind()
trans_real._translations = {}
with self.assertRaises(IOError):
with self.assertRaises(OSError):
activate('en')

View File

@ -4,7 +4,6 @@ import mimetypes
import os
import shutil
import smtpd
import socket
import sys
import tempfile
import threading
@ -1570,7 +1569,7 @@ class SMTPBackendStoppedServerTests(SMTPBackendTestsBase):
"""
A socket connection error is silenced with fail_silently=True.
"""
with self.assertRaises(socket.error):
with self.assertRaises(ConnectionError):
self.backend.open()
self.backend.fail_silently = True
self.backend.open()

View File

@ -479,11 +479,11 @@ class RequestsTests(SimpleTestCase):
def test_POST_connection_error(self):
"""
If wsgi.input.read() raises an exception while trying to read() the
POST, the exception should be identifiable (not a generic IOError).
POST, the exception is identifiable (not a generic OSError).
"""
class ExplodingBytesIO(BytesIO):
def read(self, len=0):
raise IOError("kaboom!")
raise OSError('kaboom!')
payload = b'name=value'
request = WSGIRequest({
@ -520,11 +520,11 @@ class RequestsTests(SimpleTestCase):
def test_FILES_connection_error(self):
"""
If wsgi.input.read() raises an exception while trying to read() the
FILES, the exception should be identifiable (not a generic IOError).
FILES, the exception is identifiable (not a generic OSError).
"""
class ExplodingBytesIO(BytesIO):
def read(self, len=0):
raise IOError("kaboom!")
raise OSError('kaboom!')
payload = b'x'
request = WSGIRequest({

View File

@ -22,14 +22,14 @@ class HttpResponseBaseTests(SimpleTestCase):
r = HttpResponseBase()
self.assertIs(r.writable(), False)
with self.assertRaisesMessage(IOError, 'This HttpResponseBase instance is not writable'):
with self.assertRaisesMessage(OSError, 'This HttpResponseBase instance is not writable'):
r.write('asdf')
with self.assertRaisesMessage(IOError, 'This HttpResponseBase instance is not writable'):
with self.assertRaisesMessage(OSError, 'This HttpResponseBase instance is not writable'):
r.writelines(['asdf\n', 'qwer\n'])
def test_tell(self):
r = HttpResponseBase()
with self.assertRaisesMessage(IOError, 'This HttpResponseBase instance cannot tell its position'):
with self.assertRaisesMessage(OSError, 'This HttpResponseBase instance cannot tell its position'):
r.tell()
def test_setdefault(self):

View File

@ -194,10 +194,10 @@ class LiveServerPort(LiveServerBase):
TestCase = type("TestCase", (LiveServerBase,), {})
try:
TestCase.setUpClass()
except socket.error as e:
except OSError as e:
if e.errno == errno.EADDRINUSE:
# We're out of ports, LiveServerTestCase correctly fails with
# a socket error.
# an OSError.
return
# Unexpected error.
raise

View File

@ -532,7 +532,7 @@ class FileSessionTests(SessionTestsMixin, unittest.TestCase):
def test_invalid_key_backslash(self):
# Ensure we don't allow directory-traversal.
# This is tested directly on _key_to_file, as load() will swallow
# a SuspiciousOperation in the same way as an IOError - by creating
# a SuspiciousOperation in the same way as an OSError - by creating
# a new session, making it unclear whether the slashes were detected.
with self.assertRaises(InvalidSessionKey):
self.backend()._key_to_file("a\\b\\c")

View File

@ -23,7 +23,7 @@ class BaseStaticFilesMixin:
)
def assertFileNotFound(self, filepath):
with self.assertRaises(IOError):
with self.assertRaises(OSError):
self._get_file(filepath)
def render_template(self, template, **kwargs):

View File

@ -191,11 +191,11 @@ class FileSystemLoaderTests(SimpleTestCase):
tmppath = os.path.join(tmpdir, tmpfile.name)
os.chmod(tmppath, 0o0222)
with self.set_dirs([tmpdir]):
with self.assertRaisesMessage(IOError, 'Permission denied'):
with self.assertRaisesMessage(PermissionError, 'Permission denied'):
self.engine.get_template(tmpfile.name)
def test_notafile_error(self):
with self.assertRaises(IOError):
with self.assertRaises(IsADirectoryError):
self.engine.get_template('first')