mirror of https://github.com/pypa/pip
Use unified OSError and its subclasses
Since Python 3.3, the following classes have merged into OSError. They remain as aliases for backward compatibility. - EnvironmentError - IOError - WindowsError https://docs.python.org/3/library/exceptions.html#OSError Python 3 also has subclasses of OSError to help identify more specific errors. For example, FileNotFoundError. This allows simplifying some except blocks.
This commit is contained in:
parent
2fb341aac7
commit
d282fb94a3
|
@ -29,13 +29,6 @@ per-file-ignores =
|
|||
noxfile.py: G
|
||||
# B011: Do not call assert False since python -O removes these calls
|
||||
tests/*: B011
|
||||
# TODO: Remove IOError from except (OSError, IOError) blocks in
|
||||
# these files when Python 2 is removed.
|
||||
# In Python 3, IOError have been merged into OSError
|
||||
# https://github.com/PyCQA/flake8-bugbear/issues/110
|
||||
src/pip/_internal/utils/filesystem.py: B014
|
||||
src/pip/_internal/network/cache.py: B014
|
||||
src/pip/_internal/utils/misc.py: B014
|
||||
|
||||
[mypy]
|
||||
follow_imports = silent
|
||||
|
|
|
@ -435,10 +435,10 @@ class InstallCommand(RequirementCommand):
|
|||
write_output(
|
||||
'Successfully installed %s', installed_desc,
|
||||
)
|
||||
except EnvironmentError as error:
|
||||
except OSError as error:
|
||||
show_traceback = (self.verbosity >= 1)
|
||||
|
||||
message = create_env_error_message(
|
||||
message = create_os_error_message(
|
||||
error, show_traceback, options.use_user_site,
|
||||
)
|
||||
logger.error(message, exc_info=show_traceback) # noqa
|
||||
|
@ -697,16 +697,16 @@ def reject_location_related_install_options(requirements, options):
|
|||
)
|
||||
|
||||
|
||||
def create_env_error_message(error, show_traceback, using_user_site):
|
||||
# type: (EnvironmentError, bool, bool) -> str
|
||||
"""Format an error message for an EnvironmentError
|
||||
def create_os_error_message(error, show_traceback, using_user_site):
|
||||
# type: (OSError, bool, bool) -> str
|
||||
"""Format an error message for an OSError
|
||||
|
||||
It may occur anytime during the execution of the install command.
|
||||
"""
|
||||
parts = []
|
||||
|
||||
# Mention the error if we are not going to show a traceback
|
||||
parts.append("Could not install packages due to an EnvironmentError")
|
||||
parts.append("Could not install packages due to an OSError")
|
||||
if not show_traceback:
|
||||
parts.append(": ")
|
||||
parts.append(str(error))
|
||||
|
|
|
@ -29,7 +29,7 @@ def suppressed_cache_errors():
|
|||
"""
|
||||
try:
|
||||
yield
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -553,7 +553,7 @@ def get_file_content(url, session):
|
|||
try:
|
||||
with open(url, 'rb') as f:
|
||||
content = auto_decode(f.read())
|
||||
except IOError as exc:
|
||||
except OSError as exc:
|
||||
raise InstallationError(
|
||||
f'Could not open requirements file: {exc}'
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import contextlib
|
||||
import errno
|
||||
import hashlib
|
||||
import logging
|
||||
import os
|
||||
|
@ -103,10 +102,8 @@ class RequirementTracker:
|
|||
try:
|
||||
with open(entry_path) as fp:
|
||||
contents = fp.read()
|
||||
except IOError as e:
|
||||
# if the error is anything other than "file does not exist", raise.
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
except FileNotFoundError:
|
||||
pass
|
||||
else:
|
||||
message = '{} is already being built: {}'.format(
|
||||
req.link, contents)
|
||||
|
|
|
@ -50,7 +50,7 @@ class SelfCheckState:
|
|||
try:
|
||||
with open(self.statefile_path) as statefile:
|
||||
self.state = json.load(statefile)
|
||||
except (IOError, ValueError, KeyError):
|
||||
except (OSError, ValueError, KeyError):
|
||||
# Explicitly suppressing exceptions, since we don't want to
|
||||
# error out if the cache file is invalid.
|
||||
pass
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import errno
|
||||
import fnmatch
|
||||
import os
|
||||
import os.path
|
||||
|
@ -64,7 +63,7 @@ def copy2_fixed(src, dest):
|
|||
"""
|
||||
try:
|
||||
shutil.copy2(src, dest)
|
||||
except (OSError, IOError):
|
||||
except OSError:
|
||||
for f in [src, dest]:
|
||||
try:
|
||||
is_socket_file = is_socket(f)
|
||||
|
@ -148,27 +147,22 @@ def _test_writable_dir_win(path):
|
|||
file = os.path.join(path, name)
|
||||
try:
|
||||
fd = os.open(file, os.O_RDWR | os.O_CREAT | os.O_EXCL)
|
||||
# Python 2 doesn't support FileExistsError and PermissionError.
|
||||
except OSError as e:
|
||||
# exception FileExistsError
|
||||
if e.errno == errno.EEXIST:
|
||||
continue
|
||||
# exception PermissionError
|
||||
if e.errno == errno.EPERM or e.errno == errno.EACCES:
|
||||
# This could be because there's a directory with the same name.
|
||||
# But it's highly unlikely there's a directory called that,
|
||||
# so we'll assume it's because the parent dir is not writable.
|
||||
# This could as well be because the parent dir is not readable,
|
||||
# due to non-privileged user access.
|
||||
return False
|
||||
raise
|
||||
except FileExistsError:
|
||||
pass
|
||||
except PermissionError:
|
||||
# This could be because there's a directory with the same name.
|
||||
# But it's highly unlikely there's a directory called that,
|
||||
# so we'll assume it's because the parent dir is not writable.
|
||||
# This could as well be because the parent dir is not readable,
|
||||
# due to non-privileged user access.
|
||||
return False
|
||||
else:
|
||||
os.close(fd)
|
||||
os.unlink(file)
|
||||
return True
|
||||
|
||||
# This should never be reached
|
||||
raise EnvironmentError(
|
||||
raise OSError(
|
||||
'Unexpected condition testing for writable directory'
|
||||
)
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ def rmtree_errorhandler(func, path, exc_info):
|
|||
read-only attribute, and hopefully continue without problems."""
|
||||
try:
|
||||
has_attr_readonly = not (os.stat(path).st_mode & stat.S_IWRITE)
|
||||
except (IOError, OSError):
|
||||
except OSError:
|
||||
# it's equivalent to os.path.exists
|
||||
return
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ def _get_pyvenv_cfg_lines():
|
|||
# writes with UTF-8. (pypa/pip#8717)
|
||||
with open(pyvenv_cfg_file, encoding='utf-8') as f:
|
||||
return f.read().splitlines() # avoids trailing newlines
|
||||
except IOError:
|
||||
except OSError:
|
||||
return None
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Handles all VCS (version control) support"""
|
||||
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
@ -772,16 +771,13 @@ class VersionControl:
|
|||
extra_environ=extra_environ,
|
||||
extra_ok_returncodes=extra_ok_returncodes,
|
||||
log_failed_cmd=log_failed_cmd)
|
||||
except OSError as e:
|
||||
except FileNotFoundError:
|
||||
# errno.ENOENT = no such file or directory
|
||||
# In other words, the VCS executable isn't available
|
||||
if e.errno == errno.ENOENT:
|
||||
raise BadCommand(
|
||||
'Cannot find command {cls.name!r} - do you have '
|
||||
'{cls.name!r} installed and in your '
|
||||
'PATH?'.format(**locals()))
|
||||
else:
|
||||
raise # re-raise exception if a different error occurred
|
||||
raise BadCommand(
|
||||
'Cannot find command {cls.name!r} - do you have '
|
||||
'{cls.name!r} installed and in your '
|
||||
'PATH?'.format(**locals()))
|
||||
|
||||
@classmethod
|
||||
def is_repository_directory(cls, path):
|
||||
|
|
|
@ -5,7 +5,7 @@ from mock import patch
|
|||
from pip._vendor.packaging.requirements import Requirement
|
||||
|
||||
from pip._internal.commands.install import (
|
||||
create_env_error_message,
|
||||
create_os_error_message,
|
||||
decide_user_install,
|
||||
reject_location_related_install_options,
|
||||
)
|
||||
|
@ -81,35 +81,35 @@ def test_rejection_for_location_requirement_options():
|
|||
|
||||
@pytest.mark.parametrize('error, show_traceback, using_user_site, expected', [
|
||||
# show_traceback = True, using_user_site = True
|
||||
(EnvironmentError("Illegal byte sequence"), True, True, 'Could not install'
|
||||
' packages due to an EnvironmentError.\n'),
|
||||
(EnvironmentError(errno.EACCES, "No file permission"), True, True, 'Could'
|
||||
' not install packages due to an EnvironmentError.\nCheck the'
|
||||
(OSError("Illegal byte sequence"), True, True, 'Could not install'
|
||||
' packages due to an OSError.\n'),
|
||||
(OSError(errno.EACCES, "No file permission"), True, True, 'Could'
|
||||
' not install packages due to an OSError.\nCheck the'
|
||||
' permissions.\n'),
|
||||
# show_traceback = True, using_user_site = False
|
||||
(EnvironmentError("Illegal byte sequence"), True, False, 'Could not'
|
||||
' install packages due to an EnvironmentError.\n'),
|
||||
(EnvironmentError(errno.EACCES, "No file permission"), True, False, 'Could'
|
||||
' not install packages due to an EnvironmentError.\nConsider using the'
|
||||
(OSError("Illegal byte sequence"), True, False, 'Could not'
|
||||
' install packages due to an OSError.\n'),
|
||||
(OSError(errno.EACCES, "No file permission"), True, False, 'Could'
|
||||
' not install packages due to an OSError.\nConsider using the'
|
||||
' `--user` option or check the permissions.\n'),
|
||||
# show_traceback = False, using_user_site = True
|
||||
(EnvironmentError("Illegal byte sequence"), False, True, 'Could not'
|
||||
' install packages due to an EnvironmentError: Illegal byte'
|
||||
(OSError("Illegal byte sequence"), False, True, 'Could not'
|
||||
' install packages due to an OSError: Illegal byte'
|
||||
' sequence\n'),
|
||||
(EnvironmentError(errno.EACCES, "No file permission"), False, True, 'Could'
|
||||
' not install packages due to an EnvironmentError: [Errno 13] No file'
|
||||
(OSError(errno.EACCES, "No file permission"), False, True, 'Could'
|
||||
' not install packages due to an OSError: [Errno 13] No file'
|
||||
' permission\nCheck the permissions.\n'),
|
||||
# show_traceback = False, using_user_site = False
|
||||
(EnvironmentError("Illegal byte sequence"), False, False, 'Could not'
|
||||
' install packages due to an EnvironmentError: Illegal byte sequence'
|
||||
(OSError("Illegal byte sequence"), False, False, 'Could not'
|
||||
' install packages due to an OSError: Illegal byte sequence'
|
||||
'\n'),
|
||||
(EnvironmentError(errno.EACCES, "No file permission"), False, False,
|
||||
'Could not install packages due to an EnvironmentError: [Errno 13] No'
|
||||
(OSError(errno.EACCES, "No file permission"), False, False,
|
||||
'Could not install packages due to an OSError: [Errno 13] No'
|
||||
' file permission\nConsider using the `--user` option or check the'
|
||||
' permissions.\n'),
|
||||
])
|
||||
def test_create_env_error_message(
|
||||
def test_create_os_error_message(
|
||||
error, show_traceback, using_user_site, expected
|
||||
):
|
||||
msg = create_env_error_message(error, show_traceback, using_user_site)
|
||||
msg = create_os_error_message(error, show_traceback, using_user_site)
|
||||
assert msg == expected
|
||||
|
|
Loading…
Reference in New Issue