Compare commits

...

6 Commits

Author SHA1 Message Date
Todd Gamblin
6b38f2203d
WIP 2023-02-23 12:18:10 -08:00
Todd Gamblin
457ea43e95
windows: use sys.platform == "win32" instead of is_windows
`mypy` only understands `sys.platform == "win32"`, not indirect assignments of that
value to things like `is_windows`. If we don't use the accepted platform checks, `mypy`
registers many Windows-only symbols as not present on Linux, when it should skip the
checks for platform-specific code.
2023-02-23 12:18:10 -08:00
Todd Gamblin
d1bb19e2c7
clean up kwargs and attribute issues in llnl.util.tty 2023-02-23 12:18:10 -08:00
Todd Gamblin
7238ab94f5
unparser: Ignore type errors for Python-2-only constructs 2023-02-23 12:18:10 -08:00
Todd Gamblin
af3a165a20
fix bug in ColorStream 2023-02-23 12:18:10 -08:00
Todd Gamblin
94b4a0f317
enable check_untyped_defs in pyproject.toml 2023-02-23 12:18:09 -08:00
36 changed files with 144 additions and 201 deletions

View File

@ -16,7 +16,6 @@
import sys
import tempfile
from contextlib import contextmanager
from sys import platform as _platform
from typing import Callable, List, Match, Optional, Tuple, Union
from llnl.util import tty
@ -26,9 +25,7 @@
from spack.util.executable import Executable, which
from spack.util.path import path_to_os_path, system_path_filter
is_windows = _platform == "win32"
if not is_windows:
if sys.platform != "win32":
import grp
import pwd
else:
@ -154,7 +151,7 @@ def lookup(name):
def getuid():
if is_windows:
if sys.platform == "win32":
import ctypes
if ctypes.windll.shell32.IsUserAnAdmin() == 0:
@ -167,7 +164,7 @@ def getuid():
@system_path_filter
def rename(src, dst):
# On Windows, os.rename will fail if the destination file already exists
if is_windows:
if sys.platform == "win32":
# Windows path existence checks will sometimes fail on junctions/links/symlinks
# so check for that case
if os.path.exists(dst) or os.path.islink(dst):
@ -196,7 +193,7 @@ def _get_mime_type():
"""Generate method to call `file` system command to aquire mime type
for a specified path
"""
if is_windows:
if sys.platform == "win32":
# -h option (no-dereference) does not exist in Windows
return file_command("-b", "--mime-type")
else:
@ -551,7 +548,7 @@ def get_owner_uid(path, err_msg=None):
else:
p_stat = os.stat(path)
if _platform != "win32":
if sys.platform != "win32":
owner_uid = p_stat.st_uid
else:
sid = win32security.GetFileSecurity(
@ -584,7 +581,7 @@ def group_ids(uid=None):
Returns:
(list of int): gids of groups the user is a member of
"""
if is_windows:
if sys.platform == "win32":
tty.warn("Function is not supported on Windows")
return []
@ -604,7 +601,7 @@ def group_ids(uid=None):
@system_path_filter(arg_slice=slice(1))
def chgrp(path, group, follow_symlinks=True):
"""Implement the bash chgrp function on a single path"""
if is_windows:
if sys.platform == "win32":
raise OSError("Function 'chgrp' is not supported on Windows")
if isinstance(group, str):
@ -1131,7 +1128,7 @@ def open_if_filename(str_or_file, mode="r"):
@system_path_filter
def touch(path):
"""Creates an empty file at the specified path."""
if is_windows:
if sys.platform == "win32":
perms = os.O_WRONLY | os.O_CREAT
else:
perms = os.O_WRONLY | os.O_CREAT | os.O_NONBLOCK | os.O_NOCTTY
@ -1193,7 +1190,7 @@ def temp_cwd():
yield tmp_dir
finally:
kwargs = {}
if is_windows:
if sys.platform == "win32":
kwargs["ignore_errors"] = False
kwargs["onerror"] = readonly_file_handler(ignore_errors=True)
shutil.rmtree(tmp_dir, **kwargs)
@ -1438,7 +1435,7 @@ def visit_directory_tree(root, visitor, rel_path="", depth=0):
try:
isdir = f.is_dir()
except OSError as e:
if is_windows and hasattr(e, "winerror") and e.winerror == 5 and islink:
if sys.platform == "win32" and hasattr(e, "winerror") and e.winerror == 5 and islink:
# if path is a symlink, determine destination and
# evaluate file vs directory
link_target = resolve_link_target_relative_to_the_link(f)
@ -1547,11 +1544,11 @@ def readonly_file_handler(ignore_errors=False):
"""
def error_remove_readonly(func, path, exc):
if not is_windows:
if sys.platform != "win32":
raise RuntimeError("This method should only be invoked on Windows")
excvalue = exc[1]
if (
is_windows
sys.platform == "win32"
and func in (os.rmdir, os.remove, os.unlink)
and excvalue.errno == errno.EACCES
):
@ -1581,7 +1578,7 @@ def remove_linked_tree(path):
# Windows readonly files cannot be removed by Python
# directly.
if is_windows:
if sys.platform == "win32":
kwargs["ignore_errors"] = False
kwargs["onerror"] = readonly_file_handler(ignore_errors=True)
@ -2095,7 +2092,7 @@ def names(self):
# on non Windows platform
# Windows valid library extensions are:
# ['.dll', '.lib']
valid_exts = [".dll", ".lib"] if is_windows else [".dylib", ".so", ".a"]
valid_exts = [".dll", ".lib"] if sys.platform == "win32" else [".dylib", ".so", ".a"]
for ext in valid_exts:
i = name.rfind(ext)
if i != -1:
@ -2243,7 +2240,7 @@ def find_libraries(libraries, root, shared=True, recursive=False, runtime=True):
message = message.format(find_libraries.__name__, type(libraries))
raise TypeError(message)
if is_windows:
if sys.platform == "win32":
static_ext = "lib"
# For linking (runtime=False) you need the .lib files regardless of
# whether you are doing a shared or static link
@ -2275,7 +2272,7 @@ def find_libraries(libraries, root, shared=True, recursive=False, runtime=True):
# finally search all of root recursively. The search stops when the first
# match is found.
common_lib_dirs = ["lib", "lib64"]
if is_windows:
if sys.platform == "win32":
common_lib_dirs.extend(["bin", "Lib"])
for subdir in common_lib_dirs:
@ -2410,7 +2407,7 @@ def _link(self, path, dest_dir):
# For py2 compatibility, we have to catch the specific Windows error code
# associate with trying to create a file that already exists (winerror 183)
except OSError as e:
if e.winerror == 183:
if sys.platform == "win32" and e.winerror == 183:
# We have either already symlinked or we are encoutering a naming clash
# either way, we don't want to overwrite existing libraries
already_linked = islink(dest_file)

View File

@ -3,12 +3,14 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
import contextlib
import errno
import os
import socket
import sys
import time
from datetime import datetime
from typing import Callable, Optional, Union
import llnl.util.tty as tty
from llnl.util.lang import pretty_seconds
@ -546,11 +548,11 @@ def upgrade_read_to_write(self, timeout=None):
else:
raise LockUpgradeError(self.path)
def release_read(self, release_fn=None):
def release_read(self, release_fn: Callable = None):
"""Releases a read lock.
Arguments:
release_fn (typing.Callable): function to call *before* the last recursive
release_fn (Callable): function to call *before* the last recursive
lock (read or write) is released.
If the last recursive lock will be released, then this will call
@ -586,7 +588,7 @@ def release_write(self, release_fn=None):
"""Releases a write lock.
Arguments:
release_fn (typing.Callable): function to call before the last recursive
release_fn (Callable): function to call before the last recursive
write is released.
If the last recursive *write* lock will be released, then this
@ -684,18 +686,6 @@ def _status_msg(self, locktype, status):
class LockTransaction(object):
"""Simple nested transaction context manager that uses a file lock.
Arguments:
lock (Lock): underlying lock for this transaction to be accquired on
enter and released on exit
acquire (typing.Callable or contextlib.contextmanager): function to be called
after lock is acquired, or contextmanager to enter after acquire and leave
before release.
release (typing.Callable): function to be called before release. If
``acquire`` is a contextmanager, this will be called *after*
exiting the nexted context and before the lock is released.
timeout (float): number of seconds to set for the timeout when
accquiring the lock (default no timeout)
If the ``acquire_fn`` returns a value, it is used as the return value for
``__enter__``, allowing it to be passed as the ``as`` argument of a
``with`` statement.
@ -709,7 +699,27 @@ class LockTransaction(object):
"""
def __init__(self, lock, acquire=None, release=None, timeout=None):
def __init__(
self,
lock: Lock,
acquire: Optional[Union[Callable, contextlib.contextmanager]] = None,
release: Optional[Callable] = None,
timeout: Optional[float] = None,
):
"""
Arguments:
lock: underlying lock for this transaction to be accquired on
enter and released on exit
acquire: function to be called
after lock is acquired, or contextmanager to enter after acquire and leave
before release.
release: function to be called before release. If
``acquire`` is a contextmanager, this will be called *after*
exiting the nexted context and before the lock is released.
timeout: number of seconds to set for the timeout when
accquiring the lock (default no timeout)
"""
self._lock = lock
self._timeout = timeout
self._acquire_fn = acquire

View File

@ -5,15 +5,13 @@
import errno
import os
import shutil
import sys
import tempfile
from os.path import exists, join
from sys import platform as _platform
from llnl.util import lang
is_windows = _platform == "win32"
if is_windows:
if sys.platform == "win32":
from win32file import CreateHardLink
@ -23,7 +21,7 @@ def symlink(real_path, link_path):
On Windows, use junctions if os.symlink fails.
"""
if not is_windows:
if sys.platform != "win32":
os.symlink(real_path, link_path)
elif _win32_can_symlink():
# Windows requires target_is_directory=True when the target is a dir.
@ -99,7 +97,7 @@ def _win32_is_junction(path):
if os.path.islink(path):
return False
if is_windows:
if sys.platform == "win32":
import ctypes.wintypes
GetFileAttributes = ctypes.windll.kernel32.GetFileAttributesW

View File

@ -14,6 +14,7 @@
import traceback
from datetime import datetime
from sys import platform as _platform
from typing import Optional
if _platform != "win32":
import fcntl
@ -163,14 +164,13 @@ def get_timestamp(force=False):
return ""
def msg(message, *args, **kwargs):
def msg(message, *args, newline=True):
if not msg_enabled():
return
if isinstance(message, Exception):
message = "%s: %s" % (message.__class__.__name__, str(message))
newline = kwargs.get("newline", True)
st_text = ""
if _stacktrace:
st_text = process_stacktrace(2)
@ -182,19 +182,18 @@ def msg(message, *args, **kwargs):
print(indent + _output_filter(str(arg)))
def info(message, *args, **kwargs):
def info(
message, *args, format="*b", stream=None, wrap=False, break_long_words=False, countback=3
):
if isinstance(message, Exception):
message = "%s: %s" % (message.__class__.__name__, str(message))
format = kwargs.get("format", "*b")
stream = kwargs.get("stream", sys.stdout)
wrap = kwargs.get("wrap", False)
break_long_words = kwargs.get("break_long_words", False)
st_countback = kwargs.get("countback", 3)
if stream is None:
stream = sys.stdout
st_text = ""
if _stacktrace:
st_text = process_stacktrace(st_countback)
st_text = process_stacktrace(countback)
cprint(
"@%s{%s==>} %s%s"
% (format, st_text, get_timestamp(), cescape(_output_filter(str(message)))),
@ -252,10 +251,7 @@ def die(message, *args, **kwargs):
sys.exit(1)
def get_number(prompt, **kwargs):
default = kwargs.get("default", None)
abort = kwargs.get("abort", None)
def get_number(prompt, default=None, abort=None):
if default is not None and abort is not None:
prompt += " (default is %s, %s to abort) " % (default, abort)
elif default is not None:
@ -283,14 +279,12 @@ def get_number(prompt, **kwargs):
return number
def get_yes_or_no(prompt, **kwargs):
default_value = kwargs.get("default", None)
if default_value is None:
def get_yes_or_no(prompt, default: Optional[bool] = None):
if default is None:
prompt += " [y/n] "
elif default_value is True:
elif default is True:
prompt += " [Y/n] "
elif default_value is False:
elif default is False:
prompt += " [y/N] "
else:
raise ValueError("default for get_yes_no() must be True, False, or None.")
@ -300,7 +294,7 @@ def get_yes_or_no(prompt, **kwargs):
msg(prompt, newline=False)
ans = input().lower()
if not ans:
result = default_value
result = default
if result is None:
print("Please enter yes or no.")
else:
@ -311,20 +305,13 @@ def get_yes_or_no(prompt, **kwargs):
return result
def hline(label=None, **kwargs):
def hline(label=None, char="-", max_width=64):
"""Draw a labeled horizontal line.
Keyword Arguments:
char (str): Char to draw the line with. Default '-'
max_width (int): Maximum width of the line. Default is 64 chars.
"""
char = kwargs.pop("char", "-")
max_width = kwargs.pop("max_width", 64)
if kwargs:
raise TypeError(
"'%s' is an invalid keyword argument for this function." % next(kwargs.iterkeys())
)
rows, cols = terminal_size()
if not cols:
cols = max_width

View File

@ -326,8 +326,7 @@ def __init__(self, stream, color=None):
self._stream = stream
self._color = color
def write(self, string, **kwargs):
raw = kwargs.get("raw", False)
def write(self, string, raw=False):
raw_write = getattr(self._stream, "write")
color = self._color
@ -338,7 +337,6 @@ def write(self, string, **kwargs):
color = get_color_when()
raw_write(colorize(string, color=color))
def writelines(self, sequence, **kwargs):
raw = kwargs.get("raw", False)
def writelines(self, sequence, raw=False):
for string in sequence:
self.write(string, self.color, raw=raw)
self.write(string, raw=raw)

View File

@ -26,7 +26,6 @@
description = "run spack's unit tests (wrapper around pytest)"
section = "developer"
level = "long"
is_windows = sys.platform == "win32"
def setup_parser(subparser):
@ -212,7 +211,7 @@ def unit_test(parser, args, unknown_args):
# mock configuration used by unit tests
# Note: skip on windows here because for the moment,
# clingo is wholly unsupported from bootstrap
if not is_windows:
if sys.platform != "win32":
with spack.bootstrap.ensure_bootstrap_configuration():
spack.bootstrap.ensure_core_dependencies()
if pytest is None:

View File

@ -28,8 +28,6 @@
__all__ = ["Compiler"]
is_windows = sys.platform == "win32"
@llnl.util.lang.memoized
def _get_compiler_version_output(compiler_path, version_arg, ignore_errors=()):
@ -598,7 +596,7 @@ def search_regexps(cls, language):
suffixes = [""]
# Windows compilers generally have an extension of some sort
# as do most files on Windows, handle that case here
if is_windows:
if sys.platform == "win32":
ext = r"\.(?:exe|bat)"
cls_suf = [suf + ext for suf in cls.suffixes]
ext_suf = [ext]

View File

@ -29,7 +29,6 @@
import spack.util.spack_yaml
import spack.util.windows_registry
is_windows = sys.platform == "win32"
#: Information on a package that has been detected
DetectedPackage = collections.namedtuple("DetectedPackage", ["spec", "prefix"])
@ -184,7 +183,7 @@ def library_prefix(library_dir):
elif "lib" in lowered_components:
idx = lowered_components.index("lib")
return os.sep.join(components[:idx])
elif is_windows and "bin" in lowered_components:
elif sys.platform == "win32" and "bin" in lowered_components:
idx = lowered_components.index("bin")
return os.sep.join(components[:idx])
else:
@ -260,13 +259,13 @@ def find_windows_compiler_bundled_packages():
class WindowsKitExternalPaths(object):
if is_windows:
if sys.platform == "win32":
plat_major_ver = str(winOs.windows_version()[0])
@staticmethod
def find_windows_kit_roots():
"""Return Windows kit root, typically %programfiles%\\Windows Kits\\10|11\\"""
if not is_windows:
if sys.platform != "win32":
return []
program_files = os.environ["PROGRAMFILES(x86)"]
kit_base = os.path.join(
@ -359,7 +358,7 @@ def compute_windows_program_path_for_package(pkg):
pkg (spack.package_base.PackageBase): package for which
Program Files location is to be computed
"""
if not is_windows:
if sys.platform != "win32":
return []
# note windows paths are fine here as this method should only ever be invoked
# to interact with Windows
@ -379,7 +378,7 @@ def compute_windows_user_path_for_package(pkg):
installs see:
https://learn.microsoft.com/en-us/dotnet/api/system.environment.specialfolder?view=netframework-4.8
"""
if not is_windows:
if sys.platform != "win32":
return []
# Current user directory

View File

@ -31,8 +31,6 @@
path_to_dict,
)
is_windows = sys.platform == "win32"
def common_windows_package_paths():
paths = WindowsCompilerExternalPaths.find_windows_compiler_bundled_packages()
@ -57,7 +55,7 @@ def executables_in_path(path_hints):
path_hints (list): list of paths to be searched. If None the list will be
constructed based on the PATH environment variable.
"""
if is_windows:
if sys.platform == "win32":
path_hints.extend(common_windows_package_paths())
search_paths = llnl.util.filesystem.search_paths_for_executables(*path_hints)
return path_to_dict(search_paths)
@ -149,7 +147,7 @@ def by_library(packages_to_check, path_hints=None):
path_to_lib_name = (
libraries_in_ld_and_system_library_path(path_hints=path_hints)
if not is_windows
if sys.platform != "win32"
else libraries_in_windows_paths(path_hints)
)

View File

@ -21,7 +21,6 @@
import spack.util.spack_json as sjson
from spack.error import SpackError
is_windows = sys.platform == "win32"
# Note: Posixpath is used here as opposed to
# os.path.join due to spack.spec.Spec.format
# requiring forward slash path seperators at this stage
@ -346,7 +345,7 @@ def remove_install_directory(self, spec, deprecated=False):
# Windows readonly files cannot be removed by Python
# directly, change permissions before attempting to remove
if is_windows:
if sys.platform == "win32":
kwargs = {
"ignore_errors": False,
"onerror": fs.readonly_file_handler(ignore_errors=False),

View File

@ -28,7 +28,6 @@
import os.path
import re
import shutil
import sys
import urllib.parse
from typing import List, Optional
@ -53,7 +52,6 @@
#: List of all fetch strategies, created by FetchStrategy metaclass.
all_strategies = []
is_windows = sys.platform == "win32"
CONTENT_TYPE_MISMATCH_WARNING_TEMPLATE = (
"The contents of {subject} look like {content_type}. Either the URL"

View File

@ -30,8 +30,7 @@
#: Groupdb does not exist on Windows, prevent imports
#: on supported systems
is_windows = sys.platform == "win32"
if not is_windows:
if sys.platform != "win32":
import grp
#: Spack itself also limits the shebang line to at most 4KB, which should be plenty.

View File

@ -84,9 +84,6 @@
#: queue invariants).
STATUS_REMOVED = "removed"
is_windows = sys.platform == "win32"
is_osx = sys.platform == "darwin"
class InstallAction(object):
#: Don't perform an install
@ -169,9 +166,9 @@ def _do_fake_install(pkg):
if not pkg.name.startswith("lib"):
library = "lib" + library
plat_shared = ".dll" if is_windows else ".so"
plat_static = ".lib" if is_windows else ".a"
dso_suffix = ".dylib" if is_osx else plat_shared
plat_shared = ".dll" if sys.platform == "win32" else ".so"
plat_static = ".lib" if sys.platform == "win32" else ".a"
dso_suffix = ".dylib" if sys.platform == "darwin" else plat_shared
# Install fake command
fs.mkdirp(pkg.prefix.bin)

View File

@ -92,9 +92,6 @@
_spack_configure_argsfile = "spack-configure-args.txt"
is_windows = sys.platform == "win32"
def deprecated_version(pkg, version):
"""Return True if the version is deprecated, False otherwise.
@ -165,7 +162,7 @@ def windows_establish_runtime_linkage(self):
Performs symlinking to incorporate rpath dependencies to Windows runtime search paths
"""
if is_windows:
if sys.platform == "win32":
self.win_rpath.add_library_dependent(*self.win_add_library_dependent())
self.win_rpath.add_rpath(*self.win_add_rpath())
self.win_rpath.establish_link()
@ -210,7 +207,7 @@ def to_windows_exe(exe):
plat_exe = []
if hasattr(cls, "executables"):
for exe in cls.executables:
if is_windows:
if sys.platform == "win32":
exe = to_windows_exe(exe)
plat_exe.append(exe)
return plat_exe
@ -2401,7 +2398,7 @@ def rpath(self):
# on Windows, libraries of runtime interest are typically
# stored in the bin directory
if is_windows:
if sys.platform == "win32":
rpaths = [self.prefix.bin]
rpaths.extend(d.prefix.bin for d in deps if os.path.isdir(d.prefix.bin))
else:

View File

@ -54,7 +54,6 @@
import itertools
import os
import re
import sys
import warnings
from typing import Tuple
@ -118,7 +117,6 @@
"SpecDeprecatedError",
]
is_windows = sys.platform == "win32"
#: Valid pattern for an identifier in Spack
identifier_re = r"\w[\w-]*"

View File

@ -16,8 +16,6 @@
from spack.main import SpackCommand
from spack.spec import Spec
is_windows = sys.platform == "win32"
@pytest.fixture
def executables_found(monkeypatch):
@ -39,7 +37,7 @@ def _win_exe_ext():
def define_plat_exe(exe):
if is_windows:
if sys.platform == "win32":
exe += ".bat"
return exe

View File

@ -7,7 +7,6 @@
from spack.main import SpackCommand
is_windows = sys.platform == "win32"
resource = SpackCommand("resource")
#: these are hashes used in mock packages
@ -23,7 +22,7 @@
"bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c",
"7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730",
]
if not is_windows
if sys.platform != "win32"
else [
"abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234",
"1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd",
@ -68,7 +67,7 @@ def test_resource_list_only_hashes(mock_packages, capfd):
def test_resource_show(mock_packages, capfd):
test_hash = (
"c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8"
if not is_windows
if sys.platform != "win32"
else "3c5b65abcd6a3b2c714dbf7c31ff65fe3748a1adc371f030c283007ca5534f11"
)
with capfd.disabled():

View File

@ -14,8 +14,6 @@
import spack.extensions
import spack.main
is_windows = sys.platform == "win32"
class Extension:
"""Helper class to simplify the creation of simple command extension
@ -274,7 +272,7 @@ def test_variable_in_extension_path(config, working_env):
os.environ["_MY_VAR"] = os.path.join("my", "var")
ext_paths = [os.path.join("~", "${_MY_VAR}", "spack-extension-1")]
# Home env variable is USERPROFILE on Windows
home_env = "USERPROFILE" if is_windows else "HOME"
home_env = "USERPROFILE" if sys.platform == "win32" else "HOME"
expected_ext_paths = [
os.path.join(os.environ[home_env], os.environ["_MY_VAR"], "spack-extension-1")
]

View File

@ -25,8 +25,6 @@
from spack.spec import Spec
from spack.version import ver
is_windows = sys.platform == "win32"
def check_spec(abstract, concrete):
if abstract.versions.concrete:
@ -1138,7 +1136,7 @@ def test_custom_compiler_version(self):
def test_all_patches_applied(self):
uuidpatch = (
"a60a42b73e03f207433c5579de207c6ed61d58e4d12dd3b5142eb525728d89ea"
if not is_windows
if sys.platform != "win32"
else "d0df7988457ec999c148a4a2af25ce831bfaad13954ba18a4446374cb0aef55e"
)
localpatch = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

View File

@ -54,8 +54,6 @@
from spack.util.pattern import Bunch
from spack.util.web import FetchError
is_windows = sys.platform == "win32"
def ensure_configuration_fixture_run_before(request):
"""Ensure that fixture mutating the configuration run before the one where
@ -621,7 +619,7 @@ def ensure_debug(monkeypatch):
tty.set_debug(current_debug_level)
@pytest.fixture(autouse=is_windows, scope="session")
@pytest.fixture(autouse=sys.platform == "win32", scope="session")
def platform_config():
spack.config.add_default_platform_scope(spack.platforms.real_host().name)
@ -633,7 +631,7 @@ def default_config():
This ensures we can test the real default configuration without having
tests fail when the user overrides the defaults that we test against."""
defaults_path = os.path.join(spack.paths.etc_path, "defaults")
if is_windows:
if sys.platform == "win32":
defaults_path = os.path.join(defaults_path, "windows")
with spack.config.use_configuration(defaults_path) as defaults_config:
yield defaults_config
@ -690,7 +688,7 @@ def configuration_dir(tmpdir_factory, linux_os):
tmpdir.ensure("user", dir=True)
# Slightly modify config.yaml and compilers.yaml
if is_windows:
if sys.platform == "win32":
locks = False
else:
locks = True
@ -1675,11 +1673,11 @@ def mock_executable(tmpdir):
"""
import jinja2
shebang = "#!/bin/sh\n" if not is_windows else "@ECHO OFF"
shebang = "#!/bin/sh\n" if sys.platform != "win32" else "@ECHO OFF"
def _factory(name, output, subdir=("bin",)):
f = tmpdir.ensure(*subdir, dir=True).join(name)
if is_windows:
if sys.platform == "win32":
f += ".bat"
t = jinja2.Template("{{ shebang }}{{ output }}\n")
f.write(t.render(shebang=shebang, output=output))

View File

@ -33,8 +33,6 @@
from spack.schema.database_index import schema
from spack.util.executable import Executable
is_windows = sys.platform == "win32"
pytestmark = pytest.mark.db
@ -451,7 +449,7 @@ def test_005_db_exists(database):
lock_file = os.path.join(database.root, ".spack-db", "lock")
assert os.path.exists(str(index_file))
# Lockfiles not currently supported on Windows
if not is_windows:
if sys.platform != "win32":
assert os.path.exists(str(lock_file))
with open(index_file) as fd:

View File

@ -24,8 +24,6 @@
import spack.store
import spack.util.lock as lk
is_windows = sys.platform == "win32"
def _mock_repo(root, namespace):
"""Create an empty repository at the specified root
@ -528,7 +526,7 @@ def _repoerr(repo, name):
# The call to install_tree will raise the exception since not mocking
# creation of dependency package files within *install* directories.
with pytest.raises(IOError, match=path if not is_windows else ""):
with pytest.raises(IOError, match=path if sys.platform != "win32" else ""):
inst.dump_packages(spec, path)
# Now try the error path, which requires the mock directory structure
@ -879,7 +877,7 @@ def _chgrp(path, group, follow_symlinks=True):
metadatadir = spack.store.layout.metadata_path(spec)
# Regex matching with Windows style paths typically fails
# so we skip the match check here
if is_windows:
if sys.platform == "win32":
metadatadir = None
# Should fail with a "not a directory" error
with pytest.raises(OSError, match=metadatadir):

View File

@ -11,9 +11,8 @@
import spack.paths
from spack.compiler import _parse_non_system_link_dirs
is_windows = sys.platform == "win32"
drive = ""
if is_windows:
if sys.platform == "win32":
match = re.search(r"[A-Za-z]:", spack.paths.test_path)
if match:
drive = match.group()
@ -210,7 +209,7 @@ def test_obscure_parsing_rules():
]
# TODO: add a comment explaining why this happens
if is_windows:
if sys.platform == "win32":
paths.remove(os.path.join(root, "second", "path"))
check_link_paths("obscure-parsing-rules.txt", paths)

View File

@ -13,8 +13,6 @@
import spack.paths
is_windows = sys.platform == "win32"
@pytest.fixture()
def library_list():
@ -28,7 +26,7 @@ def library_list():
"/dir3/libz.so",
"libmpi.so.20.10.1", # shared object libraries may be versioned
]
if not is_windows
if sys.platform != "win32"
else [
"/dir1/liblapack.lib",
"/dir2/libpython3.6.dll",
@ -59,10 +57,10 @@ def header_list():
# TODO: Remove below when llnl.util.filesystem.find_libraries becomes spec aware
plat_static_ext = "lib" if is_windows else "a"
plat_static_ext = "lib" if sys.platform == "win32" else "a"
plat_shared_ext = "dll" if is_windows else "so"
plat_shared_ext = "dll" if sys.platform == "win32" else "so"
plat_apple_shared_ext = "dylib"
@ -78,7 +76,8 @@ def test_joined_and_str(self, library_list):
expected = " ".join(
[
"/dir1/liblapack.%s" % plat_static_ext,
"/dir2/libpython3.6.%s" % (plat_apple_shared_ext if not is_windows else "dll"),
"/dir2/libpython3.6.%s"
% (plat_apple_shared_ext if sys.platform != "win32" else "dll"),
"/dir1/libblas.%s" % plat_static_ext,
"/dir3/libz.%s" % plat_shared_ext,
"libmpi.%s.20.10.1" % plat_shared_ext,
@ -93,7 +92,8 @@ def test_joined_and_str(self, library_list):
expected = ";".join(
[
"/dir1/liblapack.%s" % plat_static_ext,
"/dir2/libpython3.6.%s" % (plat_apple_shared_ext if not is_windows else "dll"),
"/dir2/libpython3.6.%s"
% (plat_apple_shared_ext if sys.platform != "win32" else "dll"),
"/dir1/libblas.%s" % plat_static_ext,
"/dir3/libz.%s" % plat_shared_ext,
"libmpi.%s.20.10.1" % plat_shared_ext,

View File

@ -62,8 +62,7 @@
import llnl.util.multiproc as mp
from llnl.util.filesystem import getuid, touch
is_windows = sys.platform == "win32"
if not is_windows:
if sys.platform != "win32":
import fcntl
pytestmark = pytest.mark.skipif(sys.platform == "win32", reason="does not run on windows")
@ -127,7 +126,7 @@ def make_readable(*paths):
# stat.S_IREAD constants or a corresponding integer value). All other
# bits are ignored."
for path in paths:
if not is_windows:
if sys.platform != "win32":
mode = 0o555 if os.path.isdir(path) else 0o444
else:
mode = stat.S_IREAD
@ -136,7 +135,7 @@ def make_readable(*paths):
def make_writable(*paths):
for path in paths:
if not is_windows:
if sys.platform != "win32":
mode = 0o755 if os.path.isdir(path) else 0o744
else:
mode = stat.S_IWRITE
@ -616,7 +615,7 @@ def test_read_lock_read_only_dir_writable_lockfile(lock_dir, lock_path):
pass
@pytest.mark.skipif(False if is_windows else getuid() == 0, reason="user is root")
@pytest.mark.skipif(False if sys.platform == "win32" else getuid() == 0, reason="user is root")
def test_read_lock_no_lockfile(lock_dir, lock_path):
"""read-only directory, no lockfile (so can't create)."""
with read_only(lock_dir):

View File

@ -20,7 +20,6 @@
from spack.spec import Spec
from spack.stage import Stage
from spack.util.executable import Executable
from spack.util.path import is_windows
# various sha256 sums (using variables for legibility)
# many file based shas will differ between Windows and other platforms
@ -29,22 +28,22 @@
# files with contents 'foo', 'bar', and 'baz'
foo_sha256 = (
"b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c"
if not is_windows
if sys.platform != "win32"
else "bf874c7dd3a83cf370fdc17e496e341de06cd596b5c66dbf3c9bb7f6c139e3ee"
)
bar_sha256 = (
"7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730"
if not is_windows
if sys.platform != "win32"
else "556ddc69a75d0be0ecafc82cd4657666c8063f13d762282059c39ff5dbf18116"
)
baz_sha256 = (
"bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c"
if not is_windows
if sys.platform != "win32"
else "d30392e66c636a063769cbb1db08cd3455a424650d4494db6379d73ea799582b"
)
biz_sha256 = (
"a69b288d7393261e613c276c6d38a01461028291f6e381623acc58139d01f54d"
if not is_windows
if sys.platform != "win32"
else "2f2b087a8f84834fd03d4d1d5b43584011e869e4657504ef3f8b0a672a5c222e"
)
@ -56,7 +55,7 @@
platform_url_sha = (
"252c0af58be3d90e5dc5e0d16658434c9efa5d20a5df6c10bf72c2d77f780866"
if not is_windows
if sys.platform != "win32"
else "ecf44a8244a486e9ef5f72c6cb622f99718dcd790707ac91af0b8c9a4ab7a2bb"
)
@ -160,17 +159,17 @@ def test_patch_order(mock_packages, config):
mid2_sha256 = (
"mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"
if not is_windows
if sys.platform != "win32"
else "mid21234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234abcd1234"
)
mid1_sha256 = (
"0b62284961dab49887e31319843431ee5b037382ac02c4fe436955abef11f094"
if not is_windows
if sys.platform != "win32"
else "aeb16c4dec1087e39f2330542d59d9b456dd26d791338ae6d80b6ffd10c89dfa"
)
top_sha256 = (
"f7de2947c64cb6435e15fb2bef359d1ed5f6356b2aebb7b20535e3772904e6db"
if not is_windows
if sys.platform != "win32"
else "ff34cb21271d16dbf928374f610bb5dd593d293d311036ddae86c4846ff79070"
)
@ -219,7 +218,7 @@ def test_patched_dependency(mock_packages, config, install_mockery, mock_fetch):
# make sure the patch makes it into the dependency spec
t_sha = (
"c45c1564f70def3fc1a6e22139f62cb21cd190cc3a7dbe6f4120fa59ce33dcb8"
if not is_windows
if sys.platform != "win32"
else "3c5b65abcd6a3b2c714dbf7c31ff65fe3748a1adc371f030c283007ca5534f11"
)
assert (t_sha,) == spec["libelf"].variants["patches"].value

View File

@ -11,8 +11,6 @@
import spack.util.environment as envutil
is_windows = sys.platform == "win32"
@pytest.fixture()
def prepare_environment_for_tests():
@ -23,14 +21,14 @@ def prepare_environment_for_tests():
def test_is_system_path():
sys_path = "C:\\Users" if is_windows else "/usr/bin"
sys_path = "C:\\Users" if sys.platform == "win32" else "/usr/bin"
assert envutil.is_system_path(sys_path)
assert not envutil.is_system_path("/nonsense_path/bin")
assert not envutil.is_system_path("")
assert not envutil.is_system_path(None)
if is_windows:
if sys.platform == "win32":
test_paths = [
"C:\\Users",
"C:\\",
@ -51,7 +49,7 @@ def test_is_system_path():
def test_filter_system_paths():
nonsense_prefix = "C:\\nonsense_path" if is_windows else "/nonsense_path"
nonsense_prefix = "C:\\nonsense_path" if sys.platform == "win32" else "/nonsense_path"
expected = [p for p in test_paths if p.startswith(nonsense_prefix)]
filtered = envutil.filter_system_paths(test_paths)
assert expected == filtered

View File

@ -14,13 +14,11 @@
import spack.util.executable as ex
from spack.hooks.sbang import filter_shebangs_in_directory
is_windows = sys.platform == "win32"
def test_read_unicode(tmpdir, working_env):
script_name = "print_unicode.py"
# read the unicode back in and see whether things work
if is_windows:
if sys.platform == "win32":
script = ex.Executable("%s %s" % (sys.executable, script_name))
else:
script = ex.Executable("./%s" % script_name)

View File

@ -13,9 +13,6 @@
import spack.config
import spack.util.path as sup
is_windows = sys.platform == "win32"
#: Some lines with lots of placeholders
padded_lines = [
"==> [2021-06-23-15:59:05.020387] './configure' '--prefix=/Users/gamblin2/padding-log-test/opt/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_placeholder__/__spack_path_pla/darwin-bigsur-skylake/apple-clang-12.0.5/zlib-1.2.11-74mwnxgn6nujehpyyalhwizwojwn5zga", # noqa: E501
@ -36,7 +33,7 @@ def test_sanitze_file_path(tmpdir):
"""Test filtering illegal characters out of potential file paths"""
# *nix illegal files characters are '/' and none others
illegal_file_path = str(tmpdir) + "//" + "abcdefghi.txt"
if is_windows:
if sys.platform == "win32":
# Windows has a larger set of illegal characters
illegal_file_path = os.path.join(tmpdir, 'a<b>cd?e:f"g|h*i.txt')
real_path = sup.sanitize_file_path(illegal_file_path)
@ -46,7 +43,7 @@ def test_sanitze_file_path(tmpdir):
# This class pertains to path string padding manipulation specifically
# which is used for binary caching. This functionality is not supported
# on Windows as of yet.
@pytest.mark.skipif(is_windows, reason="Padding funtionality unsupported on Windows")
@pytest.mark.skipif(sys.platform == "win32", reason="Padding funtionality unsupported on Windows")
class TestPathPadding:
@pytest.mark.parametrize("padded,fixed", zip(padded_lines, fixed_lines))
def test_padding_substitution(self, padded, fixed):
@ -122,7 +119,7 @@ def test_path_debug_padded_filter(debug, monkeypatch):
string = fmt.format(prefix, os.sep, os.sep.join([sup.SPACK_PATH_PADDING_CHARS] * 2), suffix)
expected = (
fmt.format(prefix, os.sep, "[padded-to-{0}-chars]".format(72), suffix)
if debug <= 1 and not is_windows
if debug <= 1 and sys.platform != "win32"
else string
)

View File

@ -28,8 +28,6 @@
ALLOWED_SINGLE_EXT_ARCHIVE_TYPES = PRE_EXTS + EXTS + NOTAR_EXTS
is_windows = sys.platform == "win32"
try:
import bz2 # noqa
@ -158,7 +156,7 @@ def _unzip(archive_file):
archive_file (str): absolute path of the file to be decompressed
"""
extracted_file = os.path.basename(strip_extension(archive_file, "zip"))
if is_windows:
if sys.platform == "win32":
return _untar(archive_file)
else:
exe = "unzip"
@ -170,7 +168,7 @@ def _unzip(archive_file):
def _unZ(archive_file):
if is_windows:
if sys.platform == "win32":
result = _7zip(archive_file)
else:
result = _system_gunzip(archive_file)
@ -189,7 +187,7 @@ def _lzma_decomp(archive_file):
with lzma.open(archive_file) as lar:
shutil.copyfileobj(lar, ar)
else:
if is_windows:
if sys.platform == "win32":
return _7zip(archive_file)
else:
return _xz(archive_file)
@ -227,7 +225,7 @@ def _xz(archive_file):
"""Decompress lzma compressed .xz files via xz command line
tool. Available only on Unix
"""
if is_windows:
if sys.platform == "win32":
raise RuntimeError("XZ tool unavailable on Windows")
decompressed_file = os.path.basename(strip_extension(archive_file, "xz"))
working_dir = os.getcwd()
@ -310,7 +308,7 @@ def decompressor_for(path, extension=None):
# Catch tar.xz/tar.Z files here for Windows
# as the tar utility on Windows cannot handle such
# compression types directly
if ("xz" in extension or "Z" in extension) and is_windows:
if ("xz" in extension or "Z" in extension) and sys.platform == "win32":
return _win_compressed_tarball_handler
return _untar

View File

@ -25,14 +25,12 @@
import spack.util.executable as executable
from spack.util.path import path_to_os_path, system_path_filter
is_windows = sys.platform == "win32"
system_paths = (
["/", "/usr", "/usr/local"]
if not is_windows
if sys.platform != "win32"
else ["C:\\", "C:\\Program Files", "C:\\Program Files (x86)", "C:\\Users", "C:\\ProgramData"]
)
suffixes = ["bin", "bin64", "include", "lib", "lib64"] if not is_windows else []
suffixes = ["bin", "bin64", "include", "lib", "lib64"] if sys.platform != "win32" else []
system_dirs = [os.path.join(p, s) for s in suffixes for p in system_paths] + system_paths

View File

@ -21,8 +21,6 @@
import spack.error
import spack.paths
is_windows = sys.platform == "win32"
class Lock(llnl.util.lock.Lock):
"""Lock that can be disabled.
@ -34,7 +32,7 @@ class Lock(llnl.util.lock.Lock):
def __init__(self, *args, **kwargs):
super(Lock, self).__init__(*args, **kwargs)
self._enable = spack.config.get("config:locks", not is_windows)
self._enable = spack.config.get("config:locks", sys.platform != "win32")
def _lock(self, op, timeout=0):
if self._enable:

View File

@ -22,8 +22,6 @@
import spack.util.spack_yaml as syaml
is_windows = sys.platform == "win32"
__all__ = ["substitute_config_variables", "substitute_path_variables", "canonicalize_path"]
@ -153,7 +151,7 @@ def sanitize_file_path(pth):
# instances of illegal characters on join
pth_cmpnts = pth.split(os.path.sep)
if is_windows:
if sys.platform == "win32":
drive_match = r"[a-zA-Z]:"
is_abs = bool(re.match(drive_match, pth_cmpnts[0]))
drive = pth_cmpnts[0] + os.path.sep if is_abs else ""
@ -210,7 +208,7 @@ def path_filter_caller(*args, **kwargs):
def get_system_path_max():
# Choose a conservative default
sys_max_path_length = 256
if is_windows:
if sys.platform == "win32":
sys_max_path_length = 260
else:
try:
@ -238,7 +236,7 @@ class Path:
unix = 0
windows = 1
platform_path = windows if is_windows else unix
platform_path = windows if sys.platform == "win32" else unix
def format_os_path(path, mode=Path.unix):
@ -487,7 +485,7 @@ def debug_padded_filter(string, level=1):
Returns (str): filtered string if current debug level does not exceed
level and not windows; otherwise, unfiltered string
"""
if is_windows:
if sys.platform == "win32":
return string
return padding_filter(string) if tty.debug_level() <= level else string

View File

@ -413,6 +413,7 @@ def visit_Try(self, node):
self.dispatch(node.finalbody)
def visit_TryExcept(self, node):
# this construct only exists in Python < 3.3
self.fill("try")
with self.block():
self.dispatch(node.body)
@ -425,7 +426,8 @@ def visit_TryExcept(self, node):
self.dispatch(node.orelse)
def visit_TryFinally(self, node):
if len(node.body) == 1 and isinstance(node.body[0], ast.TryExcept):
# this construct only exists in Python < 3.3
if len(node.body) == 1 and isinstance(node.body[0], ast.TryExcept): # type: ignore
# try-except-finally
self.dispatch(node.body)
else:

View File

@ -13,8 +13,7 @@
from llnl.util import tty
is_windows = sys.platform == "win32"
if is_windows:
if sys.platform == "win32":
import winreg
@ -154,7 +153,7 @@ def __init__(self, key, root_key=HKEY.HKEY_CURRENT_USER):
to get an entrypoint, the HKEY constants are always open, or an already
open key can be used instead.
"""
if not is_windows:
if sys.platform != "win32":
raise RuntimeError(
"Cannot instantiate Windows Registry class on non Windows platforms"
)
@ -167,7 +166,7 @@ def invalid_reg_ref_error_handler(self):
try:
yield
except FileNotFoundError as e:
if e.winerror == 2:
if sys.platform == "win32" and e.winerror == 2:
tty.debug("Key %s at position %s does not exist" % (self.key, str(self.root)))
else:
raise e
@ -182,7 +181,7 @@ def _load_key(self):
winreg.OpenKeyEx(self.root.hkey, self.key, access=winreg.KEY_READ),
)
except FileNotFoundError as e:
if e.winerror == 2:
if sys.platform == "win32" and e.winerror == 2:
self._reg = -1
tty.debug("Key %s at position %s does not exist" % (self.key, str(self.root)))
else:

View File

@ -113,6 +113,7 @@ namespace_packages = true
# globally, then turn back on in spack and spack submodules
ignore_errors = true
ignore_missing_imports = true
check_untyped_defs = true
[[tool.mypy.overrides]]
module = 'spack.*'