Move from python2 compliant IOError and EnvironmentError to python3-only OSError (#48764)

* IOError -> OSError

* also do EnvironmentError
This commit is contained in:
Harmen Stoppels 2025-01-30 18:32:57 +01:00 committed by GitHub
parent 6e046b04c7
commit b02dcf697d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
22 changed files with 41 additions and 47 deletions

View File

@ -668,7 +668,7 @@ def copy(src, dest, _permissions=False):
_permissions (bool): for internal use only _permissions (bool): for internal use only
Raises: Raises:
IOError: if *src* does not match any files or directories OSError: if *src* does not match any files or directories
ValueError: if *src* matches multiple files but *dest* is ValueError: if *src* matches multiple files but *dest* is
not a directory not a directory
""" """
@ -679,7 +679,7 @@ def copy(src, dest, _permissions=False):
files = glob.glob(src) files = glob.glob(src)
if not files: if not files:
raise IOError("No such file or directory: '{0}'".format(src)) raise OSError("No such file or directory: '{0}'".format(src))
if len(files) > 1 and not os.path.isdir(dest): if len(files) > 1 and not os.path.isdir(dest):
raise ValueError( raise ValueError(
"'{0}' matches multiple files but '{1}' is not a directory".format(src, dest) "'{0}' matches multiple files but '{1}' is not a directory".format(src, dest)
@ -710,7 +710,7 @@ def install(src, dest):
dest (str): the destination file or directory dest (str): the destination file or directory
Raises: Raises:
IOError: if *src* does not match any files or directories OSError: if *src* does not match any files or directories
ValueError: if *src* matches multiple files but *dest* is ValueError: if *src* matches multiple files but *dest* is
not a directory not a directory
""" """
@ -748,7 +748,7 @@ def copy_tree(
_permissions (bool): for internal use only _permissions (bool): for internal use only
Raises: Raises:
IOError: if *src* does not match any files or directories OSError: if *src* does not match any files or directories
ValueError: if *src* is a parent directory of *dest* ValueError: if *src* is a parent directory of *dest*
""" """
if _permissions: if _permissions:
@ -762,7 +762,7 @@ def copy_tree(
files = glob.glob(src) files = glob.glob(src)
if not files: if not files:
raise IOError("No such file or directory: '{0}'".format(src)) raise OSError("No such file or directory: '{0}'".format(src))
# For Windows hard-links and junctions, the source path must exist to make a symlink. Add # For Windows hard-links and junctions, the source path must exist to make a symlink. Add
# all symlinks to this list while traversing the tree, then when finished, make all # all symlinks to this list while traversing the tree, then when finished, make all
@ -843,7 +843,7 @@ def install_tree(src, dest, symlinks=True, ignore=None):
ignore (typing.Callable): function indicating which files to ignore ignore (typing.Callable): function indicating which files to ignore
Raises: Raises:
IOError: if *src* does not match any files or directories OSError: if *src* does not match any files or directories
ValueError: if *src* is a parent directory of *dest* ValueError: if *src* is a parent directory of *dest*
""" """
copy_tree(src, dest, symlinks=symlinks, ignore=ignore, _permissions=True) copy_tree(src, dest, symlinks=symlinks, ignore=ignore, _permissions=True)

View File

@ -308,7 +308,7 @@ class LinkTree:
def __init__(self, source_root): def __init__(self, source_root):
if not os.path.exists(source_root): if not os.path.exists(source_root):
raise IOError("No such file or directory: '%s'", source_root) raise OSError("No such file or directory: '%s'", source_root)
self._root = source_root self._root = source_root

View File

@ -391,7 +391,7 @@ def _poll_lock(self, op: int) -> bool:
return True return True
except IOError as e: except OSError as e:
# EAGAIN and EACCES == locked by another process (so try again) # EAGAIN and EACCES == locked by another process (so try again)
if e.errno not in (errno.EAGAIN, errno.EACCES): if e.errno not in (errno.EAGAIN, errno.EACCES):
raise raise

View File

@ -918,7 +918,7 @@ def _writer_daemon(
try: try:
if stdin_file.read(1) == "v": if stdin_file.read(1) == "v":
echo = not echo echo = not echo
except IOError as e: except OSError as e:
# If SIGTTIN is ignored, the system gives EIO # If SIGTTIN is ignored, the system gives EIO
# to let the caller know the read failed b/c it # to let the caller know the read failed b/c it
# was in the bg. Ignore that too. # was in the bg. Ignore that too.
@ -1013,7 +1013,7 @@ def wrapped(*args, **kwargs):
while True: while True:
try: try:
return function(*args, **kwargs) return function(*args, **kwargs)
except IOError as e: except OSError as e:
if e.errno == errno.EINTR: if e.errno == errno.EINTR:
continue continue
raise raise

View File

@ -110,10 +110,7 @@ def external_find(args):
# Note that KeyboardInterrupt does not subclass Exception # Note that KeyboardInterrupt does not subclass Exception
# (so CTRL-C will terminate the program as expected). # (so CTRL-C will terminate the program as expected).
skip_msg = "Skipping manifest and continuing with other external checks" skip_msg = "Skipping manifest and continuing with other external checks"
if (isinstance(e, IOError) or isinstance(e, OSError)) and e.errno in [ if isinstance(e, OSError) and e.errno in (errno.EPERM, errno.EACCES):
errno.EPERM,
errno.EACCES,
]:
# The manifest file does not have sufficient permissions enabled: # The manifest file does not have sufficient permissions enabled:
# print a warning and keep going # print a warning and keep going
tty.warn("Unable to read manifest due to insufficient permissions.", skip_msg) tty.warn("Unable to read manifest due to insufficient permissions.", skip_msg)

View File

@ -581,7 +581,7 @@ def _error_on_nonempty_view_dir(new_root):
# Check if the target path lexists # Check if the target path lexists
try: try:
st = os.lstat(new_root) st = os.lstat(new_root)
except (IOError, OSError): except OSError:
return return
# Empty directories are fine # Empty directories are fine
@ -861,7 +861,7 @@ def regenerate(self, concrete_roots: List[Spec]) -> None:
): ):
try: try:
shutil.rmtree(old_root) shutil.rmtree(old_root)
except (IOError, OSError) as e: except OSError as e:
msg = "Failed to remove old view at %s\n" % old_root msg = "Failed to remove old view at %s\n" % old_root
msg += str(e) msg += str(e)
tty.warn(msg) tty.warn(msg)
@ -2554,7 +2554,7 @@ def is_latest_format(manifest):
try: try:
with open(manifest, encoding="utf-8") as f: with open(manifest, encoding="utf-8") as f:
data = syaml.load(f) data = syaml.load(f)
except (OSError, IOError): except OSError:
return True return True
top_level_key = _top_level_key(data) top_level_key = _top_level_key(data)
changed = spack.schema.env.update(data[top_level_key]) changed = spack.schema.env.update(data[top_level_key])

View File

@ -187,7 +187,7 @@ def path_for_extension(target_name: str, *, paths: List[str]) -> str:
if name == target_name: if name == target_name:
return path return path
else: else:
raise IOError('extension "{0}" not found'.format(target_name)) raise OSError('extension "{0}" not found'.format(target_name))
def get_module(cmd_name): def get_module(cmd_name):

View File

@ -427,7 +427,7 @@ def needs_file(spec, file):
try: try:
with open(manifest_file, "r", encoding="utf-8") as f: with open(manifest_file, "r", encoding="utf-8") as f:
manifest = s_json.load(f) manifest = s_json.load(f)
except (OSError, IOError): except OSError:
# if we can't load it, assume it doesn't know about the file. # if we can't load it, assume it doesn't know about the file.
manifest = {} manifest = {}
return test_path in manifest return test_path in manifest
@ -831,7 +831,7 @@ def get_spec_from_file(filename):
try: try:
with open(filename, "r", encoding="utf-8") as f: with open(filename, "r", encoding="utf-8") as f:
return spack.spec.Spec.from_yaml(f) return spack.spec.Spec.from_yaml(f)
except IOError: except OSError:
return None return None

View File

@ -26,7 +26,7 @@ def is_shared_library_elf(filepath):
with open(filepath, "rb") as f: with open(filepath, "rb") as f:
elf = parse_elf(f, interpreter=True, dynamic_section=True) elf = parse_elf(f, interpreter=True, dynamic_section=True)
return elf.has_pt_dynamic and (elf.has_soname or not elf.has_pt_interp) return elf.has_pt_dynamic and (elf.has_soname or not elf.has_pt_interp)
except (IOError, OSError, ElfParsingError): except (OSError, ElfParsingError):
return False return False

View File

@ -166,7 +166,7 @@ def filter_shebangs_in_directory(directory, filenames=None):
# Only look at executable, non-symlink files. # Only look at executable, non-symlink files.
try: try:
st = os.lstat(path) st = os.lstat(path)
except (IOError, OSError): except OSError:
continue continue
if stat.S_ISLNK(st.st_mode) or stat.S_ISDIR(st.st_mode) or not st.st_mode & is_exe: if stat.S_ISLNK(st.st_mode) or stat.S_ISDIR(st.st_mode) or not st.st_mode & is_exe:

View File

@ -1041,7 +1041,7 @@ def _read_config(self) -> Dict[str, str]:
return yaml_data["repo"] return yaml_data["repo"]
except IOError: except OSError:
tty.die(f"Error reading {self.config_file} when opening {self.root}") tty.die(f"Error reading {self.config_file} when opening {self.root}")
def get(self, spec: "spack.spec.Spec") -> "spack.package_base.PackageBase": def get(self, spec: "spack.spec.Spec") -> "spack.package_base.PackageBase":
@ -1369,7 +1369,7 @@ def create_repo(root, namespace=None, subdir=packages_dir_name):
if subdir != packages_dir_name: if subdir != packages_dir_name:
config.write(f" subdirectory: '{subdir}'\n") config.write(f" subdirectory: '{subdir}'\n")
except (IOError, OSError) as e: except OSError as e:
# try to clean up. # try to clean up.
if existed: if existed:
shutil.rmtree(config_path, ignore_errors=True) shutil.rmtree(config_path, ignore_errors=True)

View File

@ -458,7 +458,7 @@ def test_log_install_without_build_files(install_mockery):
spec = spack.concretize.concretize_one("trivial-install-test-package") spec = spack.concretize.concretize_one("trivial-install-test-package")
# Attempt installing log without the build log file # Attempt installing log without the build log file
with pytest.raises(IOError, match="No such file or directory"): with pytest.raises(OSError, match="No such file or directory"):
spack.installer.log(spec.package) spack.installer.log(spec.package)

View File

@ -470,7 +470,7 @@ def _repoerr(repo, name):
# The call to install_tree will raise the exception since not mocking # The call to install_tree will raise the exception since not mocking
# creation of dependency package files within *install* directories. # creation of dependency package files within *install* directories.
with pytest.raises(IOError, match=path if sys.platform != "win32" else ""): with pytest.raises(OSError, match=path if sys.platform != "win32" else ""):
inst.dump_packages(spec, path) inst.dump_packages(spec, path)
# Now try the error path, which requires the mock directory structure # Now try the error path, which requires the mock directory structure

View File

@ -82,7 +82,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(IOError, match="No such file or directory"): with pytest.raises(OSError, match="No such file or directory"):
fs.copy("source/none", "dest") fs.copy("source/none", "dest")
def test_multiple_src_file_dest(self, stage): def test_multiple_src_file_dest(self, stage):
@ -139,7 +139,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(IOError, match="No such file or directory"): with pytest.raises(OSError, match="No such file or directory"):
fs.install("source/none", "dest") fs.install("source/none", "dest")
def test_multiple_src_file_dest(self, stage): def test_multiple_src_file_dest(self, stage):
@ -220,7 +220,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(IOError, match="No such file or directory"): with pytest.raises(OSError, match="No such file or directory"):
fs.copy_tree("source/none", "dest") fs.copy_tree("source/none", "dest")
def test_parent_dir(self, stage): def test_parent_dir(self, stage):
@ -301,7 +301,7 @@ def test_non_existing_src(self, stage):
"""Test using a non-existing source.""" """Test using a non-existing source."""
with fs.working_dir(str(stage)): with fs.working_dir(str(stage)):
with pytest.raises(IOError, match="No such file or directory"): with pytest.raises(OSError, match="No such file or directory"):
fs.install_tree("source/none", "dest") fs.install_tree("source/none", "dest")
def test_parent_dir(self, stage): def test_parent_dir(self, stage):

View File

@ -1339,7 +1339,7 @@ def test_poll_lock_exception(tmpdir, monkeypatch, err_num, err_msg):
"""Test poll lock exception handling.""" """Test poll lock exception handling."""
def _lockf(fd, cmd, len, start, whence): def _lockf(fd, cmd, len, start, whence):
raise IOError(err_num, err_msg) raise OSError(err_num, err_msg)
with tmpdir.as_cwd(): with tmpdir.as_cwd():
lockfile = "lockfile" lockfile = "lockfile"
@ -1351,7 +1351,7 @@ def _lockf(fd, cmd, len, start, whence):
if err_num in [errno.EAGAIN, errno.EACCES]: if err_num in [errno.EAGAIN, errno.EACCES]:
assert not lock._poll_lock(fcntl.LOCK_EX) assert not lock._poll_lock(fcntl.LOCK_EX)
else: else:
with pytest.raises(IOError, match=err_msg): with pytest.raises(OSError, match=err_msg):
lock._poll_lock(fcntl.LOCK_EX) lock._poll_lock(fcntl.LOCK_EX)
monkeypatch.undo() monkeypatch.undo()

View File

@ -238,10 +238,7 @@ def test_exclude(self, modulefile_content, module_configuration, host_architectu
assert len([x for x in content if "module load " in x]) == 1 assert len([x for x in content if "module load " in x]) == 1
# Catch "Exception" to avoid using FileNotFoundError on Python 3 with pytest.raises(FileNotFoundError):
# and IOError on Python 2 or common bases like EnvironmentError
# which are not officially documented
with pytest.raises(Exception):
modulefile_content(f"callpath target={host_architecture_str}") modulefile_content(f"callpath target={host_architecture_str}")
content = modulefile_content(f"zmpi target={host_architecture_str}") content = modulefile_content(f"zmpi target={host_architecture_str}")

View File

@ -204,13 +204,13 @@ def test_no_editor():
def assert_exec(exe, args): def assert_exec(exe, args):
assert False assert False
with pytest.raises(EnvironmentError, match=r"No text editor found.*"): with pytest.raises(OSError, match=r"No text editor found.*"):
ed.editor("/path/to/file", exec_fn=assert_exec) ed.editor("/path/to/file", exec_fn=assert_exec)
def assert_exec(exe, args): def assert_exec(exe, args):
return False return False
with pytest.raises(EnvironmentError, match=r"No text editor found.*"): with pytest.raises(OSError, match=r"No text editor found.*"):
ed.editor("/path/to/file", exec_fn=assert_exec) ed.editor("/path/to/file", exec_fn=assert_exec)
@ -220,5 +220,5 @@ def test_exec_fn_executable(editor_var, good_exe, bad_exe):
assert ed.editor(exec_fn=ed.executable) assert ed.editor(exec_fn=ed.executable)
os.environ[editor_var] = bad_exe os.environ[editor_var] = bad_exe
with pytest.raises(EnvironmentError, match=r"No text editor found.*"): with pytest.raises(OSError, match=r"No text editor found.*"):
ed.editor(exec_fn=ed.executable) ed.editor(exec_fn=ed.executable)

View File

@ -9,7 +9,7 @@
defined by the EDITOR environment variable if VISUAL is not set or the defined by the EDITOR environment variable if VISUAL is not set or the
specified editor fails (e.g. no DISPLAY for a graphical editor). If specified editor fails (e.g. no DISPLAY for a graphical editor). If
neither variable is set, we fall back to one of several common editors, neither variable is set, we fall back to one of several common editors,
raising an EnvironmentError if we are unable to find one. raising an OSError if we are unable to find one.
""" """
import os import os
import shlex import shlex
@ -141,7 +141,7 @@ def try_env_var(var):
return True return True
# Fail if nothing could be found # Fail if nothing could be found
raise EnvironmentError( raise OSError(
"No text editor found! Please set the VISUAL and/or EDITOR " "No text editor found! Please set the VISUAL and/or EDITOR "
"environment variable(s) to your preferred text editor." "environment variable(s) to your preferred text editor."
) )

View File

@ -46,7 +46,7 @@ def _process_ld_so_conf_queue(queue):
try: try:
with open(p, "rb") as f: with open(p, "rb") as f:
lines = f.readlines() lines = f.readlines()
except (IOError, OSError): except OSError:
continue continue
for line in lines: for line in lines:
@ -132,7 +132,7 @@ def host_dynamic_linker_search_paths():
if os.path.exists(possible_conf): if os.path.exists(possible_conf):
conf_file = possible_conf conf_file = possible_conf
except (IOError, OSError, elf_utils.ElfParsingError): except (OSError, elf_utils.ElfParsingError):
pass pass
# Note: ld_so_conf doesn't error if the file does not exist. # Note: ld_so_conf doesn't error if the file does not exist.

View File

@ -396,7 +396,7 @@ def install(self, spec, prefix):
copy(filepath, tmppath) copy(filepath, tmppath)
os.remove(filepath) os.remove(filepath)
os.rename(tmppath, filepath) os.rename(tmppath, filepath)
except (IOError, OSError): except OSError:
pass pass
tmp_path = join_path(builddir, "tmp") tmp_path = join_path(builddir, "tmp")

View File

@ -763,8 +763,8 @@ def edit(self, pkg, spec, prefix):
"Point environment variable LIBSMM_PATH to " "Point environment variable LIBSMM_PATH to "
"the absolute path of the libsmm.a file" "the absolute path of the libsmm.a file"
) )
except IOError: except OSError:
raise IOError( raise OSError(
"The file LIBSMM_PATH pointed to does not " "The file LIBSMM_PATH pointed to does not "
"exist. Note that it must be absolute path." "exist. Note that it must be absolute path."
) )

View File

@ -331,7 +331,7 @@ def do_stage(self, mirror_only=False):
try: try:
perm = os.stat(filename).st_mode perm = os.stat(filename).st_mode
os.chmod(filename, perm | 0o200) os.chmod(filename, perm | 0o200)
except IOError: except OSError:
continue continue
def nmake_arguments(self): def nmake_arguments(self):