From 673565aefe79f4c8c4aec8ab61fb07c57c2a7ced Mon Sep 17 00:00:00 2001
From: Harmen Stoppels <me@harmenstoppels.nl>
Date: Tue, 17 Sep 2024 07:45:59 +0200
Subject: imports: automate missing imports (#46410)

---
 lib/spack/spack/audit.py                        |  2 ++
 lib/spack/spack/bootstrap/config.py             |  1 +
 lib/spack/spack/bootstrap/environment.py        |  2 ++
 lib/spack/spack/build_environment.py            | 20 +++--------
 lib/spack/spack/build_systems/_checks.py        |  6 ++--
 lib/spack/spack/build_systems/autotools.py      |  9 +++--
 lib/spack/spack/build_systems/cmake.py          |  3 +-
 lib/spack/spack/build_systems/compiler.py       |  1 +
 lib/spack/spack/build_systems/intel.py          |  3 +-
 lib/spack/spack/build_systems/oneapi.py         |  2 +-
 lib/spack/spack/build_systems/python.py         |  2 ++
 lib/spack/spack/builder.py                      |  8 ++---
 lib/spack/spack/ci.py                           |  1 +
 lib/spack/spack/cmd/__init__.py                 |  2 +-
 lib/spack/spack/cmd/arch.py                     |  1 +
 lib/spack/spack/cmd/bootstrap.py                |  1 +
 lib/spack/spack/cmd/change.py                   |  1 +
 lib/spack/spack/cmd/clean.py                    |  1 +
 lib/spack/spack/cmd/commands.py                 |  1 +
 lib/spack/spack/cmd/common/confirmation.py      |  1 +
 lib/spack/spack/cmd/config.py                   |  6 ++--
 lib/spack/spack/cmd/debug.py                    |  2 ++
 lib/spack/spack/cmd/dev_build.py                |  2 ++
 lib/spack/spack/cmd/env.py                      |  1 +
 lib/spack/spack/cmd/external.py                 |  1 +
 lib/spack/spack/cmd/find.py                     |  2 ++
 lib/spack/spack/cmd/info.py                     |  1 +
 lib/spack/spack/cmd/install.py                  |  7 ++--
 lib/spack/spack/cmd/load.py                     |  1 +
 lib/spack/spack/cmd/modules/__init__.py         |  5 +--
 lib/spack/spack/cmd/python.py                   |  4 +--
 lib/spack/spack/cmd/solve.py                    |  2 ++
 lib/spack/spack/cmd/spec.py                     |  1 +
 lib/spack/spack/cmd/tags.py                     |  1 +
 lib/spack/spack/cmd/test.py                     |  2 ++
 lib/spack/spack/cmd/tutorial.py                 |  1 +
 lib/spack/spack/cmd/undevelop.py                |  1 +
 lib/spack/spack/cmd/unit_test.py                |  2 ++
 lib/spack/spack/cmd/unload.py                   |  2 ++
 lib/spack/spack/cmd/verify.py                   |  1 +
 lib/spack/spack/config.py                       | 43 +++++++++++------------
 lib/spack/spack/detection/common.py             |  2 ++
 lib/spack/spack/detection/path.py               |  1 +
 lib/spack/spack/directory_layout.py             |  2 ++
 lib/spack/spack/environment/environment.py      |  3 ++
 lib/spack/spack/error.py                        | 45 +++++++++++++++++++++++++
 lib/spack/spack/extensions.py                   |  1 +
 lib/spack/spack/fetch_strategy.py               |  2 +-
 lib/spack/spack/graph.py                        |  1 +
 lib/spack/spack/install_test.py                 |  4 +--
 lib/spack/spack/installer.py                    | 42 +++++++++--------------
 lib/spack/spack/main.py                         |  6 ++++
 lib/spack/spack/mirror.py                       |  1 +
 lib/spack/spack/modules/common.py               |  1 +
 lib/spack/spack/package.py                      |  9 ++---
 lib/spack/spack/package_base.py                 | 20 +++--------
 lib/spack/spack/package_prefs.py                |  2 +-
 lib/spack/spack/parser.py                       |  5 +--
 lib/spack/spack/relocate.py                     | 17 +++++-----
 lib/spack/spack/repo.py                         |  5 ++-
 lib/spack/spack/reporters/cdash.py              |  2 ++
 lib/spack/spack/rewiring.py                     |  1 +
 lib/spack/spack/schema/__init__.py              |  4 ++-
 lib/spack/spack/schema/config.py                |  1 +
 lib/spack/spack/schema/view.py                  |  1 +
 lib/spack/spack/solver/asp.py                   |  6 ++--
 lib/spack/spack/spec.py                         |  1 +
 lib/spack/spack/store.py                        |  1 +
 lib/spack/spack/tag.py                          |  3 ++
 lib/spack/spack/target.py                       |  1 +
 lib/spack/spack/test/bindist.py                 |  4 +++
 lib/spack/spack/test/bootstrap.py               |  1 +
 lib/spack/spack/test/build_environment.py       |  1 +
 lib/spack/spack/test/build_systems.py           |  5 ++-
 lib/spack/spack/test/builder.py                 |  3 ++
 lib/spack/spack/test/buildtask.py               |  3 +-
 lib/spack/spack/test/ci.py                      |  1 +
 lib/spack/spack/test/cmd/bootstrap.py           |  1 +
 lib/spack/spack/test/cmd/checksum.py            |  4 +--
 lib/spack/spack/test/cmd/clean.py               |  1 +
 lib/spack/spack/test/cmd/commands.py            |  1 +
 lib/spack/spack/test/cmd/compiler.py            |  1 +
 lib/spack/spack/test/cmd/create.py              |  1 +
 lib/spack/spack/test/cmd/debug.py               |  1 +
 lib/spack/spack/test/cmd/deprecate.py           |  1 +
 lib/spack/spack/test/cmd/dev_build.py           |  1 +
 lib/spack/spack/test/cmd/develop.py             |  4 +++
 lib/spack/spack/test/cmd/diff.py                |  2 ++
 lib/spack/spack/test/cmd/env.py                 | 10 ++++--
 lib/spack/spack/test/cmd/external.py            |  2 ++
 lib/spack/spack/test/cmd/find.py                |  1 +
 lib/spack/spack/test/cmd/install.py             | 10 +++---
 lib/spack/spack/test/cmd/is_git_repo.py         |  2 ++
 lib/spack/spack/test/cmd/list.py                |  1 +
 lib/spack/spack/test/cmd/location.py            |  1 +
 lib/spack/spack/test/cmd/logs.py                |  3 ++
 lib/spack/spack/test/cmd/mirror.py              |  3 ++
 lib/spack/spack/test/cmd/module.py              |  2 ++
 lib/spack/spack/test/cmd/pkg.py                 |  1 +
 lib/spack/spack/test/cmd/spec.py                |  3 +-
 lib/spack/spack/test/cmd/style.py               |  1 +
 lib/spack/spack/test/compilers/basics.py        |  1 +
 lib/spack/spack/test/concretize.py              |  3 ++
 lib/spack/spack/test/concretize_errors.py       |  1 +
 lib/spack/spack/test/concretize_preferences.py  |  6 ++--
 lib/spack/spack/test/concretize_requirements.py |  3 +-
 lib/spack/spack/test/config.py                  | 11 +++---
 lib/spack/spack/test/conftest.py                |  4 +++
 lib/spack/spack/test/container/images.py        |  1 +
 lib/spack/spack/test/cray_manifest.py           |  2 ++
 lib/spack/spack/test/database.py                |  2 ++
 lib/spack/spack/test/detection.py               |  2 ++
 lib/spack/spack/test/directory_layout.py        |  3 ++
 lib/spack/spack/test/env.py                     |  2 ++
 lib/spack/spack/test/git_fetch.py               |  3 ++
 lib/spack/spack/test/install.py                 |  5 ++-
 lib/spack/spack/test/installer.py               | 28 ++++++++-------
 lib/spack/spack/test/modules/common.py          |  7 ++--
 lib/spack/spack/test/modules/conftest.py        |  2 ++
 lib/spack/spack/test/modules/lmod.py            |  3 ++
 lib/spack/spack/test/multimethod.py             |  1 +
 lib/spack/spack/test/package_class.py           |  5 ++-
 lib/spack/spack/test/packages.py                |  7 ++--
 lib/spack/spack/test/packaging.py               |  3 ++
 lib/spack/spack/test/patch.py                   |  3 ++
 lib/spack/spack/test/relocate.py                |  1 +
 lib/spack/spack/test/sbang.py                   |  1 +
 lib/spack/spack/test/spec_dag.py                |  4 +--
 lib/spack/spack/test/spec_semantics.py          |  6 ++++
 lib/spack/spack/test/spec_syntax.py             |  3 ++
 lib/spack/spack/test/stage.py                   |  1 +
 lib/spack/spack/test/tag.py                     |  1 +
 lib/spack/spack/test/test_suite.py              |  2 ++
 lib/spack/spack/test/url_fetch.py               |  2 ++
 lib/spack/spack/test/util/executable.py         |  1 +
 lib/spack/spack/test/versions.py                |  1 +
 136 files changed, 383 insertions(+), 170 deletions(-)

diff --git a/lib/spack/spack/audit.py b/lib/spack/spack/audit.py
index d682cc6d58..486e3c3d65 100644
--- a/lib/spack/spack/audit.py
+++ b/lib/spack/spack/audit.py
@@ -51,7 +51,9 @@ from urllib.request import urlopen
 
 import llnl.util.lang
 
+import spack.builder
 import spack.config
+import spack.fetch_strategy
 import spack.patch
 import spack.repo
 import spack.spec
diff --git a/lib/spack/spack/bootstrap/config.py b/lib/spack/spack/bootstrap/config.py
index 51edeccc25..1781b3cc7e 100644
--- a/lib/spack/spack/bootstrap/config.py
+++ b/lib/spack/spack/bootstrap/config.py
@@ -14,6 +14,7 @@ from llnl.util import tty
 import spack.compilers
 import spack.config
 import spack.environment
+import spack.modules
 import spack.paths
 import spack.platforms
 import spack.repo
diff --git a/lib/spack/spack/bootstrap/environment.py b/lib/spack/spack/bootstrap/environment.py
index ac8db642bf..39c8aa2fa5 100644
--- a/lib/spack/spack/bootstrap/environment.py
+++ b/lib/spack/spack/bootstrap/environment.py
@@ -14,7 +14,9 @@ import archspec.cpu
 from llnl.util import tty
 
 import spack.environment
+import spack.spec
 import spack.tengine
+import spack.util.path
 
 from ._common import _root_spec
 from .config import root_path, spec_for_current_python, store_path
diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 3dfda84101..296fdd4aff 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -53,6 +53,7 @@ from llnl.util.symlink import symlink
 from llnl.util.tty.color import cescape, colorize
 from llnl.util.tty.log import MultiProcessFd
 
+import spack.build_systems._checks
 import spack.build_systems.cmake
 import spack.build_systems.meson
 import spack.build_systems.python
@@ -62,6 +63,7 @@ import spack.config
 import spack.deptypes as dt
 import spack.error
 import spack.main
+import spack.multimethod
 import spack.package_base
 import spack.paths
 import spack.platforms
@@ -73,9 +75,8 @@ import spack.subprocess_context
 import spack.util.executable
 from spack import traverse
 from spack.context import Context
-from spack.error import NoHeadersError, NoLibrariesError
+from spack.error import InstallError, NoHeadersError, NoLibrariesError
 from spack.install_test import spack_install_test_log
-from spack.installer import InstallError
 from spack.util.cpus import determine_number_of_jobs
 from spack.util.environment import (
     SYSTEM_DIR_CASE_ENTRY,
@@ -1135,7 +1136,7 @@ def _setup_pkg_and_run(
         return_value = function(pkg, kwargs)
         write_pipe.send(return_value)
 
-    except StopPhase as e:
+    except spack.error.StopPhase as e:
         # Do not create a full ChildError from this, it's not an error
         # it's a control statement.
         write_pipe.send(e)
@@ -1296,7 +1297,7 @@ def start_build_process(pkg, function, kwargs):
     p.join()
 
     # If returns a StopPhase, raise it
-    if isinstance(child_result, StopPhase):
+    if isinstance(child_result, spack.error.StopPhase):
         # do not print
         raise child_result
 
@@ -1505,17 +1506,6 @@ def _make_child_error(msg, module, name, traceback, log, log_type, context):
     return ChildError(msg, module, name, traceback, log, log_type, context)
 
 
-class StopPhase(spack.error.SpackError):
-    """Pickle-able exception to control stopped builds."""
-
-    def __reduce__(self):
-        return _make_stop_phase, (self.message, self.long_message)
-
-
-def _make_stop_phase(msg, long_msg):
-    return StopPhase(msg, long_msg)
-
-
 def write_log_summary(out, log_type, log, last=None):
     errors, warnings = parse_log_events(log)
     nerr = len(errors)
diff --git a/lib/spack/spack/build_systems/_checks.py b/lib/spack/spack/build_systems/_checks.py
index dfda043fad..e15409fc38 100644
--- a/lib/spack/spack/build_systems/_checks.py
+++ b/lib/spack/spack/build_systems/_checks.py
@@ -8,7 +8,7 @@ from typing import List
 import llnl.util.lang
 
 import spack.builder
-import spack.installer
+import spack.error
 import spack.relocate
 import spack.spec
 import spack.store
@@ -34,7 +34,7 @@ def sanity_check_prefix(builder: spack.builder.Builder):
             if not predicate(abs_path):
                 msg = "Install failed for {0}. No such {1} in prefix: {2}"
                 msg = msg.format(pkg.name, filetype, path)
-                raise spack.installer.InstallError(msg)
+                raise spack.error.InstallError(msg)
 
     check_paths(pkg.sanity_check_is_file, "file", os.path.isfile)
     check_paths(pkg.sanity_check_is_dir, "directory", os.path.isdir)
@@ -42,7 +42,7 @@ def sanity_check_prefix(builder: spack.builder.Builder):
     ignore_file = llnl.util.lang.match_predicate(spack.store.STORE.layout.hidden_file_regexes)
     if all(map(ignore_file, os.listdir(pkg.prefix))):
         msg = "Install failed for {0}.  Nothing was installed!"
-        raise spack.installer.InstallError(msg.format(pkg.name))
+        raise spack.error.InstallError(msg.format(pkg.name))
 
 
 def apply_macos_rpath_fixups(builder: spack.builder.Builder):
diff --git a/lib/spack/spack/build_systems/autotools.py b/lib/spack/spack/build_systems/autotools.py
index b9b9ee2f2e..d5ddcea11a 100644
--- a/lib/spack/spack/build_systems/autotools.py
+++ b/lib/spack/spack/build_systems/autotools.py
@@ -13,6 +13,7 @@ import llnl.util.tty as tty
 
 import spack.build_environment
 import spack.builder
+import spack.error
 import spack.package_base
 from spack.directives import build_system, conflicts, depends_on
 from spack.multimethod import when
@@ -248,7 +249,7 @@ class AutotoolsBuilder(BaseBuilder):
 
         # An external gnuconfig may not not have a prefix.
         if gnuconfig_dir is None:
-            raise spack.build_environment.InstallError(
+            raise spack.error.InstallError(
                 "Spack could not find substitutes for GNU config files because no "
                 "prefix is available for the `gnuconfig` package. Make sure you set a "
                 "prefix path instead of modules for external `gnuconfig`."
@@ -268,7 +269,7 @@ class AutotoolsBuilder(BaseBuilder):
                 msg += (
                     " or the `gnuconfig` package prefix is misconfigured as" " an external package"
                 )
-            raise spack.build_environment.InstallError(msg)
+            raise spack.error.InstallError(msg)
 
         # Filter working substitutes
         candidates = [f for f in candidates if runs_ok(f)]
@@ -293,9 +294,7 @@ To resolve this problem, please try the following:
    and set the prefix to the directory containing the `config.guess` and
    `config.sub` files.
 """
-            raise spack.build_environment.InstallError(
-                msg.format(", ".join(to_be_found), self.name)
-            )
+            raise spack.error.InstallError(msg.format(", ".join(to_be_found), self.name))
 
         # Copy the good files over the bad ones
         for abs_path in to_be_patched:
diff --git a/lib/spack/spack/build_systems/cmake.py b/lib/spack/spack/build_systems/cmake.py
index d638a3e50b..dc833a10a6 100644
--- a/lib/spack/spack/build_systems/cmake.py
+++ b/lib/spack/spack/build_systems/cmake.py
@@ -15,6 +15,7 @@ import llnl.util.filesystem as fs
 import spack.build_environment
 import spack.builder
 import spack.deptypes as dt
+import spack.error
 import spack.package_base
 from spack.directives import build_system, conflicts, depends_on, variant
 from spack.multimethod import when
@@ -344,7 +345,7 @@ class CMakeBuilder(BaseBuilder):
             msg = "Invalid CMake generator: '{0}'\n".format(generator)
             msg += "CMakePackage currently supports the following "
             msg += "primary generators: '{0}'".format("', '".join(valid_primary_generators))
-            raise spack.package_base.InstallError(msg)
+            raise spack.error.InstallError(msg)
 
         try:
             build_type = pkg.spec.variants["build_type"].value
diff --git a/lib/spack/spack/build_systems/compiler.py b/lib/spack/spack/build_systems/compiler.py
index d441b57b2e..65a85ecddf 100644
--- a/lib/spack/spack/build_systems/compiler.py
+++ b/lib/spack/spack/build_systems/compiler.py
@@ -14,6 +14,7 @@ from llnl.util.lang import classproperty
 
 import spack.compiler
 import spack.package_base
+import spack.util.executable
 
 # Local "type" for type hints
 Path = Union[str, pathlib.Path]
diff --git a/lib/spack/spack/build_systems/intel.py b/lib/spack/spack/build_systems/intel.py
index 5695a9dbeb..9f82bae14d 100644
--- a/lib/spack/spack/build_systems/intel.py
+++ b/lib/spack/spack/build_systems/intel.py
@@ -22,9 +22,10 @@ from llnl.util.filesystem import (
     install,
 )
 
+import spack.builder
 import spack.error
 from spack.build_environment import dso_suffix
-from spack.package_base import InstallError
+from spack.error import InstallError
 from spack.util.environment import EnvironmentModifications
 from spack.util.executable import Executable
 from spack.util.prefix import Prefix
diff --git a/lib/spack/spack/build_systems/oneapi.py b/lib/spack/spack/build_systems/oneapi.py
index a0c8d4fc47..6d60a7ae4f 100644
--- a/lib/spack/spack/build_systems/oneapi.py
+++ b/lib/spack/spack/build_systems/oneapi.py
@@ -15,7 +15,7 @@ from llnl.util.link_tree import LinkTree
 import spack.util.path
 from spack.build_environment import dso_suffix
 from spack.directives import conflicts, license, redistribute, variant
-from spack.package_base import InstallError
+from spack.error import InstallError
 from spack.util.environment import EnvironmentModifications
 from spack.util.executable import Executable
 
diff --git a/lib/spack/spack/build_systems/python.py b/lib/spack/spack/build_systems/python.py
index bd0c57520c..e589ac94ef 100644
--- a/lib/spack/spack/build_systems/python.py
+++ b/lib/spack/spack/build_systems/python.py
@@ -24,6 +24,8 @@ import spack.deptypes as dt
 import spack.detection
 import spack.multimethod
 import spack.package_base
+import spack.platforms
+import spack.repo
 import spack.spec
 import spack.store
 from spack.directives import build_system, depends_on, extends
diff --git a/lib/spack/spack/builder.py b/lib/spack/spack/builder.py
index 7590016c33..eaeb82b17c 100644
--- a/lib/spack/spack/builder.py
+++ b/lib/spack/spack/builder.py
@@ -10,7 +10,7 @@ from typing import List, Optional, Tuple
 
 from llnl.util import lang
 
-import spack.build_environment
+import spack.error
 import spack.multimethod
 
 #: Builder classes, as registered by the "builder" decorator
@@ -461,15 +461,13 @@ class InstallationPhase:
         # If a phase has a matching stop_before_phase attribute,
         # stop the installation process raising a StopPhase
         if getattr(instance, "stop_before_phase", None) == self.name:
-            raise spack.build_environment.StopPhase(
-                "Stopping before '{0}' phase".format(self.name)
-            )
+            raise spack.error.StopPhase("Stopping before '{0}' phase".format(self.name))
 
     def _on_phase_exit(self, instance):
         # If a phase has a matching last_phase attribute,
         # stop the installation process raising a StopPhase
         if getattr(instance, "last_phase", None) == self.name:
-            raise spack.build_environment.StopPhase("Stopping at '{0}' phase".format(self.name))
+            raise spack.error.StopPhase("Stopping at '{0}' phase".format(self.name))
 
     def copy(self):
         return copy.deepcopy(self)
diff --git a/lib/spack/spack/ci.py b/lib/spack/spack/ci.py
index 2420bf4df7..9772d05f36 100644
--- a/lib/spack/spack/ci.py
+++ b/lib/spack/spack/ci.py
@@ -31,6 +31,7 @@ from llnl.util.tty.color import cescape, colorize
 
 import spack
 import spack.binary_distribution as bindist
+import spack.concretize
 import spack.config as cfg
 import spack.environment as ev
 import spack.main
diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py
index 362dcb8d93..c481e93131 100644
--- a/lib/spack/spack/cmd/__init__.py
+++ b/lib/spack/spack/cmd/__init__.py
@@ -17,7 +17,7 @@ from llnl.util.lang import attr_setdefault, index_by
 from llnl.util.tty.colify import colify
 from llnl.util.tty.color import colorize
 
-import spack.config
+import spack.config  # breaks a cycle.
 import spack.environment as ev
 import spack.error
 import spack.extensions
diff --git a/lib/spack/spack/cmd/arch.py b/lib/spack/spack/cmd/arch.py
index 56f597d778..1634784148 100644
--- a/lib/spack/spack/cmd/arch.py
+++ b/lib/spack/spack/cmd/arch.py
@@ -11,6 +11,7 @@ import llnl.util.tty.colify as colify
 import llnl.util.tty.color as color
 
 import spack.platforms
+import spack.spec
 
 description = "print architecture information about this machine"
 section = "system"
diff --git a/lib/spack/spack/cmd/bootstrap.py b/lib/spack/spack/cmd/bootstrap.py
index ffc4615278..8704f2c7a4 100644
--- a/lib/spack/spack/cmd/bootstrap.py
+++ b/lib/spack/spack/cmd/bootstrap.py
@@ -20,6 +20,7 @@ import spack.mirror
 import spack.spec
 import spack.stage
 import spack.util.path
+import spack.util.spack_yaml
 from spack.cmd.common import arguments
 
 description = "manage bootstrap configuration"
diff --git a/lib/spack/spack/cmd/change.py b/lib/spack/spack/cmd/change.py
index 9807d5cc55..d2c8d9ae5d 100644
--- a/lib/spack/spack/cmd/change.py
+++ b/lib/spack/spack/cmd/change.py
@@ -4,6 +4,7 @@
 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
 
 import spack.cmd
+import spack.spec
 from spack.cmd.common import arguments
 
 description = "change an existing spec in an environment"
diff --git a/lib/spack/spack/cmd/clean.py b/lib/spack/spack/cmd/clean.py
index 4a8d238dbd..0b8fb6d6bb 100644
--- a/lib/spack/spack/cmd/clean.py
+++ b/lib/spack/spack/cmd/clean.py
@@ -11,6 +11,7 @@ import llnl.util.filesystem
 import llnl.util.tty as tty
 
 import spack.caches
+import spack.cmd
 import spack.config
 import spack.stage
 import spack.store
diff --git a/lib/spack/spack/cmd/commands.py b/lib/spack/spack/cmd/commands.py
index a6616061ed..875d34ee35 100644
--- a/lib/spack/spack/cmd/commands.py
+++ b/lib/spack/spack/cmd/commands.py
@@ -17,6 +17,7 @@ from llnl.util.argparsewriter import ArgparseRstWriter, ArgparseWriter, Command
 from llnl.util.tty.colify import colify
 
 import spack.cmd
+import spack.config
 import spack.main
 import spack.paths
 import spack.platforms
diff --git a/lib/spack/spack/cmd/common/confirmation.py b/lib/spack/spack/cmd/common/confirmation.py
index 8033e776b9..7e805b196c 100644
--- a/lib/spack/spack/cmd/common/confirmation.py
+++ b/lib/spack/spack/cmd/common/confirmation.py
@@ -9,6 +9,7 @@ from typing import List
 import llnl.util.tty as tty
 
 import spack.cmd
+import spack.spec
 
 display_args = {"long": True, "show_flags": False, "variants": False, "indent": 4}
 
diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py
index fdecc0156e..5c2a02f042 100644
--- a/lib/spack/spack/cmd/config.py
+++ b/lib/spack/spack/cmd/config.py
@@ -13,7 +13,9 @@ import llnl.util.tty as tty
 
 import spack.config
 import spack.environment as ev
+import spack.error
 import spack.schema.env
+import spack.spec
 import spack.store
 import spack.util.spack_yaml as syaml
 from spack.cmd.common import arguments
@@ -254,7 +256,7 @@ def config_remove(args):
         existing.pop(value, None)
     else:
         # This should be impossible to reach
-        raise spack.config.ConfigError("Config has nested non-dict values")
+        raise spack.error.ConfigError("Config has nested non-dict values")
 
     spack.config.set(path, existing, scope)
 
@@ -338,7 +340,7 @@ def _config_change(config_path, match_spec_str=None):
         if not changed:
             existing_requirements = spack.config.get(key_path)
             if isinstance(existing_requirements, str):
-                raise spack.config.ConfigError(
+                raise spack.error.ConfigError(
                     "'config change' needs to append a requirement,"
                     " but existing require: config is not a list"
                 )
diff --git a/lib/spack/spack/cmd/debug.py b/lib/spack/spack/cmd/debug.py
index a920784e54..02c22c70fd 100644
--- a/lib/spack/spack/cmd/debug.py
+++ b/lib/spack/spack/cmd/debug.py
@@ -16,6 +16,8 @@ from llnl.util.filesystem import working_dir
 import spack
 import spack.paths
 import spack.platforms
+import spack.spec
+import spack.store
 import spack.util.git
 from spack.util.executable import which
 
diff --git a/lib/spack/spack/cmd/dev_build.py b/lib/spack/spack/cmd/dev_build.py
index 0a8dc49309..b289d07dc9 100644
--- a/lib/spack/spack/cmd/dev_build.py
+++ b/lib/spack/spack/cmd/dev_build.py
@@ -8,7 +8,9 @@ import sys
 
 import llnl.util.tty as tty
 
+import spack.build_environment
 import spack.cmd
+import spack.cmd.common.arguments
 import spack.config
 import spack.repo
 from spack.cmd.common import arguments
diff --git a/lib/spack/spack/cmd/env.py b/lib/spack/spack/cmd/env.py
index 5494773c2f..fcdc719cc1 100644
--- a/lib/spack/spack/cmd/env.py
+++ b/lib/spack/spack/cmd/env.py
@@ -25,6 +25,7 @@ import spack.cmd.modules
 import spack.config
 import spack.environment as ev
 import spack.environment.depfile as depfile
+import spack.environment.environment
 import spack.environment.shell
 import spack.tengine
 from spack.cmd.common import arguments
diff --git a/lib/spack/spack/cmd/external.py b/lib/spack/spack/cmd/external.py
index 2c0d26edc2..ca32035cd7 100644
--- a/lib/spack/spack/cmd/external.py
+++ b/lib/spack/spack/cmd/external.py
@@ -18,6 +18,7 @@ import spack.config
 import spack.cray_manifest as cray_manifest
 import spack.detection
 import spack.error
+import spack.package_base
 import spack.repo
 import spack.spec
 from spack.cmd.common import arguments
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 3674cae4cf..2f25683c5e 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -11,8 +11,10 @@ import llnl.util.tty as tty
 import llnl.util.tty.color as color
 
 import spack.cmd as cmd
+import spack.config
 import spack.environment as ev
 import spack.repo
+import spack.spec
 import spack.store
 from spack.cmd.common import arguments
 from spack.database import InstallStatuses
diff --git a/lib/spack/spack/cmd/info.py b/lib/spack/spack/cmd/info.py
index a576677052..5ea99caa3a 100644
--- a/lib/spack/spack/cmd/info.py
+++ b/lib/spack/spack/cmd/info.py
@@ -16,6 +16,7 @@ import spack.fetch_strategy as fs
 import spack.install_test
 import spack.repo
 import spack.spec
+import spack.variant
 import spack.version
 from spack.cmd.common import arguments
 from spack.package_base import preferred_version
diff --git a/lib/spack/spack/cmd/install.py b/lib/spack/spack/cmd/install.py
index c262d569bc..27b2ededcd 100644
--- a/lib/spack/spack/cmd/install.py
+++ b/lib/spack/spack/cmd/install.py
@@ -13,7 +13,6 @@ import llnl.util.filesystem as fs
 from llnl.string import plural
 from llnl.util import lang, tty
 
-import spack.build_environment
 import spack.cmd
 import spack.config
 import spack.environment as ev
@@ -22,7 +21,7 @@ import spack.report
 import spack.spec
 import spack.store
 from spack.cmd.common import arguments
-from spack.error import SpackError
+from spack.error import InstallError, SpackError
 from spack.installer import PackageInstaller
 
 description = "build and install packages"
@@ -285,7 +284,7 @@ def require_user_confirmation_for_overwrite(concrete_specs, args):
         tty.die("Reinstallation aborted.")
 
 
-def _dump_log_on_error(e: spack.build_environment.InstallError):
+def _dump_log_on_error(e: InstallError):
     e.print_context()
     assert e.pkg, "Expected InstallError to include the associated package"
     if not os.path.exists(e.pkg.log_path):
@@ -350,7 +349,7 @@ def install(parser, args):
             install_with_active_env(env, args, install_kwargs, reporter_factory)
         else:
             install_without_active_env(args, install_kwargs, reporter_factory)
-    except spack.build_environment.InstallError as e:
+    except InstallError as e:
         if args.show_log_on_error:
             _dump_log_on_error(e)
         raise
diff --git a/lib/spack/spack/cmd/load.py b/lib/spack/spack/cmd/load.py
index a868494a32..d88d4b771f 100644
--- a/lib/spack/spack/cmd/load.py
+++ b/lib/spack/spack/cmd/load.py
@@ -6,6 +6,7 @@
 import sys
 
 import spack.cmd
+import spack.cmd.common
 import spack.environment as ev
 import spack.store
 import spack.user_environment as uenv
diff --git a/lib/spack/spack/cmd/modules/__init__.py b/lib/spack/spack/cmd/modules/__init__.py
index 1cb04189b9..4cf940ca17 100644
--- a/lib/spack/spack/cmd/modules/__init__.py
+++ b/lib/spack/spack/cmd/modules/__init__.py
@@ -15,6 +15,7 @@ from llnl.util.tty import color
 
 import spack.cmd
 import spack.config
+import spack.error
 import spack.modules
 import spack.modules.common
 import spack.repo
@@ -124,13 +125,13 @@ def check_module_set_name(name):
     names = [k for k in modules if k != "prefix_inspections"]
 
     if not names:
-        raise spack.config.ConfigError(
+        raise spack.error.ConfigError(
             f"Module set configuration is missing. Cannot use module set '{name}'"
         )
 
     pretty_names = "', '".join(names)
 
-    raise spack.config.ConfigError(
+    raise spack.error.ConfigError(
         f"Cannot use invalid module set '{name}'.",
         f"Valid module set names are: '{pretty_names}'.",
     )
diff --git a/lib/spack/spack/cmd/python.py b/lib/spack/spack/cmd/python.py
index a4f177fa38..6f96234642 100644
--- a/lib/spack/spack/cmd/python.py
+++ b/lib/spack/spack/cmd/python.py
@@ -78,8 +78,8 @@ def python(parser, args, unknown_args):
 
     # Run user choice of interpreter
     if args.python_interpreter == "ipython":
-        return spack.cmd.python.ipython_interpreter(args)
-    return spack.cmd.python.python_interpreter(args)
+        return ipython_interpreter(args)
+    return python_interpreter(args)
 
 
 def ipython_interpreter(args):
diff --git a/lib/spack/spack/cmd/solve.py b/lib/spack/spack/cmd/solve.py
index 47d733fe63..f5a9c09c3d 100644
--- a/lib/spack/spack/cmd/solve.py
+++ b/lib/spack/spack/cmd/solve.py
@@ -12,10 +12,12 @@ import llnl.util.tty.color as color
 
 import spack
 import spack.cmd
+import spack.cmd.common.arguments
 import spack.config
 import spack.environment
 import spack.hash_types as ht
 import spack.solver.asp as asp
+import spack.spec
 from spack.cmd.common import arguments
 
 description = "concretize a specs using an ASP solver"
diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py
index ae08e1f977..e5cc951d69 100644
--- a/lib/spack/spack/cmd/spec.py
+++ b/lib/spack/spack/cmd/spec.py
@@ -14,6 +14,7 @@ import spack.environment as ev
 import spack.hash_types as ht
 import spack.spec
 import spack.store
+import spack.traverse
 from spack.cmd.common import arguments
 
 description = "show what would be installed, given a spec"
diff --git a/lib/spack/spack/cmd/tags.py b/lib/spack/spack/cmd/tags.py
index 736b3062c5..e43740abc7 100644
--- a/lib/spack/spack/cmd/tags.py
+++ b/lib/spack/spack/cmd/tags.py
@@ -9,6 +9,7 @@ import llnl.string
 import llnl.util.tty as tty
 import llnl.util.tty.colify as colify
 
+import spack.environment
 import spack.repo
 import spack.tag
 
diff --git a/lib/spack/spack/cmd/test.py b/lib/spack/spack/cmd/test.py
index 4eedb0d370..d3d45dbe46 100644
--- a/lib/spack/spack/cmd/test.py
+++ b/lib/spack/spack/cmd/test.py
@@ -15,10 +15,12 @@ from llnl.util import lang, tty
 from llnl.util.tty import colify
 
 import spack.cmd
+import spack.config
 import spack.environment as ev
 import spack.install_test
 import spack.repo
 import spack.report
+import spack.store
 from spack.cmd.common import arguments
 
 description = "run spack's tests for an install"
diff --git a/lib/spack/spack/cmd/tutorial.py b/lib/spack/spack/cmd/tutorial.py
index 3dd7746f81..478ca52b7f 100644
--- a/lib/spack/spack/cmd/tutorial.py
+++ b/lib/spack/spack/cmd/tutorial.py
@@ -10,6 +10,7 @@ import llnl.util.tty as tty
 from llnl.util.filesystem import working_dir
 
 import spack
+import spack.cmd
 import spack.config
 import spack.paths
 import spack.util.git
diff --git a/lib/spack/spack/cmd/undevelop.py b/lib/spack/spack/cmd/undevelop.py
index 539ddb850d..a4c6371ae5 100644
--- a/lib/spack/spack/cmd/undevelop.py
+++ b/lib/spack/spack/cmd/undevelop.py
@@ -6,6 +6,7 @@
 import llnl.util.tty as tty
 
 import spack.cmd
+import spack.config
 from spack.cmd.common import arguments
 
 description = "remove specs from an environment"
diff --git a/lib/spack/spack/cmd/unit_test.py b/lib/spack/spack/cmd/unit_test.py
index c46012d5dc..4717c9ee9b 100644
--- a/lib/spack/spack/cmd/unit_test.py
+++ b/lib/spack/spack/cmd/unit_test.py
@@ -10,6 +10,8 @@ import os.path
 import re
 import sys
 
+import spack.extensions
+
 try:
     import pytest
 except ImportError:
diff --git a/lib/spack/spack/cmd/unload.py b/lib/spack/spack/cmd/unload.py
index a6ea80e582..f937ebd313 100644
--- a/lib/spack/spack/cmd/unload.py
+++ b/lib/spack/spack/cmd/unload.py
@@ -7,7 +7,9 @@ import os
 import sys
 
 import spack.cmd
+import spack.cmd.common
 import spack.error
+import spack.store
 import spack.user_environment as uenv
 from spack.cmd.common import arguments
 
diff --git a/lib/spack/spack/cmd/verify.py b/lib/spack/spack/cmd/verify.py
index 383e9e046b..57b3078832 100644
--- a/lib/spack/spack/cmd/verify.py
+++ b/lib/spack/spack/cmd/verify.py
@@ -6,6 +6,7 @@ import argparse
 
 import llnl.util.tty as tty
 
+import spack.cmd
 import spack.environment as ev
 import spack.store
 import spack.verify
diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py
index 82962d36fb..34dd133d97 100644
--- a/lib/spack/spack/config.py
+++ b/lib/spack/spack/config.py
@@ -39,6 +39,7 @@ from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Union
 
 from llnl.util import filesystem, lang, tty
 
+import spack.error
 import spack.paths
 import spack.platforms
 import spack.schema
@@ -48,17 +49,21 @@ import spack.schema.ci
 import spack.schema.compilers
 import spack.schema.concretizer
 import spack.schema.config
+import spack.schema.definitions
+import spack.schema.develop
 import spack.schema.env
 import spack.schema.mirrors
 import spack.schema.modules
 import spack.schema.packages
 import spack.schema.repos
 import spack.schema.upstreams
+import spack.schema.view
+import spack.spec
 
 # Hacked yaml for configuration files preserves line numbers.
 import spack.util.spack_yaml as syaml
 import spack.util.web as web_util
-from spack.error import SpackError
+from spack.error import SpecSyntaxError
 from spack.util.cpus import cpus_available
 
 #: Dict from section names -> schema for that section
@@ -165,7 +170,7 @@ class DirectoryConfigScope(ConfigScope):
 
     def _write_section(self, section: str) -> None:
         if not self.writable:
-            raise ConfigError(f"Cannot write to immutable scope {self}")
+            raise spack.error.ConfigError(f"Cannot write to immutable scope {self}")
 
         filename = self.get_section_filename(section)
         data = self.get_section(section)
@@ -277,7 +282,7 @@ class SingleFileScope(ConfigScope):
 
     def _write_section(self, section: str) -> None:
         if not self.writable:
-            raise ConfigError(f"Cannot write to immutable scope {self}")
+            raise spack.error.ConfigError(f"Cannot write to immutable scope {self}")
         data_to_write: Optional[YamlConfigDict] = self._raw_data
 
         # If there is no existing data, this section SingleFileScope has never
@@ -705,7 +710,7 @@ class Configuration:
             data[section] = self.get_config(section, scope=scope)
             syaml.dump_config(data, stream=sys.stdout, default_flow_style=False, blame=blame)
         except (syaml.SpackYAMLError, OSError) as e:
-            raise ConfigError(f"cannot read '{section}' configuration") from e
+            raise spack.error.ConfigError(f"cannot read '{section}' configuration") from e
 
 
 @contextlib.contextmanager
@@ -807,7 +812,7 @@ def _add_command_line_scopes(
             _add_platform_scope(cfg, name, path, writable=False)
             continue
         else:
-            raise ConfigError(f"Invalid configuration scope: {path}")
+            raise spack.error.ConfigError(f"Invalid configuration scope: {path}")
 
         for scope in manifest.env_config_scopes:
             scope.name = f"{name}:{scope.name}"
@@ -1019,7 +1024,7 @@ def change_or_add(
 
     if found:
         update_fn(section)
-        spack.config.set(section_name, section, scope=scope)
+        CONFIG.set(section_name, section, scope=scope)
         return
 
     # If no scope meets the criteria specified by ``find_fn``,
@@ -1032,14 +1037,14 @@ def change_or_add(
             break
 
     if found:
-        spack.config.set(section_name, section, scope=scope)
+        CONFIG.set(section_name, section, scope=scope)
         return
 
     # If no scopes define any config for the named section, then
     # modify the highest-priority scope.
     scope, section = configs_by_section[0]
     update_fn(section)
-    spack.config.set(section_name, section, scope=scope)
+    CONFIG.set(section_name, section, scope=scope)
 
 
 def update_all(section_name: str, change_fn: Callable[[str], bool]) -> None:
@@ -1051,7 +1056,7 @@ def update_all(section_name: str, change_fn: Callable[[str], bool]) -> None:
     for scope, section in configs_by_section:
         modified = change_fn(section)
         if modified:
-            spack.config.set(section_name, section, scope=scope)
+            CONFIG.set(section_name, section, scope=scope)
 
 
 def _validate_section_name(section: str) -> None:
@@ -1225,7 +1230,7 @@ def get_valid_type(path):
                     return types[schema_type]()
     else:
         return type(None)
-    raise ConfigError(f"Cannot determine valid type for path '{path}'.")
+    raise spack.error.ConfigError(f"Cannot determine valid type for path '{path}'.")
 
 
 def remove_yaml(dest, source):
@@ -1268,7 +1273,7 @@ def remove_yaml(dest, source):
             unmerge = sk in dest
             old_dest_value = dest.pop(sk, None)
 
-            if unmerge and not spack.config._override(sk):
+            if unmerge and not _override(sk):
                 dest[sk] = remove_yaml(old_dest_value, sv)
 
         return dest
@@ -1718,27 +1723,23 @@ def parse_spec_from_yaml_string(string: str) -> "spack.spec.Spec":
     try:
         spec = spack.spec.Spec(string)
         return spec
-    except spack.parser.SpecSyntaxError as e:
-        mark = spack.config.get_mark_from_yaml_data(string)
+    except SpecSyntaxError as e:
+        mark = get_mark_from_yaml_data(string)
         if mark:
             msg = f"{mark.name}:{mark.line + 1}: {str(e)}"
-            raise spack.parser.SpecSyntaxError(msg) from e
+            raise SpecSyntaxError(msg) from e
         raise e
 
 
-class ConfigError(SpackError):
-    """Superclass for all Spack config related errors."""
-
-
-class ConfigSectionError(ConfigError):
+class ConfigSectionError(spack.error.ConfigError):
     """Error for referring to a bad config section name in a configuration."""
 
 
-class ConfigFileError(ConfigError):
+class ConfigFileError(spack.error.ConfigError):
     """Issue reading or accessing a configuration file."""
 
 
-class ConfigFormatError(ConfigError):
+class ConfigFormatError(spack.error.ConfigError):
     """Raised when a configuration format does not match its schema."""
 
     def __init__(
diff --git a/lib/spack/spack/detection/common.py b/lib/spack/spack/detection/common.py
index addcd1797d..1b16aa6ccd 100644
--- a/lib/spack/spack/detection/common.py
+++ b/lib/spack/spack/detection/common.py
@@ -25,8 +25,10 @@ from typing import Dict, List, Optional, Set, Tuple, Union
 import llnl.util.tty
 
 import spack.config
+import spack.error
 import spack.operating_systems.windows_os as winOs
 import spack.spec
+import spack.util.environment
 import spack.util.spack_yaml
 import spack.util.windows_registry
 
diff --git a/lib/spack/spack/detection/path.py b/lib/spack/spack/detection/path.py
index ec94b71f14..3588d96115 100644
--- a/lib/spack/spack/detection/path.py
+++ b/lib/spack/spack/detection/path.py
@@ -18,6 +18,7 @@ import llnl.util.filesystem
 import llnl.util.lang
 import llnl.util.tty
 
+import spack.spec
 import spack.util.elf as elf_utils
 import spack.util.environment
 import spack.util.environment as environment
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index 7b715d14d3..19f5582bce 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -16,7 +16,9 @@ from llnl.util.symlink import readlink
 
 import spack.config
 import spack.hash_types as ht
+import spack.projections
 import spack.spec
+import spack.store
 import spack.util.spack_json as sjson
 from spack.error import SpackError
 
diff --git a/lib/spack/spack/environment/environment.py b/lib/spack/spack/environment/environment.py
index 727fd7f234..1d2ea86c9d 100644
--- a/lib/spack/spack/environment/environment.py
+++ b/lib/spack/spack/environment/environment.py
@@ -30,13 +30,16 @@ import spack.compilers
 import spack.concretize
 import spack.config
 import spack.deptypes as dt
+import spack.environment
 import spack.error
 import spack.filesystem_view as fsv
 import spack.hash_types as ht
 import spack.paths
 import spack.repo
 import spack.schema.env
+import spack.schema.merged
 import spack.spec
+import spack.spec_list
 import spack.store
 import spack.user_environment as uenv
 import spack.util.cpus
diff --git a/lib/spack/spack/error.py b/lib/spack/spack/error.py
index ea37d5787b..edb4b9e89f 100644
--- a/lib/spack/spack/error.py
+++ b/lib/spack/spack/error.py
@@ -144,3 +144,48 @@ class PatchDirectiveError(SpackError):
 
 class PatchLookupError(NoSuchPatchError):
     """Raised when a patch file cannot be located from sha256."""
+
+
+class SpecSyntaxError(Exception):
+    """Base class for Spec syntax errors"""
+
+
+class PackageError(SpackError):
+    """Raised when something is wrong with a package definition."""
+
+    def __init__(self, message, long_msg=None):
+        super().__init__(message, long_msg)
+
+
+class NoURLError(PackageError):
+    """Raised when someone tries to build a URL for a package with no URLs."""
+
+    def __init__(self, cls):
+        super().__init__("Package %s has no version with a URL." % cls.__name__)
+
+
+class InstallError(SpackError):
+    """Raised when something goes wrong during install or uninstall.
+
+    The error can be annotated with a ``pkg`` attribute to allow the
+    caller to get the package for which the exception was raised.
+    """
+
+    def __init__(self, message, long_msg=None, pkg=None):
+        super().__init__(message, long_msg)
+        self.pkg = pkg
+
+
+class ConfigError(SpackError):
+    """Superclass for all Spack config related errors."""
+
+
+class StopPhase(SpackError):
+    """Pickle-able exception to control stopped builds."""
+
+    def __reduce__(self):
+        return _make_stop_phase, (self.message, self.long_message)
+
+
+def _make_stop_phase(msg, long_msg):
+    return StopPhase(msg, long_msg)
diff --git a/lib/spack/spack/extensions.py b/lib/spack/spack/extensions.py
index a561c50ecf..e13e3f17d4 100644
--- a/lib/spack/spack/extensions.py
+++ b/lib/spack/spack/extensions.py
@@ -17,6 +17,7 @@ from typing import List
 
 import llnl.util.lang
 
+import spack.cmd
 import spack.config
 import spack.error
 import spack.util.path
diff --git a/lib/spack/spack/fetch_strategy.py b/lib/spack/spack/fetch_strategy.py
index a4e8fcc203..54e8a80b8a 100644
--- a/lib/spack/spack/fetch_strategy.py
+++ b/lib/spack/spack/fetch_strategy.py
@@ -1541,7 +1541,7 @@ def _extrapolate(pkg, version):
     """Create a fetcher from an extrapolated URL for this version."""
     try:
         return URLFetchStrategy(url=pkg.url_for_version(version), fetch_options=pkg.fetch_options)
-    except spack.package_base.NoURLError:
+    except spack.error.NoURLError:
         raise ExtrapolationError(
             f"Can't extrapolate a URL for version {version} because "
             f"package {pkg.name} defines no URLs"
diff --git a/lib/spack/spack/graph.py b/lib/spack/spack/graph.py
index 684a6061fb..f4ac437df9 100644
--- a/lib/spack/spack/graph.py
+++ b/lib/spack/spack/graph.py
@@ -46,6 +46,7 @@ import spack.deptypes as dt
 import spack.repo
 import spack.spec
 import spack.tengine
+import spack.traverse
 
 
 def find(seq, predicate):
diff --git a/lib/spack/spack/install_test.py b/lib/spack/spack/install_test.py
index f0b62523d1..9bd171f017 100644
--- a/lib/spack/spack/install_test.py
+++ b/lib/spack/spack/install_test.py
@@ -33,7 +33,7 @@ import spack.spec
 import spack.util.executable
 import spack.util.path
 import spack.util.spack_json as sjson
-from spack.installer import InstallError
+from spack.error import InstallError
 from spack.spec import Spec
 from spack.util.prefix import Prefix
 
@@ -119,7 +119,7 @@ def cache_extra_test_sources(pkg: Pb, srcs: ListOrStringType):
             location(s) under the install testing directory.
 
     Raises:
-        spack.installer.InstallError: if any of the source paths are absolute
+        spack.error.InstallError: if any of the source paths are absolute
             or do not exist
             under the build stage
     """
diff --git a/lib/spack/spack/installer.py b/lib/spack/spack/installer.py
index 42325e22f7..fd46b9006d 100644
--- a/lib/spack/spack/installer.py
+++ b/lib/spack/spack/installer.py
@@ -889,7 +889,7 @@ class BuildTask:
         # ensure priority queue invariants when tasks are "removed" from the
         # queue.
         if status == STATUS_REMOVED:
-            raise InstallError(
+            raise spack.error.InstallError(
                 f"Cannot create a build task for {self.pkg_id} with status '{status}'", pkg=pkg
             )
 
@@ -1160,7 +1160,7 @@ class PackageInstaller:
             if spack.store.STORE.failure_tracker.has_failed(dep):
                 action = "'spack install' the dependency"
                 msg = f"{dep_id} is marked as an install failure: {action}"
-                raise InstallError(err.format(request.pkg_id, msg), pkg=dep_pkg)
+                raise spack.error.InstallError(err.format(request.pkg_id, msg), pkg=dep_pkg)
 
             # Attempt to get a read lock to ensure another process does not
             # uninstall the dependency while the requested spec is being
@@ -1168,7 +1168,7 @@ class PackageInstaller:
             ltype, lock = self._ensure_locked("read", dep_pkg)
             if lock is None:
                 msg = f"{dep_id} is write locked by another process"
-                raise InstallError(err.format(request.pkg_id, msg), pkg=request.pkg)
+                raise spack.error.InstallError(err.format(request.pkg_id, msg), pkg=request.pkg)
 
             # Flag external and upstream packages as being installed
             if dep_pkg.spec.external or dep_pkg.spec.installed_upstream:
@@ -1220,7 +1220,7 @@ class PackageInstaller:
         if not installed_in_db:
             # Ensure there is no other installed spec with the same prefix dir
             if spack.store.STORE.db.is_occupied_install_prefix(task.pkg.spec.prefix):
-                raise InstallError(
+                raise spack.error.InstallError(
                     f"Install prefix collision for {task.pkg_id}",
                     long_msg=f"Prefix directory {task.pkg.spec.prefix} already "
                     "used by another installed spec.",
@@ -1488,7 +1488,9 @@ class PackageInstaller:
                 self._update_installed(task)
                 return
             elif cache_only:
-                raise InstallError("No binary found when cache-only was specified", pkg=pkg)
+                raise spack.error.InstallError(
+                    "No binary found when cache-only was specified", pkg=pkg
+                )
             else:
                 tty.msg(f"No binary for {pkg_id} found: installing from source")
 
@@ -1515,7 +1517,7 @@ class PackageInstaller:
             # the database, so that we don't need to re-read from file.
             spack.store.STORE.db.add(pkg.spec, explicit=explicit)
 
-        except spack.build_environment.StopPhase as e:
+        except spack.error.StopPhase as e:
             # A StopPhase exception means that do_install was asked to
             # stop early from clients, and is not an error at this point
             pid = f"{self.pid}: " if tty.show_pid() else ""
@@ -1848,7 +1850,7 @@ class PackageInstaller:
                     tty.warn(f"{pkg_id} does NOT actually have any uninstalled deps left")
                 dep_str = "dependencies" if task.priority > 1 else "dependency"
 
-                raise InstallError(
+                raise spack.error.InstallError(
                     f"Cannot proceed with {pkg_id}: {task.priority} uninstalled "
                     f"{dep_str}: {','.join(task.uninstalled_deps)}",
                     pkg=pkg,
@@ -1870,7 +1872,7 @@ class PackageInstaller:
                 self._update_failed(task)
 
                 if self.fail_fast:
-                    raise InstallError(fail_fast_err, pkg=pkg)
+                    raise spack.error.InstallError(fail_fast_err, pkg=pkg)
 
                 continue
 
@@ -1999,7 +2001,7 @@ class PackageInstaller:
                     )
                 # Terminate if requested to do so on the first failure.
                 if self.fail_fast:
-                    raise InstallError(f"{fail_fast_err}: {str(exc)}", pkg=pkg)
+                    raise spack.error.InstallError(f"{fail_fast_err}: {str(exc)}", pkg=pkg)
 
                 # Terminate when a single build request has failed, or summarize errors later.
                 if task.is_build_request:
@@ -2051,7 +2053,7 @@ class PackageInstaller:
                     f"missing package ({ids[0]}) from {', '.join(ids)}"
                 )
 
-            raise InstallError(
+            raise spack.error.InstallError(
                 "Installation request failed.  Refer to reported errors for failing package(s).",
                 pkg=pkg,
             )
@@ -2317,33 +2319,21 @@ class OverwriteInstall:
             raise e.inner_exception
 
 
-class InstallError(spack.error.SpackError):
-    """Raised when something goes wrong during install or uninstall.
-
-    The error can be annotated with a ``pkg`` attribute to allow the
-    caller to get the package for which the exception was raised.
-    """
-
-    def __init__(self, message, long_msg=None, pkg=None):
-        super().__init__(message, long_msg)
-        self.pkg = pkg
-
-
-class BadInstallPhase(InstallError):
+class BadInstallPhase(spack.error.InstallError):
     """Raised for an install phase option is not allowed for a package."""
 
     def __init__(self, pkg_name, phase):
         super().__init__(f"'{phase}' is not a valid phase for package {pkg_name}")
 
 
-class ExternalPackageError(InstallError):
+class ExternalPackageError(spack.error.InstallError):
     """Raised by install() when a package is only for external use."""
 
 
-class InstallLockError(InstallError):
+class InstallLockError(spack.error.InstallError):
     """Raised during install when something goes wrong with package locking."""
 
 
-class UpstreamPackageError(InstallError):
+class UpstreamPackageError(spack.error.InstallError):
     """Raised during install when something goes wrong with an upstream
     package."""
diff --git a/lib/spack/spack/main.py b/lib/spack/spack/main.py
index db5d45034c..eb15789c76 100644
--- a/lib/spack/spack/main.py
+++ b/lib/spack/spack/main.py
@@ -9,6 +9,8 @@ In a normal Spack installation, this is invoked from the bin/spack script
 after the system path is set up.
 """
 import argparse
+
+# import spack.modules.common
 import inspect
 import io
 import operator
@@ -36,6 +38,7 @@ import spack
 import spack.cmd
 import spack.config
 import spack.environment as ev
+import spack.error
 import spack.modules
 import spack.paths
 import spack.platforms
@@ -44,6 +47,7 @@ import spack.spec
 import spack.store
 import spack.util.debug
 import spack.util.environment
+import spack.util.lock
 from spack.error import SpackError
 
 #: names of profile statistics
@@ -763,6 +767,8 @@ def print_setup_info(*info):
     This is in ``main.py`` to make it fast; the setup scripts need to
     invoke spack in login scripts, and it needs to be quick.
     """
+    import spack.modules.common
+
     shell = "csh" if "csh" in info else "sh"
 
     def shell_set(var, value):
diff --git a/lib/spack/spack/mirror.py b/lib/spack/spack/mirror.py
index 02ddeae42a..8caa272137 100644
--- a/lib/spack/spack/mirror.py
+++ b/lib/spack/spack/mirror.py
@@ -29,6 +29,7 @@ import spack.caches
 import spack.config
 import spack.error
 import spack.fetch_strategy
+import spack.mirror
 import spack.oci.image
 import spack.repo
 import spack.spec
diff --git a/lib/spack/spack/modules/common.py b/lib/spack/spack/modules/common.py
index e4f7a197f3..cf81bcaba5 100644
--- a/lib/spack/spack/modules/common.py
+++ b/lib/spack/spack/modules/common.py
@@ -46,6 +46,7 @@ import spack.config
 import spack.deptypes as dt
 import spack.environment
 import spack.error
+import spack.modules
 import spack.paths
 import spack.projections as proj
 import spack.repo
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 99135b4834..d2a00f9941 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -11,6 +11,8 @@ Everything in this module is automatically imported into Spack package files.
 from os import chdir, environ, getcwd, makedirs, mkdir, remove, removedirs
 from shutil import move, rmtree
 
+from spack.error import InstallError
+
 # Emulate some shell commands for convenience
 env = environ
 cd = chdir
@@ -84,12 +86,7 @@ from spack.install_test import (
     install_test_root,
     test_part,
 )
-from spack.installer import (
-    ExternalPackageError,
-    InstallError,
-    InstallLockError,
-    UpstreamPackageError,
-)
+from spack.installer import ExternalPackageError, InstallLockError, UpstreamPackageError
 from spack.mixins import filter_compiler_wrappers
 from spack.multimethod import default_args, when
 from spack.package_base import (
diff --git a/lib/spack/spack/package_base.py b/lib/spack/spack/package_base.py
index 382d0b25f7..e2c7069ef8 100644
--- a/lib/spack/spack/package_base.py
+++ b/lib/spack/spack/package_base.py
@@ -33,6 +33,8 @@ import llnl.util.tty as tty
 from llnl.util.lang import classproperty, memoized
 from llnl.util.link_tree import LinkTree
 
+import spack.build_environment
+import spack.builder
 import spack.compilers
 import spack.config
 import spack.dependency
@@ -50,8 +52,10 @@ import spack.spec
 import spack.store
 import spack.url
 import spack.util.environment
+import spack.util.executable
 import spack.util.path
 import spack.util.web
+from spack.error import InstallError, NoURLError, PackageError
 from spack.filesystem_view import YamlFilesystemView
 from spack.install_test import (
     PackageTest,
@@ -61,7 +65,7 @@ from spack.install_test import (
     cache_extra_test_sources,
     install_test_root,
 )
-from spack.installer import InstallError, PackageInstaller
+from spack.installer import PackageInstaller
 from spack.solver.version_order import concretization_version_order
 from spack.stage import DevelopStage, ResourceStage, Stage, StageComposite, compute_stage_name
 from spack.util.executable import ProcessError, which
@@ -2581,20 +2585,6 @@ class PackageStillNeededError(InstallError):
         self.dependents = dependents
 
 
-class PackageError(spack.error.SpackError):
-    """Raised when something is wrong with a package definition."""
-
-    def __init__(self, message, long_msg=None):
-        super().__init__(message, long_msg)
-
-
-class NoURLError(PackageError):
-    """Raised when someone tries to build a URL for a package with no URLs."""
-
-    def __init__(self, cls):
-        super().__init__("Package %s has no version with a URL." % cls.__name__)
-
-
 class InvalidPackageOpError(PackageError):
     """Raised when someone tries perform an invalid operation on a package."""
 
diff --git a/lib/spack/spack/package_prefs.py b/lib/spack/spack/package_prefs.py
index 2c8644e0b2..f655fbb885 100644
--- a/lib/spack/spack/package_prefs.py
+++ b/lib/spack/spack/package_prefs.py
@@ -9,7 +9,7 @@ import spack.config
 import spack.error
 import spack.repo
 import spack.spec
-from spack.config import ConfigError
+from spack.error import ConfigError
 from spack.version import Version
 
 _lesser_spec_types = {"compiler": spack.spec.CompilerSpec, "version": Version}
diff --git a/lib/spack/spack/parser.py b/lib/spack/spack/parser.py
index 097af99283..23739b6841 100644
--- a/lib/spack/spack/parser.py
+++ b/lib/spack/spack/parser.py
@@ -70,6 +70,7 @@ import spack.deptypes
 import spack.error
 import spack.spec
 import spack.version
+from spack.error import SpecSyntaxError
 
 IS_WINDOWS = sys.platform == "win32"
 #: Valid name for specs and variants. Here we are not using
@@ -600,10 +601,6 @@ def parse_one_or_raise(
     return result
 
 
-class SpecSyntaxError(Exception):
-    """Base class for Spec syntax errors"""
-
-
 class SpecTokenizationError(SpecSyntaxError):
     """Syntax error in a spec string"""
 
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index c376a261a6..764c51a819 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -6,6 +6,7 @@ import collections
 import itertools
 import os
 import re
+import sys
 from collections import OrderedDict
 from typing import List, Optional
 
@@ -17,7 +18,7 @@ import llnl.util.tty as tty
 from llnl.util.lang import memoized
 from llnl.util.symlink import readlink, symlink
 
-import spack.platforms
+import spack.error
 import spack.store
 import spack.util.elf as elf
 import spack.util.executable as executable
@@ -25,8 +26,6 @@ import spack.util.filesystem as ssys
 
 from .relocate_text import BinaryFilePrefixReplacer, TextFilePrefixReplacer
 
-is_macos = str(spack.platforms.real_host()) == "darwin"
-
 
 class InstallRootStringError(spack.error.SpackError):
     def __init__(self, file_path, root_path):
@@ -49,7 +48,7 @@ def _patchelf() -> Optional[executable.Executable]:
     """Return the full path to the patchelf binary, if available, else None."""
     import spack.bootstrap
 
-    if is_macos:
+    if sys.platform == "darwin":
         return None
 
     with spack.bootstrap.ensure_bootstrap_configuration():
@@ -416,7 +415,7 @@ def relocate_macho_binaries(
             # normalized paths
             rel_to_orig = macho_make_paths_normal(orig_path_name, rpaths, deps, idpath)
             # replace the relativized paths with normalized paths
-            if is_macos:
+            if sys.platform == "darwin":
                 modify_macho_object(path_name, rpaths, deps, idpath, rel_to_orig)
             else:
                 modify_object_macholib(path_name, rel_to_orig)
@@ -427,7 +426,7 @@ def relocate_macho_binaries(
                 rpaths, deps, idpath, old_layout_root, prefix_to_prefix
             )
             # replace the old paths with new paths
-            if is_macos:
+            if sys.platform == "darwin":
                 modify_macho_object(path_name, rpaths, deps, idpath, paths_to_paths)
             else:
                 modify_object_macholib(path_name, paths_to_paths)
@@ -438,7 +437,7 @@ def relocate_macho_binaries(
                 path_name, new_layout_root, rpaths, deps, idpath
             )
             # replace the new paths with relativized paths in the new prefix
-            if is_macos:
+            if sys.platform == "darwin":
                 modify_macho_object(path_name, rpaths, deps, idpath, paths_to_paths)
             else:
                 modify_object_macholib(path_name, paths_to_paths)
@@ -450,7 +449,7 @@ def relocate_macho_binaries(
                 rpaths, deps, idpath, old_layout_root, prefix_to_prefix
             )
             # replace the old paths with new paths
-            if is_macos:
+            if sys.platform == "darwin":
                 modify_macho_object(path_name, rpaths, deps, idpath, paths_to_paths)
             else:
                 modify_object_macholib(path_name, paths_to_paths)
@@ -572,7 +571,7 @@ def make_macho_binaries_relative(cur_path_names, orig_path_names, old_layout_roo
     """
     Replace old RPATHs with paths relative to old_dir in binary files
     """
-    if not is_macos:
+    if not sys.platform == "darwin":
         return
 
     for cur_path, orig_path in zip(cur_path_names, orig_path_names):
diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py
index fd1609df83..b916c3baef 100644
--- a/lib/spack/spack/repo.py
+++ b/lib/spack/spack/repo.py
@@ -39,6 +39,7 @@ import spack.config
 import spack.error
 import spack.patch
 import spack.provider_index
+import spack.repo
 import spack.spec
 import spack.tag
 import spack.util.git
@@ -1522,8 +1523,10 @@ class MockRepositoryBuilder:
                 Both "dep_type" and "condition" can default to ``None`` in which case
                 ``spack.dependency.default_deptype`` and ``spack.spec.Spec()`` are used.
         """
+        import spack.tengine  # avoid circular import
+
         dependencies = dependencies or []
-        context = {"cls_name": spack.util.naming.mod_to_class(name), "dependencies": dependencies}
+        context = {"cls_name": nm.mod_to_class(name), "dependencies": dependencies}
         template = spack.tengine.make_environment().get_template("mock-repository/package.pyt")
         text = template.render(context)
         package_py = self.recipe_filename(name)
diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py
index 2ecfacb60b..d2da8bbed2 100644
--- a/lib/spack/spack/reporters/cdash.py
+++ b/lib/spack/spack/reporters/cdash.py
@@ -22,6 +22,8 @@ from llnl.util.filesystem import working_dir
 import spack
 import spack.paths
 import spack.platforms
+import spack.spec
+import spack.tengine
 import spack.util.git
 from spack.error import SpackError
 from spack.util.crypto import checksum
diff --git a/lib/spack/spack/rewiring.py b/lib/spack/spack/rewiring.py
index f2a01cd6d1..bffd085619 100644
--- a/lib/spack/spack/rewiring.py
+++ b/lib/spack/spack/rewiring.py
@@ -14,6 +14,7 @@ from llnl.util.symlink import readlink, symlink
 import spack.binary_distribution as bindist
 import spack.error
 import spack.hooks
+import spack.platforms
 import spack.relocate as relocate
 import spack.store
 
diff --git a/lib/spack/spack/schema/__init__.py b/lib/spack/spack/schema/__init__.py
index 5ccb7dd709..8c04ebdaac 100644
--- a/lib/spack/spack/schema/__init__.py
+++ b/lib/spack/spack/schema/__init__.py
@@ -8,6 +8,8 @@ import warnings
 
 import llnl.util.lang
 
+from spack.error import SpecSyntaxError
+
 
 class DeprecationMessage(typing.NamedTuple):
     message: str
@@ -31,7 +33,7 @@ def _make_validator():
         for spec_str in instance:
             try:
                 spack.parser.parse(spec_str)
-            except spack.parser.SpecSyntaxError as e:
+            except SpecSyntaxError as e:
                 yield jsonschema.ValidationError(str(e))
 
     def _deprecated_properties(validator, deprecated, instance, schema):
diff --git a/lib/spack/spack/schema/config.py b/lib/spack/spack/schema/config.py
index 72590d8e82..e1072a501b 100644
--- a/lib/spack/spack/schema/config.py
+++ b/lib/spack/spack/schema/config.py
@@ -11,6 +11,7 @@ from typing import Any, Dict
 
 from llnl.util.lang import union_dicts
 
+import spack.config
 import spack.schema.projections
 
 #: Properties for inclusion in other schemas
diff --git a/lib/spack/spack/schema/view.py b/lib/spack/spack/schema/view.py
index 6c24501ba9..d3e983167f 100644
--- a/lib/spack/spack/schema/view.py
+++ b/lib/spack/spack/schema/view.py
@@ -11,6 +11,7 @@
 from typing import Any, Dict
 
 import spack.schema
+import spack.schema.projections
 
 projections_scheme = spack.schema.projections.properties["projections"]
 
diff --git a/lib/spack/spack/solver/asp.py b/lib/spack/spack/solver/asp.py
index 9b694d3850..3b98117c1c 100644
--- a/lib/spack/spack/solver/asp.py
+++ b/lib/spack/spack/solver/asp.py
@@ -27,7 +27,9 @@ from llnl.util.lang import elide_list
 
 import spack
 import spack.binary_distribution
+import spack.bootstrap.core
 import spack.compilers
+import spack.concretize
 import spack.config
 import spack.config as sc
 import spack.deptypes as dt
@@ -2166,7 +2168,7 @@ class SpackSolverSetup:
                     matches = [x for x in self.possible_versions[pkg_name] if x.satisfies(v)]
                     matches.sort(reverse=True)
                     if not matches:
-                        raise spack.config.ConfigError(
+                        raise spack.error.ConfigError(
                             f"Preference for version {v} does not match any known "
                             f"version of {pkg_name} (in its package.py or any external)"
                         )
@@ -2796,7 +2798,7 @@ class SpackSolverSetup:
                     # not throw an error, which is just so that users know they need to change
                     # their config, instead of getting a hard to decipher concretization error.
                     if not any(x for x in self.possible_versions[name] if x.satisfies(versions)):
-                        raise spack.config.ConfigError(
+                        raise spack.error.ConfigError(
                             f"Version requirement {versions} on {pkg_name} for {name} "
                             f"cannot match any known version from package.py or externals"
                         )
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index 1e23ebc63f..492841f81a 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -2016,6 +2016,7 @@ class Spec:
     def _lookup_hash(self):
         """Lookup just one spec with an abstract hash, returning a spec from the the environment,
         store, or finally, binary caches."""
+        import spack.binary_distribution
         import spack.environment
 
         active_env = spack.environment.active_environment()
diff --git a/lib/spack/spack/store.py b/lib/spack/spack/store.py
index 62a5b5c4fb..31369531d5 100644
--- a/lib/spack/spack/store.py
+++ b/lib/spack/spack/store.py
@@ -33,6 +33,7 @@ import spack.directory_layout
 import spack.error
 import spack.paths
 import spack.spec
+import spack.store
 import spack.util.path
 
 #: default installation root, relative to the Spack install path
diff --git a/lib/spack/spack/tag.py b/lib/spack/spack/tag.py
index 559af56f0c..fd2b252d83 100644
--- a/lib/spack/spack/tag.py
+++ b/lib/spack/spack/tag.py
@@ -8,11 +8,14 @@ import copy
 from collections.abc import Mapping
 
 import spack.error
+import spack.repo
 import spack.util.spack_json as sjson
 
 
 def _get_installed_package_names():
     """Returns names of packages installed in the active environment."""
+    import spack.environment
+
     specs = spack.environment.installed_specs()
     return [spec.name for spec in specs]
 
diff --git a/lib/spack/spack/target.py b/lib/spack/spack/target.py
index 8d0943c28a..4a78196865 100644
--- a/lib/spack/spack/target.py
+++ b/lib/spack/spack/target.py
@@ -11,6 +11,7 @@ import llnl.util.tty as tty
 import spack.compiler
 import spack.compilers
 import spack.spec
+import spack.util.executable
 import spack.util.spack_yaml as syaml
 
 
diff --git a/lib/spack/spack/test/bindist.py b/lib/spack/spack/test/bindist.py
index a418ef360a..57a810e8cd 100644
--- a/lib/spack/spack/test/bindist.py
+++ b/lib/spack/spack/test/bindist.py
@@ -27,11 +27,15 @@ from llnl.util.symlink import readlink
 
 import spack.binary_distribution as bindist
 import spack.caches
+import spack.compilers
 import spack.config
 import spack.fetch_strategy
 import spack.hooks.sbang as sbang
 import spack.main
 import spack.mirror
+import spack.paths
+import spack.spec
+import spack.stage
 import spack.store
 import spack.util.gpg
 import spack.util.spack_yaml as syaml
diff --git a/lib/spack/spack/test/bootstrap.py b/lib/spack/spack/test/bootstrap.py
index f0d11d4124..603fe90fad 100644
--- a/lib/spack/spack/test/bootstrap.py
+++ b/lib/spack/spack/test/bootstrap.py
@@ -9,6 +9,7 @@ import spack.bootstrap
 import spack.bootstrap.config
 import spack.bootstrap.core
 import spack.compilers
+import spack.config
 import spack.environment
 import spack.store
 import spack.util.path
diff --git a/lib/spack/spack/test/build_environment.py b/lib/spack/spack/test/build_environment.py
index 3ae41acc9c..38d34fc1e8 100644
--- a/lib/spack/spack/test/build_environment.py
+++ b/lib/spack/spack/test/build_environment.py
@@ -16,6 +16,7 @@ import spack.build_environment
 import spack.config
 import spack.deptypes as dt
 import spack.package_base
+import spack.paths
 import spack.spec
 import spack.util.spack_yaml as syaml
 from spack.build_environment import UseMode, _static_to_shared_library, dso_suffix
diff --git a/lib/spack/spack/test/build_systems.py b/lib/spack/spack/test/build_systems.py
index f224982e1a..a28742488a 100644
--- a/lib/spack/spack/test/build_systems.py
+++ b/lib/spack/spack/test/build_systems.py
@@ -16,7 +16,10 @@ import llnl.util.filesystem as fs
 import spack.build_systems.autotools
 import spack.build_systems.cmake
 import spack.environment
+import spack.error
+import spack.paths
 import spack.platforms
+import spack.platforms.test
 from spack.build_environment import ChildError, setup_package
 from spack.spec import Spec
 from spack.util.executable import which
@@ -265,7 +268,7 @@ class TestCMakePackage:
 
     def test_cmake_bad_generator(self, default_mock_concretization):
         s = default_mock_concretization("cmake-client")
-        with pytest.raises(spack.package_base.InstallError):
+        with pytest.raises(spack.error.InstallError):
             spack.build_systems.cmake.CMakeBuilder.std_args(
                 s.package, generator="Yellow Sticky Notes"
             )
diff --git a/lib/spack/spack/test/builder.py b/lib/spack/spack/test/builder.py
index 4bd128c3bf..ab611dbaec 100644
--- a/lib/spack/spack/test/builder.py
+++ b/lib/spack/spack/test/builder.py
@@ -8,7 +8,10 @@ import pytest
 
 from llnl.util.filesystem import touch
 
+import spack.builder
 import spack.paths
+import spack.repo
+import spack.spec
 
 
 @pytest.fixture()
diff --git a/lib/spack/spack/test/buildtask.py b/lib/spack/spack/test/buildtask.py
index 569bfc56d8..61def432c0 100644
--- a/lib/spack/spack/test/buildtask.py
+++ b/lib/spack/spack/test/buildtask.py
@@ -5,6 +5,7 @@
 
 import pytest
 
+import spack.error
 import spack.installer as inst
 import spack.repo
 import spack.spec
@@ -25,7 +26,7 @@ def test_build_task_errors(install_mockery):
         inst.BuildTask(spec.package, None, False, 0, 0, 0, set())
 
     request = inst.BuildRequest(spec.package, {})
-    with pytest.raises(inst.InstallError, match="Cannot create a build task"):
+    with pytest.raises(spack.error.InstallError, match="Cannot create a build task"):
         inst.BuildTask(spec.package, request, False, 0, 0, inst.STATUS_REMOVED, set())
 
 
diff --git a/lib/spack/spack/test/ci.py b/lib/spack/spack/test/ci.py
index 6742e02c74..0c9a10814a 100644
--- a/lib/spack/spack/test/ci.py
+++ b/lib/spack/spack/test/ci.py
@@ -13,6 +13,7 @@ import spack.ci as ci
 import spack.environment as ev
 import spack.error
 import spack.paths as spack_paths
+import spack.spec
 import spack.util.git
 
 
diff --git a/lib/spack/spack/test/cmd/bootstrap.py b/lib/spack/spack/test/cmd/bootstrap.py
index 7797aec31c..888f823c55 100644
--- a/lib/spack/spack/test/cmd/bootstrap.py
+++ b/lib/spack/spack/test/cmd/bootstrap.py
@@ -15,6 +15,7 @@ import spack.config
 import spack.environment as ev
 import spack.main
 import spack.mirror
+import spack.spec
 
 _bootstrap = spack.main.SpackCommand("bootstrap")
 
diff --git a/lib/spack/spack/test/cmd/checksum.py b/lib/spack/spack/test/cmd/checksum.py
index ad63c40ff8..6c20caff88 100644
--- a/lib/spack/spack/test/cmd/checksum.py
+++ b/lib/spack/spack/test/cmd/checksum.py
@@ -8,8 +8,8 @@ import argparse
 import pytest
 
 import spack.cmd.checksum
+import spack.error
 import spack.package_base
-import spack.parser
 import spack.repo
 import spack.spec
 import spack.stage
@@ -304,7 +304,7 @@ def test_checksum_deprecated_version(mock_packages, can_fetch_versions):
 
 def test_checksum_url(mock_packages, config):
     pkg_cls = spack.repo.PATH.get_pkg_class("zlib")
-    with pytest.raises(spack.parser.SpecSyntaxError):
+    with pytest.raises(spack.error.SpecSyntaxError):
         spack_checksum(f"{pkg_cls.url}")
 
 
diff --git a/lib/spack/spack/test/cmd/clean.py b/lib/spack/spack/test/cmd/clean.py
index 4c35868333..8b671e495e 100644
--- a/lib/spack/spack/test/cmd/clean.py
+++ b/lib/spack/spack/test/cmd/clean.py
@@ -14,6 +14,7 @@ import spack.cmd.clean
 import spack.environment as ev
 import spack.main
 import spack.package_base
+import spack.spec
 import spack.stage
 import spack.store
 
diff --git a/lib/spack/spack/test/cmd/commands.py b/lib/spack/spack/test/cmd/commands.py
index b7cc59e115..c0c781cb89 100644
--- a/lib/spack/spack/test/cmd/commands.py
+++ b/lib/spack/spack/test/cmd/commands.py
@@ -10,6 +10,7 @@ import shutil
 import pytest
 
 import spack.cmd
+import spack.cmd.commands
 import spack.main
 import spack.paths
 from spack.cmd.commands import _dest_to_fish_complete, _positional_to_subroutine
diff --git a/lib/spack/spack/test/cmd/compiler.py b/lib/spack/spack/test/cmd/compiler.py
index 2638aa7926..431cdfd787 100644
--- a/lib/spack/spack/test/cmd/compiler.py
+++ b/lib/spack/spack/test/cmd/compiler.py
@@ -10,6 +10,7 @@ import pytest
 
 import spack.cmd.compiler
 import spack.compilers
+import spack.config
 import spack.main
 import spack.spec
 import spack.util.pattern
diff --git a/lib/spack/spack/test/cmd/create.py b/lib/spack/spack/test/cmd/create.py
index 13967adb52..03dc5ec0e6 100644
--- a/lib/spack/spack/test/cmd/create.py
+++ b/lib/spack/spack/test/cmd/create.py
@@ -9,6 +9,7 @@ import tarfile
 import pytest
 
 import spack.cmd.create
+import spack.url
 from spack.main import SpackCommand
 from spack.url import UndetectableNameError
 from spack.util.executable import which
diff --git a/lib/spack/spack/test/cmd/debug.py b/lib/spack/spack/test/cmd/debug.py
index 2cff3b29c6..49f739b543 100644
--- a/lib/spack/spack/test/cmd/debug.py
+++ b/lib/spack/spack/test/cmd/debug.py
@@ -11,6 +11,7 @@ import pytest
 
 import spack
 import spack.platforms
+import spack.spec
 from spack.main import SpackCommand
 from spack.util.executable import which
 
diff --git a/lib/spack/spack/test/cmd/deprecate.py b/lib/spack/spack/test/cmd/deprecate.py
index 8306bea023..867b1cf2e1 100644
--- a/lib/spack/spack/test/cmd/deprecate.py
+++ b/lib/spack/spack/test/cmd/deprecate.py
@@ -5,6 +5,7 @@
 
 import pytest
 
+import spack.spec
 import spack.store
 from spack.database import InstallStatuses
 from spack.main import SpackCommand
diff --git a/lib/spack/spack/test/cmd/dev_build.py b/lib/spack/spack/test/cmd/dev_build.py
index 8545a9dc52..c335ea0ccf 100644
--- a/lib/spack/spack/test/cmd/dev_build.py
+++ b/lib/spack/spack/test/cmd/dev_build.py
@@ -11,6 +11,7 @@ import llnl.util.filesystem as fs
 
 import spack.environment as ev
 import spack.error
+import spack.repo
 import spack.spec
 import spack.store
 from spack.main import SpackCommand
diff --git a/lib/spack/spack/test/cmd/develop.py b/lib/spack/spack/test/cmd/develop.py
index 440a008a3c..202e165165 100644
--- a/lib/spack/spack/test/cmd/develop.py
+++ b/lib/spack/spack/test/cmd/develop.py
@@ -11,7 +11,11 @@ import llnl.util.filesystem as fs
 
 import spack.config
 import spack.environment as ev
+import spack.package_base
 import spack.spec
+import spack.stage
+import spack.util.git
+import spack.util.path
 from spack.main import SpackCommand
 
 add = SpackCommand("add")
diff --git a/lib/spack/spack/test/cmd/diff.py b/lib/spack/spack/test/cmd/diff.py
index 322b33b3d4..e352ce1352 100644
--- a/lib/spack/spack/test/cmd/diff.py
+++ b/lib/spack/spack/test/cmd/diff.py
@@ -7,6 +7,8 @@ import pytest
 
 import spack.cmd.diff
 import spack.main
+import spack.repo
+import spack.spec
 import spack.util.spack_json as sjson
 from spack.test.conftest import create_test_repo
 
diff --git a/lib/spack/spack/test/cmd/env.py b/lib/spack/spack/test/cmd/env.py
index e841b1c845..336cf25c8c 100644
--- a/lib/spack/spack/test/cmd/env.py
+++ b/lib/spack/spack/test/cmd/env.py
@@ -24,11 +24,17 @@ import spack.environment.depfile as depfile
 import spack.environment.environment
 import spack.environment.shell
 import spack.error
+import spack.main
 import spack.modules
+import spack.modules.tcl
 import spack.package_base
 import spack.paths
 import spack.repo
+import spack.solver.asp
+import spack.spec
+import spack.stage
 import spack.store
+import spack.util.environment
 import spack.util.spack_json as sjson
 import spack.util.spack_yaml
 from spack.cmd.env import _env_create
@@ -1160,7 +1166,7 @@ spack:
     )
     with ev.Environment(tmp_path):
         assert spack.spec.Spec("mpich").concretized().satisfies("@3.0.3")
-        with pytest.raises(spack.config.ConfigError, match="not a list"):
+        with pytest.raises(spack.error.ConfigError, match="not a list"):
             config("change", "packages:mpich:require:~debug")
 
 
@@ -1188,7 +1194,7 @@ def test_env_with_included_config_missing_file(tmpdir, mutable_empty_config):
     with spack_yaml.open("w") as f:
         f.write("spack:\n  include:\n    - {0}\n".format(missing_file.strpath))
 
-    with pytest.raises(spack.config.ConfigError, match="missing include path"):
+    with pytest.raises(spack.error.ConfigError, match="missing include path"):
         ev.Environment(tmpdir.strpath)
 
 
diff --git a/lib/spack/spack/test/cmd/external.py b/lib/spack/spack/test/cmd/external.py
index a186552987..684520bea2 100644
--- a/lib/spack/spack/test/cmd/external.py
+++ b/lib/spack/spack/test/cmd/external.py
@@ -12,6 +12,8 @@ from llnl.util.filesystem import getuid, touch
 
 import spack
 import spack.cmd.external
+import spack.config
+import spack.cray_manifest
 import spack.detection
 import spack.detection.path
 import spack.repo
diff --git a/lib/spack/spack/test/cmd/find.py b/lib/spack/spack/test/cmd/find.py
index 59370b0d84..fa8299f2ab 100644
--- a/lib/spack/spack/test/cmd/find.py
+++ b/lib/spack/spack/test/cmd/find.py
@@ -14,6 +14,7 @@ import pytest
 import spack.cmd as cmd
 import spack.cmd.find
 import spack.environment as ev
+import spack.store
 import spack.user_environment as uenv
 from spack.main import SpackCommand
 from spack.spec import Spec
diff --git a/lib/spack/spack/test/cmd/install.py b/lib/spack/spack/test/cmd/install.py
index 748c162db7..da85366165 100644
--- a/lib/spack/spack/test/cmd/install.py
+++ b/lib/spack/spack/test/cmd/install.py
@@ -17,16 +17,18 @@ import pytest
 import llnl.util.filesystem as fs
 import llnl.util.tty as tty
 
+import spack.build_environment
 import spack.cmd.common.arguments
 import spack.cmd.install
 import spack.config
 import spack.environment as ev
+import spack.error
 import spack.hash_types as ht
+import spack.installer
 import spack.package_base
 import spack.store
-from spack.error import SpackError
+from spack.error import SpackError, SpecSyntaxError
 from spack.main import SpackCommand
-from spack.parser import SpecSyntaxError
 from spack.spec import Spec
 
 install = SpackCommand("install")
@@ -420,7 +422,7 @@ def test_junit_output_with_failures(tmpdir, exc_typename, msg):
 @pytest.mark.parametrize(
     "exc_typename,expected_exc,msg",
     [
-        ("RuntimeError", spack.installer.InstallError, "something weird happened"),
+        ("RuntimeError", spack.error.InstallError, "something weird happened"),
         ("KeyboardInterrupt", KeyboardInterrupt, "Ctrl-C strikes again"),
     ],
 )
@@ -704,7 +706,7 @@ def test_install_only_package(tmpdir, mock_fetch, install_mockery, capfd):
     with capfd.disabled():
         try:
             install("--only", "package", "dependent-install")
-        except spack.installer.InstallError as e:
+        except spack.error.InstallError as e:
             msg = str(e)
 
     assert "Cannot proceed with dependent-install" in msg
diff --git a/lib/spack/spack/test/cmd/is_git_repo.py b/lib/spack/spack/test/cmd/is_git_repo.py
index 087f69e028..3dabc8623a 100644
--- a/lib/spack/spack/test/cmd/is_git_repo.py
+++ b/lib/spack/spack/test/cmd/is_git_repo.py
@@ -11,6 +11,8 @@ import pytest
 from llnl.util.filesystem import mkdirp, working_dir
 
 import spack
+import spack.cmd
+import spack.fetch_strategy
 from spack.version import ver
 
 
diff --git a/lib/spack/spack/test/cmd/list.py b/lib/spack/spack/test/cmd/list.py
index 4a92504673..23903107f6 100644
--- a/lib/spack/spack/test/cmd/list.py
+++ b/lib/spack/spack/test/cmd/list.py
@@ -7,6 +7,7 @@ import os.path
 import sys
 from textwrap import dedent
 
+import spack.paths
 import spack.repo
 from spack.main import SpackCommand
 
diff --git a/lib/spack/spack/test/cmd/location.py b/lib/spack/spack/test/cmd/location.py
index 9e42a03b02..25fa02a6b0 100644
--- a/lib/spack/spack/test/cmd/location.py
+++ b/lib/spack/spack/test/cmd/location.py
@@ -11,6 +11,7 @@ from llnl.util.filesystem import mkdirp
 
 import spack.environment as ev
 import spack.paths
+import spack.spec
 import spack.stage
 from spack.main import SpackCommand, SpackCommandError
 
diff --git a/lib/spack/spack/test/cmd/logs.py b/lib/spack/spack/test/cmd/logs.py
index 0691549be5..b668cd449c 100644
--- a/lib/spack/spack/test/cmd/logs.py
+++ b/lib/spack/spack/test/cmd/logs.py
@@ -13,6 +13,9 @@ from io import BytesIO, TextIOWrapper
 import pytest
 
 import spack
+import spack.cmd.logs
+import spack.main
+import spack.spec
 from spack.main import SpackCommand
 
 logs = SpackCommand("logs")
diff --git a/lib/spack/spack/test/cmd/mirror.py b/lib/spack/spack/test/cmd/mirror.py
index c1e24a9825..2a67bc2e14 100644
--- a/lib/spack/spack/test/cmd/mirror.py
+++ b/lib/spack/spack/test/cmd/mirror.py
@@ -10,8 +10,11 @@ import pytest
 import spack.cmd.mirror
 import spack.config
 import spack.environment as ev
+import spack.error
+import spack.mirror
 import spack.spec
 import spack.util.url as url_util
+import spack.version
 from spack.main import SpackCommand, SpackCommandError
 
 mirror = SpackCommand("mirror")
diff --git a/lib/spack/spack/test/cmd/module.py b/lib/spack/spack/test/cmd/module.py
index 4b460eb90a..e16c8edecb 100644
--- a/lib/spack/spack/test/cmd/module.py
+++ b/lib/spack/spack/test/cmd/module.py
@@ -11,6 +11,8 @@ import pytest
 import spack.config
 import spack.main
 import spack.modules
+import spack.modules.lmod
+import spack.repo
 import spack.spec
 import spack.store
 
diff --git a/lib/spack/spack/test/cmd/pkg.py b/lib/spack/spack/test/cmd/pkg.py
index c6db5693c7..bbe5b61462 100644
--- a/lib/spack/spack/test/cmd/pkg.py
+++ b/lib/spack/spack/test/cmd/pkg.py
@@ -12,6 +12,7 @@ from llnl.util.filesystem import mkdirp, working_dir
 
 import spack.cmd.pkg
 import spack.main
+import spack.paths
 import spack.repo
 import spack.util.file_cache
 
diff --git a/lib/spack/spack/test/cmd/spec.py b/lib/spack/spack/test/cmd/spec.py
index 9512f31c2a..a57c40ec92 100644
--- a/lib/spack/spack/test/cmd/spec.py
+++ b/lib/spack/spack/test/cmd/spec.py
@@ -9,7 +9,6 @@ import pytest
 
 import spack.environment as ev
 import spack.error
-import spack.parser
 import spack.spec
 import spack.store
 from spack.main import SpackCommand, SpackCommandError
@@ -142,7 +141,7 @@ def test_spec_returncode():
 
 
 def test_spec_parse_error():
-    with pytest.raises(spack.parser.SpecSyntaxError) as e:
+    with pytest.raises(spack.error.SpecSyntaxError) as e:
         spec("1.15:")
 
     # make sure the error is formatted properly
diff --git a/lib/spack/spack/test/cmd/style.py b/lib/spack/spack/test/cmd/style.py
index 7444c970c1..208e31f8a2 100644
--- a/lib/spack/spack/test/cmd/style.py
+++ b/lib/spack/spack/test/cmd/style.py
@@ -11,6 +11,7 @@ import pytest
 
 from llnl.util.filesystem import FileFilter
 
+import spack.cmd.style
 import spack.main
 import spack.paths
 import spack.repo
diff --git a/lib/spack/spack/test/compilers/basics.py b/lib/spack/spack/test/compilers/basics.py
index 59edeaea15..ca12ad6030 100644
--- a/lib/spack/spack/test/compilers/basics.py
+++ b/lib/spack/spack/test/compilers/basics.py
@@ -12,6 +12,7 @@ import llnl.util.filesystem as fs
 
 import spack.compiler
 import spack.compilers
+import spack.config
 import spack.spec
 import spack.util.module_cmd
 from spack.compiler import Compiler
diff --git a/lib/spack/spack/test/concretize.py b/lib/spack/spack/test/concretize.py
index e362cc27ff..7aaa2bc7f5 100644
--- a/lib/spack/spack/test/concretize.py
+++ b/lib/spack/spack/test/concretize.py
@@ -22,10 +22,13 @@ import spack.deptypes as dt
 import spack.detection
 import spack.error
 import spack.hash_types as ht
+import spack.paths
 import spack.platforms
+import spack.platforms.test
 import spack.repo
 import spack.solver.asp
 import spack.solver.version_order
+import spack.spec
 import spack.store
 import spack.util.file_cache
 import spack.variant as vt
diff --git a/lib/spack/spack/test/concretize_errors.py b/lib/spack/spack/test/concretize_errors.py
index 0b3cf10933..0cb7a533c1 100644
--- a/lib/spack/spack/test/concretize_errors.py
+++ b/lib/spack/spack/test/concretize_errors.py
@@ -5,6 +5,7 @@
 
 import pytest
 
+import spack.config
 import spack.solver.asp
 import spack.spec
 
diff --git a/lib/spack/spack/test/concretize_preferences.py b/lib/spack/spack/test/concretize_preferences.py
index 1a41140774..faf7b07fc0 100644
--- a/lib/spack/spack/test/concretize_preferences.py
+++ b/lib/spack/spack/test/concretize_preferences.py
@@ -11,8 +11,10 @@ import pytest
 import spack.config
 import spack.package_prefs
 import spack.repo
+import spack.spec
+import spack.util.module_cmd
 import spack.util.spack_yaml as syaml
-from spack.config import ConfigError
+from spack.error import ConfigError
 from spack.spec import CompilerSpec, Spec
 from spack.version import Version
 
@@ -227,7 +229,7 @@ mpileaks:
         """Preference should not specify an undefined version"""
         update_packages("python", "version", ["3.5.0.1"])
         spec = Spec("python")
-        with pytest.raises(spack.config.ConfigError):
+        with pytest.raises(ConfigError):
             spec.concretize()
 
     def test_preferred_truncated(self):
diff --git a/lib/spack/spack/test/concretize_requirements.py b/lib/spack/spack/test/concretize_requirements.py
index 420db9fa9d..aef8d0ed5c 100644
--- a/lib/spack/spack/test/concretize_requirements.py
+++ b/lib/spack/spack/test/concretize_requirements.py
@@ -11,6 +11,7 @@ import spack.config
 import spack.error
 import spack.package_base
 import spack.repo
+import spack.solver.asp
 import spack.util.spack_yaml as syaml
 import spack.version
 from spack.solver.asp import InternalConcretizerError, UnsatisfiableSpecError
@@ -70,7 +71,7 @@ packages:
     require: "@1.2"
 """
     update_packages_config(conf_str)
-    with pytest.raises(spack.config.ConfigError):
+    with pytest.raises(spack.error.ConfigError):
         Spec("x").concretize()
 
 
diff --git a/lib/spack/spack/test/config.py b/lib/spack/spack/test/config.py
index abe9f9121b..ddf21ffb05 100644
--- a/lib/spack/spack/test/config.py
+++ b/lib/spack/spack/test/config.py
@@ -18,14 +18,17 @@ from llnl.util.filesystem import join_path, touch, touchp
 import spack.config
 import spack.directory_layout
 import spack.environment as ev
+import spack.error
 import spack.package_base
 import spack.paths
+import spack.platforms
 import spack.repo
 import spack.schema.compilers
 import spack.schema.config
 import spack.schema.env
 import spack.schema.mirrors
 import spack.schema.repos
+import spack.spec
 import spack.store
 import spack.util.path as spack_path
 import spack.util.spack_yaml as syaml
@@ -310,7 +313,7 @@ def test_add_config_path_with_enumerated_type(mutable_config):
     spack.config.add("config:flags:keep_werror:specific")
     assert spack.config.get("config")["flags"]["keep_werror"] == "specific"
 
-    with pytest.raises(spack.config.ConfigError):
+    with pytest.raises(spack.error.ConfigError):
         spack.config.add("config:flags:keep_werror:foo")
 
 
@@ -869,10 +872,10 @@ def test_bad_command_line_scopes(tmp_path, config):
 
     file_path.write_text("")
 
-    with pytest.raises(spack.config.ConfigError):
+    with pytest.raises(spack.error.ConfigError):
         spack.config._add_command_line_scopes(cfg, [str(file_path)])
 
-    with pytest.raises(spack.config.ConfigError):
+    with pytest.raises(spack.error.ConfigError):
         spack.config._add_command_line_scopes(cfg, [str(non_existing_path)])
 
 
@@ -990,7 +993,7 @@ config:
     data = scope.get_section("config")
     assert data["config"]["install_tree"] == {"root": "dummy_tree_value"}
 
-    with pytest.raises(spack.config.ConfigError):
+    with pytest.raises(spack.error.ConfigError):
         scope._write_section("config")
 
 
diff --git a/lib/spack/spack/test/conftest.py b/lib/spack/spack/test/conftest.py
index b8cec8611d..607844265f 100644
--- a/lib/spack/spack/test/conftest.py
+++ b/lib/spack/spack/test/conftest.py
@@ -38,17 +38,21 @@ import spack.caches
 import spack.compiler
 import spack.compilers
 import spack.config
+import spack.directives
 import spack.environment as ev
 import spack.error
+import spack.modules.common
 import spack.package_base
 import spack.paths
 import spack.platforms
 import spack.repo
 import spack.solver.asp
+import spack.spec
 import spack.stage
 import spack.store
 import spack.subprocess_context
 import spack.util.executable
+import spack.util.file_cache
 import spack.util.git
 import spack.util.gpg
 import spack.util.parallel
diff --git a/lib/spack/spack/test/container/images.py b/lib/spack/spack/test/container/images.py
index faac9d0c8e..1e5e9e0d70 100644
--- a/lib/spack/spack/test/container/images.py
+++ b/lib/spack/spack/test/container/images.py
@@ -7,6 +7,7 @@ import os.path
 import pytest
 
 import spack.container
+import spack.container.images
 
 
 @pytest.mark.parametrize(
diff --git a/lib/spack/spack/test/cray_manifest.py b/lib/spack/spack/test/cray_manifest.py
index dd5bd3e4a6..2a11b79a11 100644
--- a/lib/spack/spack/test/cray_manifest.py
+++ b/lib/spack/spack/test/cray_manifest.py
@@ -19,6 +19,8 @@ import spack.cmd
 import spack.cmd.external
 import spack.compilers
 import spack.cray_manifest as cray_manifest
+import spack.platforms
+import spack.platforms.test
 import spack.solver.asp
 import spack.spec
 import spack.store
diff --git a/lib/spack/spack/test/database.py b/lib/spack/spack/test/database.py
index 5e8e5abbc8..e34c85a788 100644
--- a/lib/spack/spack/test/database.py
+++ b/lib/spack/spack/test/database.py
@@ -13,6 +13,8 @@ import sys
 
 import pytest
 
+import spack.subprocess_context
+
 try:
     import uuid
 
diff --git a/lib/spack/spack/test/detection.py b/lib/spack/spack/test/detection.py
index 3fbc52fcbd..f699308287 100644
--- a/lib/spack/spack/test/detection.py
+++ b/lib/spack/spack/test/detection.py
@@ -4,7 +4,9 @@
 # SPDX-License-Identifier: (Apache-2.0 OR MIT)
 import collections
 
+import spack.config
 import spack.detection
+import spack.detection.common
 import spack.spec
 
 
diff --git a/lib/spack/spack/test/directory_layout.py b/lib/spack/spack/test/directory_layout.py
index da51de415e..169c6a9c5e 100644
--- a/lib/spack/spack/test/directory_layout.py
+++ b/lib/spack/spack/test/directory_layout.py
@@ -14,8 +14,11 @@ import pytest
 
 from llnl.path import path_to_os_path
 
+import spack.hash_types
 import spack.paths
 import spack.repo
+import spack.spec
+import spack.util.file_cache
 from spack.directory_layout import DirectoryLayout, InvalidDirectoryLayoutParametersError
 from spack.spec import Spec
 
diff --git a/lib/spack/spack/test/env.py b/lib/spack/spack/test/env.py
index b239301680..682540361f 100644
--- a/lib/spack/spack/test/env.py
+++ b/lib/spack/spack/test/env.py
@@ -11,7 +11,9 @@ import pytest
 
 import llnl.util.filesystem as fs
 
+import spack.config
 import spack.environment as ev
+import spack.solver.asp
 import spack.spec
 from spack.environment.environment import (
     EnvironmentManifestFile,
diff --git a/lib/spack/spack/test/git_fetch.py b/lib/spack/spack/test/git_fetch.py
index eb2e03db07..54ac9d8a1b 100644
--- a/lib/spack/spack/test/git_fetch.py
+++ b/lib/spack/spack/test/git_fetch.py
@@ -12,6 +12,9 @@ import pytest
 from llnl.util.filesystem import mkdirp, touch, working_dir
 
 import spack.config
+import spack.error
+import spack.fetch_strategy
+import spack.platforms
 import spack.repo
 from spack.fetch_strategy import GitFetchStrategy
 from spack.spec import Spec
diff --git a/lib/spack/spack/test/install.py b/lib/spack/spack/test/install.py
index 4159296886..ba7084960a 100644
--- a/lib/spack/spack/test/install.py
+++ b/lib/spack/spack/test/install.py
@@ -11,17 +11,20 @@ import pytest
 
 import llnl.util.filesystem as fs
 
+import spack.build_environment
 import spack.config
 import spack.database
 import spack.error
+import spack.installer
 import spack.mirror
+import spack.package_base
 import spack.patch
 import spack.repo
 import spack.store
 import spack.util.spack_json as sjson
 from spack import binary_distribution
+from spack.error import InstallError
 from spack.package_base import (
-    InstallError,
     PackageBase,
     PackageStillNeededError,
     _spack_build_envfile,
diff --git a/lib/spack/spack/test/installer.py b/lib/spack/spack/test/installer.py
index 8d7669f544..25dcafb64d 100644
--- a/lib/spack/spack/test/installer.py
+++ b/lib/spack/spack/test/installer.py
@@ -19,6 +19,8 @@ import llnl.util.tty as tty
 import spack.binary_distribution
 import spack.database
 import spack.deptypes as dt
+import spack.error
+import spack.hooks
 import spack.installer as inst
 import spack.package_base
 import spack.package_prefs as prefs
@@ -135,7 +137,9 @@ def test_install_from_cache_errors(install_mockery):
     assert spec.concrete
 
     # Check with cache-only
-    with pytest.raises(inst.InstallError, match="No binary found when cache-only was specified"):
+    with pytest.raises(
+        spack.error.InstallError, match="No binary found when cache-only was specified"
+    ):
         spec.package.do_install(package_cache_only=True, dependencies_cache_only=True)
     assert not spec.package.installed_from_binary_cache
 
@@ -581,7 +585,7 @@ def test_check_deps_status_install_failure(install_mockery):
     installer = create_installer(["pkg-a"], {})
     request = installer.build_requests[0]
 
-    with pytest.raises(inst.InstallError, match="install failure"):
+    with pytest.raises(spack.error.InstallError, match="install failure"):
         installer._check_deps_status(request)
 
 
@@ -592,7 +596,7 @@ def test_check_deps_status_write_locked(install_mockery, monkeypatch):
     # Ensure the lock is not acquired
     monkeypatch.setattr(inst.PackageInstaller, "_ensure_locked", _not_locked)
 
-    with pytest.raises(inst.InstallError, match="write locked by another"):
+    with pytest.raises(spack.error.InstallError, match="write locked by another"):
         installer._check_deps_status(request)
 
 
@@ -799,7 +803,7 @@ def test_install_uninstalled_deps(install_mockery, monkeypatch, capsys):
     monkeypatch.setattr(inst.PackageInstaller, "_update_failed", _noop)
 
     msg = "Cannot proceed with dependent-install"
-    with pytest.raises(inst.InstallError, match=msg):
+    with pytest.raises(spack.error.InstallError, match=msg):
         installer.install()
 
     out = str(capsys.readouterr())
@@ -813,7 +817,7 @@ def test_install_failed(install_mockery, monkeypatch, capsys):
     # Make sure the package is identified as failed
     monkeypatch.setattr(spack.database.FailureTracker, "has_failed", _true)
 
-    with pytest.raises(inst.InstallError, match="request failed"):
+    with pytest.raises(spack.error.InstallError, match="request failed"):
         installer.install()
 
     out = str(capsys.readouterr())
@@ -828,7 +832,7 @@ def test_install_failed_not_fast(install_mockery, monkeypatch, capsys):
     # Make sure the package is identified as failed
     monkeypatch.setattr(spack.database.FailureTracker, "has_failed", _true)
 
-    with pytest.raises(inst.InstallError, match="request failed"):
+    with pytest.raises(spack.error.InstallError, match="request failed"):
         installer.install()
 
     out = str(capsys.readouterr())
@@ -904,7 +908,7 @@ def test_install_fail_multi(install_mockery, monkeypatch):
     # Raise a KeyboardInterrupt error to trigger early termination
     monkeypatch.setattr(inst.PackageInstaller, "_install_task", _install)
 
-    with pytest.raises(inst.InstallError, match="Installation request failed"):
+    with pytest.raises(spack.error.InstallError, match="Installation request failed"):
         installer.install()
 
     assert "pkg-a" in installer.installed  # ensure the the second spec installed
@@ -922,7 +926,7 @@ def test_install_fail_fast_on_detect(install_mockery, monkeypatch, capsys):
     # This will prevent b from installing, which will cause the build of c to be skipped.
     monkeypatch.setattr(spack.database.FailureTracker, "has_failed", _true)
 
-    with pytest.raises(inst.InstallError, match="after first install failure"):
+    with pytest.raises(spack.error.InstallError, match="after first install failure"):
         installer.install()
 
     assert b_id in installer.failed, "Expected b to be marked as failed"
@@ -950,7 +954,7 @@ def test_install_fail_fast_on_except(install_mockery, monkeypatch, capsys):
         spack.package_base.PackageBase, "do_patch", _test_install_fail_fast_on_except_patch
     )
 
-    with pytest.raises(inst.InstallError, match="mock patch failure"):
+    with pytest.raises(spack.error.InstallError, match="mock patch failure"):
         installer.install()
 
     out = str(capsys.readouterr())
@@ -971,7 +975,7 @@ def test_install_lock_failures(install_mockery, monkeypatch, capfd):
     # Ensure don't continually requeue the task
     monkeypatch.setattr(inst.PackageInstaller, "_requeue_task", _requeued)
 
-    with pytest.raises(inst.InstallError, match="request failed"):
+    with pytest.raises(spack.error.InstallError, match="request failed"):
         installer.install()
 
     out = capfd.readouterr()[0]
@@ -1002,7 +1006,7 @@ def test_install_lock_installed_requeue(install_mockery, monkeypatch, capfd):
     # Ensure don't continually requeue the task
     monkeypatch.setattr(inst.PackageInstaller, "_requeue_task", _requeued)
 
-    with pytest.raises(inst.InstallError, match="request failed"):
+    with pytest.raises(spack.error.InstallError, match="request failed"):
         installer.install()
 
     assert b_pkg_id not in installer.installed
@@ -1038,7 +1042,7 @@ def test_install_read_locked_requeue(install_mockery, monkeypatch, capfd):
 
     installer = create_installer(["pkg-b"], {})
 
-    with pytest.raises(inst.InstallError, match="request failed"):
+    with pytest.raises(spack.error.InstallError, match="request failed"):
         installer.install()
 
     assert "b" not in installer.installed
diff --git a/lib/spack/spack/test/modules/common.py b/lib/spack/spack/test/modules/common.py
index 694f3f6538..49f63f6c3b 100644
--- a/lib/spack/spack/test/modules/common.py
+++ b/lib/spack/spack/test/modules/common.py
@@ -12,8 +12,11 @@ from llnl.util.symlink import readlink
 import spack.cmd.modules
 import spack.config
 import spack.error
+import spack.modules.common
 import spack.modules.tcl
 import spack.package_base
+import spack.package_prefs
+import spack.repo
 import spack.spec
 from spack.modules.common import UpstreamModuleIndex
 from spack.spec import Spec
@@ -215,8 +218,8 @@ def test_check_module_set_name(mutable_config):
 
     # Invalid module set names
     msg = "Valid module set names are"
-    with pytest.raises(spack.config.ConfigError, match=msg):
+    with pytest.raises(spack.error.ConfigError, match=msg):
         spack.cmd.modules.check_module_set_name("prefix_inspections")
 
-    with pytest.raises(spack.config.ConfigError, match=msg):
+    with pytest.raises(spack.error.ConfigError, match=msg):
         spack.cmd.modules.check_module_set_name("third")
diff --git a/lib/spack/spack/test/modules/conftest.py b/lib/spack/spack/test/modules/conftest.py
index 8869d60d8d..5a2e0ceaed 100644
--- a/lib/spack/spack/test/modules/conftest.py
+++ b/lib/spack/spack/test/modules/conftest.py
@@ -6,6 +6,8 @@ import pathlib
 
 import pytest
 
+import spack.modules.lmod
+import spack.modules.tcl
 import spack.spec
 
 
diff --git a/lib/spack/spack/test/modules/lmod.py b/lib/spack/spack/test/modules/lmod.py
index 43ee11ec49..a985cb1b7e 100644
--- a/lib/spack/spack/test/modules/lmod.py
+++ b/lib/spack/spack/test/modules/lmod.py
@@ -9,10 +9,13 @@ import pytest
 
 import archspec.cpu
 
+import spack.config
 import spack.environment as ev
 import spack.main
+import spack.modules.common
 import spack.modules.lmod
 import spack.spec
+import spack.util.environment
 
 mpich_spec_string = "mpich@3.0.4"
 mpileaks_spec_string = "mpileaks"
diff --git a/lib/spack/spack/test/multimethod.py b/lib/spack/spack/test/multimethod.py
index 974985d5b8..7e5231ee93 100644
--- a/lib/spack/spack/test/multimethod.py
+++ b/lib/spack/spack/test/multimethod.py
@@ -7,6 +7,7 @@
 
 import pytest
 
+import spack.config
 import spack.platforms
 import spack.spec
 from spack.multimethod import NoSuchMethodError
diff --git a/lib/spack/spack/test/package_class.py b/lib/spack/spack/test/package_class.py
index 1a44c19fb7..5a61d90d33 100644
--- a/lib/spack/spack/test/package_class.py
+++ b/lib/spack/spack/test/package_class.py
@@ -17,13 +17,16 @@ import pytest
 
 import llnl.util.filesystem as fs
 
+import spack.compilers
+import spack.config
 import spack.deptypes as dt
+import spack.error
 import spack.install_test
 import spack.package_base
 import spack.repo
 import spack.spec
 from spack.build_systems.generic import Package
-from spack.installer import InstallError
+from spack.error import InstallError
 
 
 @pytest.fixture(scope="module")
diff --git a/lib/spack/spack/test/packages.py b/lib/spack/spack/test/packages.py
index 4f16fb71e8..692f9d84cb 100644
--- a/lib/spack/spack/test/packages.py
+++ b/lib/spack/spack/test/packages.py
@@ -7,8 +7,11 @@ import os
 
 import pytest
 
+import spack.build_environment
 import spack.directives
+import spack.error
 import spack.fetch_strategy
+import spack.package_base
 import spack.repo
 from spack.paths import mock_packages_path
 from spack.spec import Spec
@@ -127,10 +130,10 @@ def test_urls_for_versions(mock_packages, config):
 def test_url_for_version_with_no_urls(mock_packages, config):
     spec = Spec("git-test")
     pkg_cls = spack.repo.PATH.get_pkg_class(spec.name)
-    with pytest.raises(spack.package_base.NoURLError):
+    with pytest.raises(spack.error.NoURLError):
         pkg_cls(spec).url_for_version("1.0")
 
-    with pytest.raises(spack.package_base.NoURLError):
+    with pytest.raises(spack.error.NoURLError):
         pkg_cls(spec).url_for_version("1.1")
 
 
diff --git a/lib/spack/spack/test/packaging.py b/lib/spack/spack/test/packaging.py
index 9fb7e3b152..f616cb47a7 100644
--- a/lib/spack/spack/test/packaging.py
+++ b/lib/spack/spack/test/packaging.py
@@ -21,9 +21,12 @@ from llnl.util.symlink import readlink, symlink
 
 import spack.binary_distribution as bindist
 import spack.cmd.buildcache as buildcache
+import spack.config
 import spack.error
 import spack.fetch_strategy
+import spack.mirror
 import spack.package_base
+import spack.stage
 import spack.util.gpg
 import spack.util.url as url_util
 from spack.fetch_strategy import URLFetchStrategy
diff --git a/lib/spack/spack/test/patch.py b/lib/spack/spack/test/patch.py
index 8c8ea24227..4b5f31b904 100644
--- a/lib/spack/spack/test/patch.py
+++ b/lib/spack/spack/test/patch.py
@@ -14,9 +14,12 @@ import pytest
 from llnl.util.filesystem import mkdirp, touch, working_dir
 
 import spack.error
+import spack.fetch_strategy
 import spack.patch
 import spack.paths
 import spack.repo
+import spack.spec
+import spack.stage
 import spack.util.url as url_util
 from spack.spec import Spec
 from spack.stage import Stage
diff --git a/lib/spack/spack/test/relocate.py b/lib/spack/spack/test/relocate.py
index 31c206264a..bceddbe728 100644
--- a/lib/spack/spack/test/relocate.py
+++ b/lib/spack/spack/test/relocate.py
@@ -12,6 +12,7 @@ import pytest
 import spack.platforms
 import spack.relocate
 import spack.relocate_text as relocate_text
+import spack.repo
 import spack.util.executable
 
 pytestmark = pytest.mark.not_on_windows("Tests fail on Windows")
diff --git a/lib/spack/spack/test/sbang.py b/lib/spack/spack/test/sbang.py
index 24cc098d69..d3c5ef2da4 100644
--- a/lib/spack/spack/test/sbang.py
+++ b/lib/spack/spack/test/sbang.py
@@ -17,6 +17,7 @@ import pytest
 
 import llnl.util.filesystem as fs
 
+import spack.config
 import spack.hooks.sbang as sbang
 import spack.store
 import spack.util.spack_yaml as syaml
diff --git a/lib/spack/spack/test/spec_dag.py b/lib/spack/spack/test/spec_dag.py
index e0ecfce90a..0d1fe4abcf 100644
--- a/lib/spack/spack/test/spec_dag.py
+++ b/lib/spack/spack/test/spec_dag.py
@@ -9,9 +9,9 @@ import pytest
 
 import spack.deptypes as dt
 import spack.error
-import spack.parser
 import spack.repo
 import spack.util.hash as hashutil
+import spack.version
 from spack.dependency import Dependency
 from spack.spec import Spec
 
@@ -741,7 +741,7 @@ class TestSpecDag:
 
     def test_invalid_literal_spec(self):
         # Can't give type 'build' to a top-level spec
-        with pytest.raises(spack.parser.SpecSyntaxError):
+        with pytest.raises(spack.error.SpecSyntaxError):
             Spec.from_literal({"foo:build": None})
 
         # Can't use more than one ':' separator
diff --git a/lib/spack/spack/test/spec_semantics.py b/lib/spack/spack/test/spec_semantics.py
index 0f3b58e486..a7f4383bc6 100644
--- a/lib/spack/spack/test/spec_semantics.py
+++ b/lib/spack/spack/test/spec_semantics.py
@@ -9,6 +9,12 @@ import pytest
 
 import spack.directives
 import spack.error
+import spack.parser
+import spack.paths
+import spack.solver.asp
+import spack.spec
+import spack.store
+import spack.variant
 from spack.error import SpecError, UnsatisfiableSpecError
 from spack.spec import (
     ArchSpec,
diff --git a/lib/spack/spack/test/spec_syntax.py b/lib/spack/spack/test/spec_syntax.py
index 33bb9bdf7b..7a1bd3b3cd 100644
--- a/lib/spack/spack/test/spec_syntax.py
+++ b/lib/spack/spack/test/spec_syntax.py
@@ -9,8 +9,11 @@ import sys
 
 import pytest
 
+import spack.binary_distribution
 import spack.cmd
+import spack.parser
 import spack.platforms.test
+import spack.repo
 import spack.spec
 from spack.parser import (
     UNIX_FILENAME,
diff --git a/lib/spack/spack/test/stage.py b/lib/spack/spack/test/stage.py
index 63cd20eb2a..36a9e2eef2 100644
--- a/lib/spack/spack/test/stage.py
+++ b/lib/spack/spack/test/stage.py
@@ -17,6 +17,7 @@ import pytest
 from llnl.util.filesystem import getuid, mkdirp, partition_path, touch, working_dir
 from llnl.util.symlink import readlink
 
+import spack.config
 import spack.error
 import spack.fetch_strategy
 import spack.stage
diff --git a/lib/spack/spack/test/tag.py b/lib/spack/spack/test/tag.py
index 1d493d3a79..e429b9f457 100644
--- a/lib/spack/spack/test/tag.py
+++ b/lib/spack/spack/test/tag.py
@@ -7,6 +7,7 @@ import io
 
 import pytest
 
+import spack.repo
 import spack.tag
 from spack.main import SpackCommand
 
diff --git a/lib/spack/spack/test/test_suite.py b/lib/spack/spack/test/test_suite.py
index 708c4788be..60a54e7171 100644
--- a/lib/spack/spack/test/test_suite.py
+++ b/lib/spack/spack/test/test_suite.py
@@ -10,8 +10,10 @@ import pytest
 
 from llnl.util.filesystem import join_path, mkdirp, touch
 
+import spack.config
 import spack.install_test
 import spack.spec
+import spack.util.executable
 from spack.install_test import TestStatus
 from spack.util.executable import which
 
diff --git a/lib/spack/spack/test/url_fetch.py b/lib/spack/spack/test/url_fetch.py
index ff7e4a142e..f103244a10 100644
--- a/lib/spack/spack/test/url_fetch.py
+++ b/lib/spack/spack/test/url_fetch.py
@@ -17,9 +17,11 @@ from llnl.util.filesystem import is_exe, working_dir
 import spack.config
 import spack.error
 import spack.fetch_strategy as fs
+import spack.url
 import spack.util.crypto as crypto
 import spack.util.executable
 import spack.util.web as web_util
+import spack.version
 from spack.spec import Spec
 from spack.stage import Stage
 from spack.util.executable import which
diff --git a/lib/spack/spack/test/util/executable.py b/lib/spack/spack/test/util/executable.py
index d854ec426e..9b0536eba9 100644
--- a/lib/spack/spack/test/util/executable.py
+++ b/lib/spack/spack/test/util/executable.py
@@ -12,6 +12,7 @@ import pytest
 import llnl.util.filesystem as fs
 
 import spack
+import spack.main
 import spack.util.executable as ex
 from spack.hooks.sbang import filter_shebangs_in_directory
 
diff --git a/lib/spack/spack/test/versions.py b/lib/spack/spack/test/versions.py
index bc97fe4667..734ba4ca4a 100644
--- a/lib/spack/spack/test/versions.py
+++ b/lib/spack/spack/test/versions.py
@@ -16,6 +16,7 @@ from llnl.util.filesystem import working_dir
 
 import spack.package_base
 import spack.spec
+import spack.version
 from spack.version import (
     EmptyRangeError,
     GitVersion,
-- 
cgit v1.2.3-70-g09d2