summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Coldrick <thomas.coldrick@codethink.co.uk>2020-01-17 15:22:06 +0000
committerThomas Coldrick <thomas.coldrick@codethink.co.uk>2020-01-23 16:45:35 +0000
commit8aa7e8b6c2ca418aafddf4ce308a9d0ff56cf467 (patch)
tree01fef02fe2ca9634b1ede36d5b96fab66a6532f5
parentbf5f20704831f58d7ced04e960ca8f7b97c6736c (diff)
downloadbuildstream-8aa7e8b6c2ca418aafddf4ce308a9d0ff56cf467.tar.gz
exceptions: Expose ErrorDomain, ErrorLoadReason
Plugin tests are already accessing this API, but using imports from private modules. For motivation for this to be exposed publicly, note that ErrorDomain is an argument for most things in runcli.py, and LoadErrorReason may be another.
-rw-r--r--doc/source/core_framework.rst1
-rw-r--r--src/buildstream/_context.py3
-rw-r--r--src/buildstream/_exceptions.py106
-rw-r--r--src/buildstream/_frontend/app.py3
-rw-r--r--src/buildstream/_includes.py3
-rw-r--r--src/buildstream/_loader/loader.py3
-rw-r--r--src/buildstream/_loader/types.pyx3
-rw-r--r--src/buildstream/_options/optionarch.py3
-rw-r--r--src/buildstream/_options/optionbool.py3
-rw-r--r--src/buildstream/_options/optionenum.py3
-rw-r--r--src/buildstream/_options/optionflags.py3
-rw-r--r--src/buildstream/_options/optionpool.py3
-rw-r--r--src/buildstream/_plugincontext.py3
-rw-r--r--src/buildstream/_project.py3
-rw-r--r--src/buildstream/_projectrefs.py3
-rw-r--r--src/buildstream/_remote.py3
-rw-r--r--src/buildstream/_variables.pyx3
-rw-r--r--src/buildstream/_workspaces.py3
-rw-r--r--src/buildstream/_yaml.pyx3
-rw-r--r--src/buildstream/element.py3
-rw-r--r--src/buildstream/exceptions.py141
-rw-r--r--src/buildstream/node.pyx3
-rw-r--r--src/buildstream/source.py3
-rw-r--r--src/buildstream/storage/directory.py3
-rw-r--r--src/buildstream/testing/__init__.py1
-rw-r--r--src/buildstream/testing/_sourcetests/mirror.py2
-rw-r--r--src/buildstream/testing/_sourcetests/track.py2
-rw-r--r--src/buildstream/utils.py3
-rw-r--r--tests/artifactcache/config.py2
-rw-r--r--tests/artifactcache/expiry.py2
-rw-r--r--tests/elements/filter.py2
-rw-r--r--tests/format/assertion.py2
-rw-r--r--tests/format/dependencies.py2
-rw-r--r--tests/format/include.py2
-rw-r--r--tests/format/invalid_keys.py2
-rw-r--r--tests/format/junctions.py2
-rw-r--r--tests/format/listdirectiveerrors.py2
-rw-r--r--tests/format/optionarch.py2
-rw-r--r--tests/format/optionbool.py2
-rw-r--r--tests/format/optioneltmask.py2
-rw-r--r--tests/format/optionenum.py2
-rw-r--r--tests/format/optionflags.py2
-rw-r--r--tests/format/optionos.py2
-rw-r--r--tests/format/options.py2
-rw-r--r--tests/format/project.py2
-rw-r--r--tests/format/userconfig.py2
-rw-r--r--tests/format/variables.py2
-rw-r--r--tests/frontend/artifact_delete.py2
-rw-r--r--tests/frontend/artifact_show.py2
-rw-r--r--tests/frontend/buildcheckout.py2
-rw-r--r--tests/frontend/configurable_warnings.py2
-rw-r--r--tests/frontend/fetch.py2
-rw-r--r--tests/frontend/init.py2
-rw-r--r--tests/frontend/logging.py2
-rw-r--r--tests/frontend/overlaps.py2
-rw-r--r--tests/frontend/progress.py2
-rw-r--r--tests/frontend/push.py2
-rw-r--r--tests/frontend/show.py2
-rw-r--r--tests/frontend/track.py2
-rw-r--r--tests/frontend/workspace.py2
-rw-r--r--tests/integration/cachedfail.py2
-rw-r--r--tests/integration/messages.py2
-rw-r--r--tests/integration/pullbuildtrees.py2
-rw-r--r--tests/integration/sandbox-bwrap.py2
-rw-r--r--tests/integration/shell.py2
-rw-r--r--tests/integration/shellbuildtrees.py2
-rw-r--r--tests/integration/workspace.py2
-rw-r--r--tests/internals/context.py3
-rw-r--r--tests/internals/loader.py3
-rw-r--r--tests/internals/pluginloading.py3
-rw-r--r--tests/internals/yaml.py3
-rw-r--r--tests/remoteexecution/buildfail.py2
-rw-r--r--tests/remoteexecution/partial.py2
-rw-r--r--tests/sandboxes/fallback.py2
-rw-r--r--tests/sandboxes/missing-command.py2
-rw-r--r--tests/sandboxes/missing_dependencies.py2
-rw-r--r--tests/sandboxes/remote-exec-config.py2
-rw-r--r--tests/sandboxes/selection.py2
-rw-r--r--tests/sourcecache/config.py2
-rw-r--r--tests/sourcecache/fetch.py2
-rw-r--r--tests/sourcecache/push.py2
-rw-r--r--tests/sourcecache/source-checkout.py2
-rw-r--r--tests/sources/git.py2
-rw-r--r--tests/sources/keytest.py2
-rw-r--r--tests/sources/local.py2
-rw-r--r--tests/sources/patch.py2
-rw-r--r--tests/sources/pip.py2
-rw-r--r--tests/sources/remote.py2
-rw-r--r--tests/sources/tar.py2
-rw-r--r--tests/sources/zip.py2
90 files changed, 257 insertions, 190 deletions
diff --git a/doc/source/core_framework.rst b/doc/source/core_framework.rst
index 60fbc5539..bdfa600f5 100644
--- a/doc/source/core_framework.rst
+++ b/doc/source/core_framework.rst
@@ -20,5 +20,6 @@ useful for working on BuildStream itself.
buildstream.buildelement
buildstream.scriptelement
buildstream.sandbox.sandbox
+ buildstream.exceptions
buildstream.utils
buildstream.testing
diff --git a/src/buildstream/_context.py b/src/buildstream/_context.py
index 513754a4c..c3ea52f0e 100644
--- a/src/buildstream/_context.py
+++ b/src/buildstream/_context.py
@@ -22,7 +22,8 @@ import shutil
from . import utils
from . import _site
from . import _yaml
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
from ._messenger import Messenger
from ._profile import Topics, PROFILER
from ._platform import Platform
diff --git a/src/buildstream/_exceptions.py b/src/buildstream/_exceptions.py
index 51f542783..e9599d225 100644
--- a/src/buildstream/_exceptions.py
+++ b/src/buildstream/_exceptions.py
@@ -18,9 +18,10 @@
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
# Tiago Gomes <tiago.gomes@codethink.co.uk>
-from enum import Enum, unique
import os
+from .exceptions import ErrorDomain
+
# Disable pylint warnings for whole file here:
# pylint: disable=global-statement
@@ -79,27 +80,6 @@ def set_last_task_error(domain, reason):
_last_task_error_reason = reason
-@unique
-class ErrorDomain(Enum):
- PLUGIN = 1
- LOAD = 2
- IMPL = 3
- PLATFORM = 4
- SANDBOX = 5
- ARTIFACT = 6
- PIPELINE = 7
- UTIL = 8
- SOURCE = 9
- ELEMENT = 10
- APP = 11
- STREAM = 12
- VIRTUAL_FS = 13
- CAS = 14
- PROG_NOT_FOUND = 15
- REMOTE = 16
- PROFILE = 17
-
-
# BstError is an internal base exception class for BuildStream
# exceptions.
#
@@ -148,88 +128,6 @@ class PluginError(BstError):
super().__init__(message, domain=ErrorDomain.PLUGIN, reason=reason, temporary=False)
-# LoadErrorReason
-#
-# Describes the reason why a :class:`.LoadError` was raised.
-#
-class LoadErrorReason(Enum):
-
- # A file was not found.
- MISSING_FILE = 1
-
- # The parsed data was not valid YAML.
- INVALID_YAML = 2
-
- # Data was malformed, a value was not of the expected type, etc
- INVALID_DATA = 3
-
- # An error occurred during YAML dictionary composition.
- #
- # This can happen by overriding a value with a new differently typed
- # value, or by overwriting some named value when that was not allowed.
- ILLEGAL_COMPOSITE = 4
-
- # An circular dependency chain was detected
- CIRCULAR_DEPENDENCY = 5
-
- # A variable could not be resolved. This can happen if your project
- # has cyclic dependencies in variable declarations, or, when substituting
- # a string which refers to an undefined variable.
- UNRESOLVED_VARIABLE = 6
-
- # BuildStream does not support the required project format version
- UNSUPPORTED_PROJECT = 7
-
- # Project requires a newer version of a plugin than the one which was loaded
- UNSUPPORTED_PLUGIN = 8
-
- # A conditional expression failed to resolve
- EXPRESSION_FAILED = 9
-
- # An assertion was intentionally encoded into project YAML
- USER_ASSERTION = 10
-
- # A list composition directive did not apply to any underlying list
- TRAILING_LIST_DIRECTIVE = 11
-
- # Conflicting junctions in subprojects
- CONFLICTING_JUNCTION = 12
-
- # Failure to load a project from a specified junction
- INVALID_JUNCTION = 13
-
- # Subproject has no ref
- SUBPROJECT_INCONSISTENT = 15
-
- # An invalid symbol name was encountered
- INVALID_SYMBOL_NAME = 16
-
- # A project.conf file was missing
- MISSING_PROJECT_CONF = 17
-
- # Try to load a directory not a yaml file
- LOADING_DIRECTORY = 18
-
- # A project path leads outside of the project directory
- PROJ_PATH_INVALID = 19
-
- # A project path points to a file of the not right kind (e.g. a
- # socket)
- PROJ_PATH_INVALID_KIND = 20
-
- # A recursive include has been encountered.
- RECURSIVE_INCLUDE = 21
-
- # A recursive variable has been encountered
- RECURSIVE_VARIABLE = 22
-
- # An attempt so set the value of a protected variable
- PROTECTED_VARIABLE_REDEFINED = 23
-
- # A duplicate dependency was detected
- DUPLICATE_DEPENDENCY = 24
-
-
# LoadError
#
# Raised while loading some YAML.
diff --git a/src/buildstream/_frontend/app.py b/src/buildstream/_frontend/app.py
index cd05b7f8d..8ce5493ee 100644
--- a/src/buildstream/_frontend/app.py
+++ b/src/buildstream/_frontend/app.py
@@ -32,7 +32,8 @@ from .. import Scope
# Import various buildstream internals
from .._context import Context
from .._project import Project
-from .._exceptions import BstError, StreamError, LoadError, LoadErrorReason, AppError
+from .._exceptions import BstError, StreamError, LoadError, AppError
+from ..exceptions import LoadErrorReason
from .._message import Message, MessageType, unconditional_messages
from .._stream import Stream
from .._versions import BST_FORMAT_VERSION
diff --git a/src/buildstream/_includes.py b/src/buildstream/_includes.py
index bc0d7718b..b49560947 100644
--- a/src/buildstream/_includes.py
+++ b/src/buildstream/_includes.py
@@ -1,7 +1,8 @@
import os
from . import _yaml
from .node import MappingNode, ScalarNode, SequenceNode
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
# Includes()
diff --git a/src/buildstream/_loader/loader.py b/src/buildstream/_loader/loader.py
index 531655c09..3200920b9 100644
--- a/src/buildstream/_loader/loader.py
+++ b/src/buildstream/_loader/loader.py
@@ -19,7 +19,8 @@
import os
-from .._exceptions import LoadError, LoadErrorReason
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
from .. import _yaml
from ..element import Element
from ..node import Node
diff --git a/src/buildstream/_loader/types.pyx b/src/buildstream/_loader/types.pyx
index 42a7b801f..1f264789a 100644
--- a/src/buildstream/_loader/types.pyx
+++ b/src/buildstream/_loader/types.pyx
@@ -17,7 +17,8 @@
# Authors:
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
-from .._exceptions import LoadError, LoadErrorReason
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
from ..node cimport MappingNode, Node, ProvenanceInformation, ScalarNode, SequenceNode
diff --git a/src/buildstream/_options/optionarch.py b/src/buildstream/_options/optionarch.py
index 2d663f0ef..651afbea5 100644
--- a/src/buildstream/_options/optionarch.py
+++ b/src/buildstream/_options/optionarch.py
@@ -17,7 +17,8 @@
# Authors:
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
-from .._exceptions import LoadError, LoadErrorReason, PlatformError
+from .._exceptions import LoadError, PlatformError
+from ..exceptions import LoadErrorReason
from .._platform import Platform
from .optionenum import OptionEnum
diff --git a/src/buildstream/_options/optionbool.py b/src/buildstream/_options/optionbool.py
index c7289b936..f6159825c 100644
--- a/src/buildstream/_options/optionbool.py
+++ b/src/buildstream/_options/optionbool.py
@@ -17,7 +17,8 @@
# Authors:
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
-from .._exceptions import LoadError, LoadErrorReason
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
from .option import Option, OPTION_SYMBOLS
diff --git a/src/buildstream/_options/optionenum.py b/src/buildstream/_options/optionenum.py
index d30f45696..12ec7cb63 100644
--- a/src/buildstream/_options/optionenum.py
+++ b/src/buildstream/_options/optionenum.py
@@ -17,7 +17,8 @@
# Authors:
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
-from .._exceptions import LoadError, LoadErrorReason
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
from .option import Option, OPTION_SYMBOLS
diff --git a/src/buildstream/_options/optionflags.py b/src/buildstream/_options/optionflags.py
index 82ede5649..b19a22738 100644
--- a/src/buildstream/_options/optionflags.py
+++ b/src/buildstream/_options/optionflags.py
@@ -17,7 +17,8 @@
# Authors:
# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
-from .._exceptions import LoadError, LoadErrorReason
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
from .option import Option, OPTION_SYMBOLS
diff --git a/src/buildstream/_options/optionpool.py b/src/buildstream/_options/optionpool.py
index f105bb12c..dee038f0b 100644
--- a/src/buildstream/_options/optionpool.py
+++ b/src/buildstream/_options/optionpool.py
@@ -20,7 +20,8 @@
import jinja2
-from .._exceptions import LoadError, LoadErrorReason
+from .._exceptions import LoadError
+from ..exceptions import LoadErrorReason
from ..node import MappingNode, SequenceNode, _assert_symbol_name
from ..types import FastEnum
from .optionbool import OptionBool
diff --git a/src/buildstream/_plugincontext.py b/src/buildstream/_plugincontext.py
index 295482574..3a195e239 100644
--- a/src/buildstream/_plugincontext.py
+++ b/src/buildstream/_plugincontext.py
@@ -20,7 +20,8 @@
import os
import inspect
-from ._exceptions import PluginError, LoadError, LoadErrorReason
+from ._exceptions import PluginError, LoadError
+from .exceptions import LoadErrorReason
from . import utils
diff --git a/src/buildstream/_project.py b/src/buildstream/_project.py
index 0a9580dbe..ed3810350 100644
--- a/src/buildstream/_project.py
+++ b/src/buildstream/_project.py
@@ -28,7 +28,8 @@ from . import _site
from . import _yaml
from ._artifactelement import ArtifactElement
from ._profile import Topics, PROFILER
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
from ._options import OptionPool
from ._artifactcache import ArtifactCache
from ._sourcecache import SourceCache
diff --git a/src/buildstream/_projectrefs.py b/src/buildstream/_projectrefs.py
index aca7c6712..6af470808 100644
--- a/src/buildstream/_projectrefs.py
+++ b/src/buildstream/_projectrefs.py
@@ -20,7 +20,8 @@ import os
from . import _yaml
from .node import _new_synthetic_file
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
# ProjectRefStorage()
diff --git a/src/buildstream/_remote.py b/src/buildstream/_remote.py
index f8edd5192..d01b13b32 100644
--- a/src/buildstream/_remote.py
+++ b/src/buildstream/_remote.py
@@ -21,7 +21,8 @@ from urllib.parse import urlparse
import grpc
-from ._exceptions import LoadError, LoadErrorReason, ImplError, RemoteError
+from ._exceptions import LoadError, ImplError, RemoteError
+from .exceptions import LoadErrorReason
from .types import FastEnum
diff --git a/src/buildstream/_variables.pyx b/src/buildstream/_variables.pyx
index f8662ac61..f9de2a6cc 100644
--- a/src/buildstream/_variables.pyx
+++ b/src/buildstream/_variables.pyx
@@ -23,7 +23,8 @@
import re
import sys
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
from .node cimport MappingNode
# Variables are allowed to have dashes here
diff --git a/src/buildstream/_workspaces.py b/src/buildstream/_workspaces.py
index 49b76a7b9..5c3b4af8f 100644
--- a/src/buildstream/_workspaces.py
+++ b/src/buildstream/_workspaces.py
@@ -22,7 +22,8 @@ from . import utils
from . import _yaml
from .node import MappingNode, ScalarNode
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
BST_WORKSPACE_FORMAT_VERSION = 3
diff --git a/src/buildstream/_yaml.pyx b/src/buildstream/_yaml.pyx
index 797e10d15..373311a47 100644
--- a/src/buildstream/_yaml.pyx
+++ b/src/buildstream/_yaml.pyx
@@ -29,7 +29,8 @@ from collections.abc import Mapping
from ruamel import yaml
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
from . cimport node
from .node cimport MappingNode, ScalarNode, SequenceNode
diff --git a/src/buildstream/element.py b/src/buildstream/element.py
index d39135b53..fe7d36649 100644
--- a/src/buildstream/element.py
+++ b/src/buildstream/element.py
@@ -89,7 +89,8 @@ from pyroaring import BitMap # pylint: disable=no-name-in-module
from . import _yaml
from ._variables import Variables
from ._versions import BST_CORE_ARTIFACT_VERSION
-from ._exceptions import BstError, LoadError, LoadErrorReason, ImplError, ErrorDomain, SourceCacheError
+from ._exceptions import BstError, LoadError, ImplError, SourceCacheError
+from .exceptions import ErrorDomain, LoadErrorReason
from .utils import FileListResult
from . import utils
from . import _cachekey
diff --git a/src/buildstream/exceptions.py b/src/buildstream/exceptions.py
new file mode 100644
index 000000000..123e18d72
--- /dev/null
+++ b/src/buildstream/exceptions.py
@@ -0,0 +1,141 @@
+#
+# Copyright (C) 2018 Codethink Limited
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library. If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors:
+# Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
+# Tiago Gomes <tiago.gomes@codethink.co.uk>
+"""
+Exceptions - API for Error Handling
+===================================
+
+This module contains some Enums used in Error Handling which are useful in
+testing external plugins.
+"""
+
+from enum import Enum, unique
+
+
+@unique
+class ErrorDomain(Enum):
+ """ErrorDomain
+
+ Describes what the error is related to.
+ """
+
+ PLUGIN = 1
+ LOAD = 2
+ IMPL = 3
+ PLATFORM = 4
+ SANDBOX = 5
+ ARTIFACT = 6
+ PIPELINE = 7
+ UTIL = 8
+ SOURCE = 9
+ ELEMENT = 10
+ APP = 11
+ STREAM = 12
+ VIRTUAL_FS = 13
+ CAS = 14
+ PROG_NOT_FOUND = 15
+ REMOTE = 16
+ PROFILE = 17
+
+
+class LoadErrorReason(Enum):
+ """LoadErrorReason
+
+ Describes the reason why a :class:`.LoadError` was raised.
+ """
+
+ MISSING_FILE = 1
+ """A file was not found."""
+
+ INVALID_YAML = 2
+ """The parsed data was not valid YAML."""
+
+ INVALID_DATA = 3
+ """Data was malformed, a value was not of the expected type, etc"""
+
+ ILLEGAL_COMPOSITE = 4
+ """An error occurred during YAML dictionary composition.
+
+ This can happen by overriding a value with a new differently typed
+ value, or by overwriting some named value when that was not allowed.
+ """
+
+ CIRCULAR_DEPENDENCY = 5
+ """A circular dependency chain was detected"""
+
+ UNRESOLVED_VARIABLE = 6
+ """A variable could not be resolved. This can happen if your project
+ has cyclic dependencies in variable declarations, or, when substituting
+ a string which refers to an undefined variable.
+ """
+
+ UNSUPPORTED_PROJECT = 7
+ """BuildStream does not support the required project format version"""
+
+ UNSUPPORTED_PLUGIN = 8
+ """Project requires a newer version of a plugin than the one which was
+ loaded
+ """
+
+ EXPRESSION_FAILED = 9
+ """A conditional expression failed to resolve"""
+
+ USER_ASSERTION = 10
+ """An assertion was intentionally encoded into project YAML"""
+
+ TRAILING_LIST_DIRECTIVE = 11
+ """A list composition directive did not apply to any underlying list"""
+
+ CONFLICTING_JUNCTION = 12
+ """Conflicting junctions in subprojects"""
+
+ INVALID_JUNCTION = 13
+ """Failure to load a project from a specified junction"""
+
+ SUBPROJECT_INCONSISTENT = 15
+ """Subproject has no ref"""
+
+ INVALID_SYMBOL_NAME = 16
+ """An invalid symbol name was encountered"""
+
+ MISSING_PROJECT_CONF = 17
+ """A project.conf file was missing"""
+
+ LOADING_DIRECTORY = 18
+ """Try to load a directory not a yaml file"""
+
+ PROJ_PATH_INVALID = 19
+ """A project path leads outside of the project directory"""
+
+ PROJ_PATH_INVALID_KIND = 20
+ """A project path points to a file of the not right kind (e.g. a
+ socket)
+ """
+
+ RECURSIVE_INCLUDE = 21
+ """A recursive include has been encountered"""
+
+ RECURSIVE_VARIABLE = 22
+ """A recursive variable has been encountered"""
+
+ PROTECTED_VARIABLE_REDEFINED = 23
+ """An attempt was made to set the value of a protected variable"""
+
+ DUPLICATE_DEPENDENCY = 24
+ """A duplicate dependency was detected"""
diff --git a/src/buildstream/node.pyx b/src/buildstream/node.pyx
index 58fd0f33d..87c2ab6d1 100644
--- a/src/buildstream/node.pyx
+++ b/src/buildstream/node.pyx
@@ -50,7 +50,8 @@ Class Reference
import string
-from ._exceptions import LoadError, LoadErrorReason
+from ._exceptions import LoadError
+from .exceptions import LoadErrorReason
# A sentinel to be used as a default argument for functions that need
diff --git a/src/buildstream/source.py b/src/buildstream/source.py
index 4839cf0fe..a221d30a4 100644
--- a/src/buildstream/source.py
+++ b/src/buildstream/source.py
@@ -166,7 +166,8 @@ from . import _yaml, utils
from .node import MappingNode
from .plugin import Plugin
from .types import SourceRef, Union, List
-from ._exceptions import BstError, ImplError, PluginError, ErrorDomain
+from ._exceptions import BstError, ImplError, PluginError
+from .exceptions import ErrorDomain
from ._loader.metasource import MetaSource
from ._projectrefs import ProjectRefStorage
from ._cachekey import generate_key
diff --git a/src/buildstream/storage/directory.py b/src/buildstream/storage/directory.py
index 89d20c433..2d3dfd4da 100644
--- a/src/buildstream/storage/directory.py
+++ b/src/buildstream/storage/directory.py
@@ -34,7 +34,8 @@ See also: :ref:`sandboxing`.
from typing import Callable, Optional, Union
-from .._exceptions import BstError, ErrorDomain
+from .._exceptions import BstError
+from ..exceptions import ErrorDomain
from ..types import FastEnum
from ..utils import BST_ARBITRARY_TIMESTAMP, FileListResult
diff --git a/src/buildstream/testing/__init__.py b/src/buildstream/testing/__init__.py
index 67e96885a..46cadbbfa 100644
--- a/src/buildstream/testing/__init__.py
+++ b/src/buildstream/testing/__init__.py
@@ -21,6 +21,7 @@ This package contains various utilities which make it easier to test plugins.
import os
from collections import OrderedDict
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from .repo import Repo
from .runcli import cli, cli_integration, cli_remote_execution
from .integration import integration_cache
diff --git a/src/buildstream/testing/_sourcetests/mirror.py b/src/buildstream/testing/_sourcetests/mirror.py
index 3ff3fb981..de05b894c 100644
--- a/src/buildstream/testing/_sourcetests/mirror.py
+++ b/src/buildstream/testing/_sourcetests/mirror.py
@@ -23,7 +23,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from .._utils import generate_junction
from .. import create_repo
from .. import cli # pylint: disable=unused-import
diff --git a/src/buildstream/testing/_sourcetests/track.py b/src/buildstream/testing/_sourcetests/track.py
index 623045cd9..ecb508b1a 100644
--- a/src/buildstream/testing/_sourcetests/track.py
+++ b/src/buildstream/testing/_sourcetests/track.py
@@ -23,7 +23,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from .._utils import generate_junction
from .. import create_repo
from .. import cli # pylint: disable=unused-import
diff --git a/src/buildstream/utils.py b/src/buildstream/utils.py
index 545816e89..88314b263 100644
--- a/src/buildstream/utils.py
+++ b/src/buildstream/utils.py
@@ -41,7 +41,8 @@ from typing import Callable, IO, Iterable, Iterator, Optional, Tuple, Union
import psutil
from . import _signals
-from ._exceptions import BstError, ErrorDomain
+from ._exceptions import BstError
+from .exceptions import ErrorDomain
from ._protos.build.bazel.remote.execution.v2 import remote_execution_pb2
# Contains utils that have been rewritten in Cython for speed benefits
diff --git a/tests/artifactcache/config.py b/tests/artifactcache/config.py
index 64e6c6a30..a42d1e487 100644
--- a/tests/artifactcache/config.py
+++ b/tests/artifactcache/config.py
@@ -11,7 +11,7 @@ from buildstream._artifactcache import ArtifactCache
from buildstream._project import Project
from buildstream.utils import _deduplicate
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
diff --git a/tests/artifactcache/expiry.py b/tests/artifactcache/expiry.py
index 83577f0c6..1474cecf6 100644
--- a/tests/artifactcache/expiry.py
+++ b/tests/artifactcache/expiry.py
@@ -26,7 +26,7 @@ import time
import pytest
from buildstream._cas import CASCache
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils import create_element_size, wait_for_cache_granularity
diff --git a/tests/elements/filter.py b/tests/elements/filter.py
index 3b38094dc..2f16270d8 100644
--- a/tests/elements/filter.py
+++ b/tests/elements/filter.py
@@ -8,7 +8,7 @@ import pytest
from buildstream.testing import create_repo
from buildstream.testing import cli # pylint: disable=unused-import
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream import _yaml
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "filter",)
diff --git a/tests/format/assertion.py b/tests/format/assertion.py
index 67436250a..3ca50726c 100644
--- a/tests/format/assertion.py
+++ b/tests/format/assertion.py
@@ -3,7 +3,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/dependencies.py b/tests/format/dependencies.py
index e54b9b2d5..b1a684081 100644
--- a/tests/format/dependencies.py
+++ b/tests/format/dependencies.py
@@ -4,7 +4,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
DATA_DIR = os.path.dirname(os.path.realpath(__file__))
diff --git a/tests/format/include.py b/tests/format/include.py
index 5efbc62a9..3e7e0abf0 100644
--- a/tests/format/include.py
+++ b/tests/format/include.py
@@ -5,7 +5,7 @@ import os
import textwrap
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream.testing import create_repo
from tests.testutils import generate_junction
diff --git a/tests/format/invalid_keys.py b/tests/format/invalid_keys.py
index ce1e2e487..b2bab194e 100644
--- a/tests/format/invalid_keys.py
+++ b/tests/format/invalid_keys.py
@@ -3,7 +3,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/junctions.py b/tests/format/junctions.py
index 43cd3f7ba..581e7442f 100644
--- a/tests/format/junctions.py
+++ b/tests/format/junctions.py
@@ -7,7 +7,7 @@ import shutil
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream.testing import create_repo
from buildstream.testing._utils.site import HAVE_GIT
diff --git a/tests/format/listdirectiveerrors.py b/tests/format/listdirectiveerrors.py
index 79102cb02..77d9b3f55 100644
--- a/tests/format/listdirectiveerrors.py
+++ b/tests/format/listdirectiveerrors.py
@@ -3,7 +3,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/optionarch.py b/tests/format/optionarch.py
index 75cae9abe..4f7084b11 100644
--- a/tests/format/optionarch.py
+++ b/tests/format/optionarch.py
@@ -6,7 +6,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
from tests.testutils import override_platform_uname
diff --git a/tests/format/optionbool.py b/tests/format/optionbool.py
index 3b05aafa1..6f5624926 100644
--- a/tests/format/optionbool.py
+++ b/tests/format/optionbool.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/optioneltmask.py b/tests/format/optioneltmask.py
index 399b37b97..c5b32d127 100644
--- a/tests/format/optioneltmask.py
+++ b/tests/format/optioneltmask.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/optionenum.py b/tests/format/optionenum.py
index ba79bea79..b525347f8 100644
--- a/tests/format/optionenum.py
+++ b/tests/format/optionenum.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/optionflags.py b/tests/format/optionflags.py
index 53e674919..a3c310f05 100644
--- a/tests/format/optionflags.py
+++ b/tests/format/optionflags.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/optionos.py b/tests/format/optionos.py
index 16177c4fb..46ec22de5 100644
--- a/tests/format/optionos.py
+++ b/tests/format/optionos.py
@@ -6,7 +6,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
from tests.testutils import override_platform_uname
diff --git a/tests/format/options.py b/tests/format/options.py
index aa0854e96..4af3495b4 100644
--- a/tests/format/options.py
+++ b/tests/format/options.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/project.py b/tests/format/project.py
index e6bc6a5cd..3d0931b86 100644
--- a/tests/format/project.py
+++ b/tests/format/project.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils import filetypegenerator
diff --git a/tests/format/userconfig.py b/tests/format/userconfig.py
index 9b514cc3d..134327bad 100644
--- a/tests/format/userconfig.py
+++ b/tests/format/userconfig.py
@@ -5,7 +5,7 @@ import os
import pytest
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/format/variables.py b/tests/format/variables.py
index 1d8b5aff9..11a34ee07 100644
--- a/tests/format/variables.py
+++ b/tests/format/variables.py
@@ -7,7 +7,7 @@ import sys
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
diff --git a/tests/frontend/artifact_delete.py b/tests/frontend/artifact_delete.py
index a93d99ef6..2651f567e 100644
--- a/tests/frontend/artifact_delete.py
+++ b/tests/frontend/artifact_delete.py
@@ -22,7 +22,7 @@ import os
import pytest
from buildstream.element import _get_normal_name
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils import create_artifact_share
diff --git a/tests/frontend/artifact_show.py b/tests/frontend/artifact_show.py
index 6f824c0e4..de9b78c45 100644
--- a/tests/frontend/artifact_show.py
+++ b/tests/frontend/artifact_show.py
@@ -21,7 +21,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils import create_artifact_share
diff --git a/tests/frontend/buildcheckout.py b/tests/frontend/buildcheckout.py
index d6a216daf..512c6c151 100644
--- a/tests/frontend/buildcheckout.py
+++ b/tests/frontend/buildcheckout.py
@@ -12,7 +12,7 @@ from buildstream.testing import cli # pylint: disable=unused-import
from buildstream.testing import create_repo
from buildstream.testing._utils.site import IS_WINDOWS, CASD_SEPARATE_USER
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream import utils
from tests.testutils import generate_junction, create_artifact_share
diff --git a/tests/frontend/configurable_warnings.py b/tests/frontend/configurable_warnings.py
index 488dab233..be0706360 100644
--- a/tests/frontend/configurable_warnings.py
+++ b/tests/frontend/configurable_warnings.py
@@ -6,7 +6,7 @@ import os
import pytest
from buildstream.plugin import CoreWarnings
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream import _yaml
from buildstream.testing.runcli import cli # pylint: disable=unused-import
diff --git a/tests/frontend/fetch.py b/tests/frontend/fetch.py
index 8bd54ccc1..d6b28c589 100644
--- a/tests/frontend/fetch.py
+++ b/tests/frontend/fetch.py
@@ -6,7 +6,7 @@ import pytest
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from tests.testutils import generate_junction
diff --git a/tests/frontend/init.py b/tests/frontend/init.py
index 3b9a95c34..78aa3eb19 100644
--- a/tests/frontend/init.py
+++ b/tests/frontend/init.py
@@ -7,7 +7,7 @@ from buildstream.testing import cli # pylint: disable=unused-import
from buildstream import _yaml
from buildstream._frontend.app import App
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream._versions import BST_FORMAT_VERSION
diff --git a/tests/frontend/logging.py b/tests/frontend/logging.py
index 27ff88352..7db37fa4c 100644
--- a/tests/frontend/logging.py
+++ b/tests/frontend/logging.py
@@ -9,7 +9,7 @@ import pytest
from buildstream.testing import create_repo
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
# Project directory
diff --git a/tests/frontend/overlaps.py b/tests/frontend/overlaps.py
index e1c5a7c94..d734a3781 100644
--- a/tests/frontend/overlaps.py
+++ b/tests/frontend/overlaps.py
@@ -4,7 +4,7 @@
import os
import pytest
from buildstream.testing.runcli import cli # pylint: disable=unused-import
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream import _yaml
from buildstream.plugin import CoreWarnings
from tests.testutils import generate_junction
diff --git a/tests/frontend/progress.py b/tests/frontend/progress.py
index 45cba0b50..5d446bb10 100644
--- a/tests/frontend/progress.py
+++ b/tests/frontend/progress.py
@@ -6,7 +6,7 @@ import pytest
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from tests.testutils import generate_junction
diff --git a/tests/frontend/push.py b/tests/frontend/push.py
index 583b57399..e9dfa2c6a 100644
--- a/tests/frontend/push.py
+++ b/tests/frontend/push.py
@@ -26,7 +26,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils import (
create_artifact_share,
diff --git a/tests/frontend/show.py b/tests/frontend/show.py
index 94b94a058..17931ffe3 100644
--- a/tests/frontend/show.py
+++ b/tests/frontend/show.py
@@ -8,7 +8,7 @@ import itertools
import pytest
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from tests.testutils import generate_junction
diff --git a/tests/frontend/track.py b/tests/frontend/track.py
index 477c81556..07a89d428 100644
--- a/tests/frontend/track.py
+++ b/tests/frontend/track.py
@@ -7,7 +7,7 @@ import pytest
from buildstream.testing import create_repo
from buildstream.testing import cli # pylint: disable=unused-import
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream import _yaml
from tests.testutils import generate_junction
from . import configure_project
diff --git a/tests/frontend/workspace.py b/tests/frontend/workspace.py
index eabaca68c..e05b6bd1f 100644
--- a/tests/frontend/workspace.py
+++ b/tests/frontend/workspace.py
@@ -37,7 +37,7 @@ import pytest
from buildstream.testing import create_repo, ALL_REPO_KINDS
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream._workspaces import BST_WORKSPACE_FORMAT_VERSION
from tests.testutils import create_artifact_share, create_element_size, wait_for_cache_granularity
diff --git a/tests/integration/cachedfail.py b/tests/integration/cachedfail.py
index 9d68635e8..da764bbd2 100644
--- a/tests/integration/cachedfail.py
+++ b/tests/integration/cachedfail.py
@@ -21,7 +21,7 @@ import os
import pytest
from buildstream import utils, _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli_integration as cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX
diff --git a/tests/integration/messages.py b/tests/integration/messages.py
index f35b778d6..1a324a61f 100644
--- a/tests/integration/messages.py
+++ b/tests/integration/messages.py
@@ -24,7 +24,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli_integration as cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX
diff --git a/tests/integration/pullbuildtrees.py b/tests/integration/pullbuildtrees.py
index b43a07121..6d9eefb26 100644
--- a/tests/integration/pullbuildtrees.py
+++ b/tests/integration/pullbuildtrees.py
@@ -8,7 +8,7 @@ import pytest
from buildstream.testing import cli, cli_integration as cli2 # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from tests.testutils import create_artifact_share
diff --git a/tests/integration/sandbox-bwrap.py b/tests/integration/sandbox-bwrap.py
index a6312914b..3bf734edb 100644
--- a/tests/integration/sandbox-bwrap.py
+++ b/tests/integration/sandbox-bwrap.py
@@ -4,7 +4,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli_integration as cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX, HAVE_BWRAP_JSON_STATUS
diff --git a/tests/integration/shell.py b/tests/integration/shell.py
index 040ae53a5..5e35d550c 100644
--- a/tests/integration/shell.py
+++ b/tests/integration/shell.py
@@ -7,7 +7,7 @@ import pytest
from buildstream import _yaml
from buildstream.testing import cli_integration as cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX, BUILDBOX_RUN
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream import utils
from tests.testutils import create_artifact_share
diff --git a/tests/integration/shellbuildtrees.py b/tests/integration/shellbuildtrees.py
index a3e7da1c2..0d80c1640 100644
--- a/tests/integration/shellbuildtrees.py
+++ b/tests/integration/shellbuildtrees.py
@@ -7,7 +7,7 @@ import shutil
import pytest
from buildstream.testing import cli, cli_integration # pylint: disable=unused-import
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing._utils.site import HAVE_SANDBOX
from tests.testutils import create_artifact_share
diff --git a/tests/integration/workspace.py b/tests/integration/workspace.py
index 776a1a1a6..7e84b690b 100644
--- a/tests/integration/workspace.py
+++ b/tests/integration/workspace.py
@@ -7,7 +7,7 @@ import pytest
from buildstream import _yaml
from buildstream.testing import cli_integration as cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
pytestmark = pytest.mark.integration
diff --git a/tests/internals/context.py b/tests/internals/context.py
index c2ee1efb5..a8b9f6dd3 100644
--- a/tests/internals/context.py
+++ b/tests/internals/context.py
@@ -5,7 +5,8 @@ import os
import pytest
from buildstream._context import Context
-from buildstream._exceptions import LoadError, LoadErrorReason
+from buildstream._exceptions import LoadError
+from buildstream.exceptions import LoadErrorReason
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "context",)
diff --git a/tests/internals/loader.py b/tests/internals/loader.py
index 781d144ae..6fdd9fc3a 100644
--- a/tests/internals/loader.py
+++ b/tests/internals/loader.py
@@ -2,7 +2,8 @@ from contextlib import contextmanager
import os
import pytest
-from buildstream._exceptions import LoadError, LoadErrorReason
+from buildstream.exceptions import LoadErrorReason
+from buildstream._exceptions import LoadError
from buildstream._project import Project
from buildstream._loader import MetaElement
from buildstream._loader.loader import _NO_PROGRESS
diff --git a/tests/internals/pluginloading.py b/tests/internals/pluginloading.py
index 83944bbd9..0685b09da 100644
--- a/tests/internals/pluginloading.py
+++ b/tests/internals/pluginloading.py
@@ -3,7 +3,8 @@ import os
import pytest
from buildstream._project import Project
-from buildstream._exceptions import LoadError, LoadErrorReason
+from buildstream._exceptions import LoadError
+from buildstream.exceptions import LoadErrorReason
from buildstream._pipeline import Pipeline
from tests.testutils import dummy_context
diff --git a/tests/internals/yaml.py b/tests/internals/yaml.py
index 7b711575c..a4f8d08cc 100644
--- a/tests/internals/yaml.py
+++ b/tests/internals/yaml.py
@@ -4,7 +4,8 @@ from io import StringIO
import pytest
from buildstream import _yaml, Node, ProvenanceInformation, SequenceNode
-from buildstream._exceptions import LoadError, LoadErrorReason
+from buildstream.exceptions import LoadErrorReason
+from buildstream._exceptions import LoadError
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "yaml",)
diff --git a/tests/remoteexecution/buildfail.py b/tests/remoteexecution/buildfail.py
index 22d9c825f..37f4dcafa 100644
--- a/tests/remoteexecution/buildfail.py
+++ b/tests/remoteexecution/buildfail.py
@@ -21,7 +21,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream import _yaml
from buildstream.testing import cli_remote_execution as cli # pylint: disable=unused-import
diff --git a/tests/remoteexecution/partial.py b/tests/remoteexecution/partial.py
index a452d6613..ec5fabedb 100644
--- a/tests/remoteexecution/partial.py
+++ b/tests/remoteexecution/partial.py
@@ -4,7 +4,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli_remote_execution as cli # pylint: disable=unused-import
from buildstream.testing.integration import assert_contains
diff --git a/tests/sandboxes/fallback.py b/tests/sandboxes/fallback.py
index 948e3a6de..0fd8ed4aa 100644
--- a/tests/sandboxes/fallback.py
+++ b/tests/sandboxes/fallback.py
@@ -20,7 +20,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
pytestmark = pytest.mark.integration
diff --git a/tests/sandboxes/missing-command.py b/tests/sandboxes/missing-command.py
index 87e668966..ec6ba184b 100644
--- a/tests/sandboxes/missing-command.py
+++ b/tests/sandboxes/missing-command.py
@@ -4,7 +4,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
diff --git a/tests/sandboxes/missing_dependencies.py b/tests/sandboxes/missing_dependencies.py
index 722cfc647..2e96a1b1f 100644
--- a/tests/sandboxes/missing_dependencies.py
+++ b/tests/sandboxes/missing_dependencies.py
@@ -6,7 +6,7 @@ import os
import pytest
from buildstream import utils, _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing._utils.site import IS_LINUX
from buildstream.testing import cli # pylint: disable=unused-import
diff --git a/tests/sandboxes/remote-exec-config.py b/tests/sandboxes/remote-exec-config.py
index 7066ddeab..a6297834b 100644
--- a/tests/sandboxes/remote-exec-config.py
+++ b/tests/sandboxes/remote-exec-config.py
@@ -6,7 +6,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "remote-exec-config")
diff --git a/tests/sandboxes/selection.py b/tests/sandboxes/selection.py
index a338fe0bb..daee6dcdd 100644
--- a/tests/sandboxes/selection.py
+++ b/tests/sandboxes/selection.py
@@ -20,7 +20,7 @@ import os
import pytest
from buildstream import utils, _yaml
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
pytestmark = pytest.mark.integration
diff --git a/tests/sourcecache/config.py b/tests/sourcecache/config.py
index 9233e9f44..0c11a2726 100644
--- a/tests/sourcecache/config.py
+++ b/tests/sourcecache/config.py
@@ -25,7 +25,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing.runcli import cli # pylint: disable=unused-import
diff --git a/tests/sourcecache/fetch.py b/tests/sourcecache/fetch.py
index e21f84c89..889de62f0 100644
--- a/tests/sourcecache/fetch.py
+++ b/tests/sourcecache/fetch.py
@@ -24,7 +24,7 @@ import os
import shutil
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream._project import Project
from buildstream import _yaml
from buildstream.testing import cli # pylint: disable=unused-import
diff --git a/tests/sourcecache/push.py b/tests/sourcecache/push.py
index 210bbfcff..9f8663a4a 100644
--- a/tests/sourcecache/push.py
+++ b/tests/sourcecache/push.py
@@ -25,7 +25,7 @@ from contextlib import contextmanager, ExitStack
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream._project import Project
from buildstream import _yaml
from buildstream.testing import cli # pylint: disable=unused-import
diff --git a/tests/sourcecache/source-checkout.py b/tests/sourcecache/source-checkout.py
index f1e0706a7..8abceadbd 100644
--- a/tests/sourcecache/source-checkout.py
+++ b/tests/sourcecache/source-checkout.py
@@ -26,7 +26,7 @@ import shutil
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.exceptions import ErrorDomain
from buildstream.testing.runcli import cli # pylint: disable=unused-import
from tests.testutils.element_generators import create_element_size
diff --git a/tests/sources/git.py b/tests/sources/git.py
index 25976ffca..1176c8ffd 100644
--- a/tests/sources/git.py
+++ b/tests/sources/git.py
@@ -29,8 +29,8 @@ import shutil
import pytest
-from buildstream._exceptions import ErrorDomain
from buildstream import _yaml, Node
+from buildstream.exceptions import ErrorDomain
from buildstream.plugin import CoreWarnings
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream.testing import create_repo
diff --git a/tests/sources/keytest.py b/tests/sources/keytest.py
index 46d0d07fe..70e01f60f 100644
--- a/tests/sources/keytest.py
+++ b/tests/sources/keytest.py
@@ -24,7 +24,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.testing import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
DATA_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "project_key_test")
diff --git a/tests/sources/local.py b/tests/sources/local.py
index 92313ca7f..2b0155107 100644
--- a/tests/sources/local.py
+++ b/tests/sources/local.py
@@ -5,7 +5,7 @@ import os
import pytest
from buildstream import _yaml
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_SANDBOX
from tests.testutils import filetypegenerator
diff --git a/tests/sources/patch.py b/tests/sources/patch.py
index 2b80a7055..5392a64cb 100644
--- a/tests/sources/patch.py
+++ b/tests/sources/patch.py
@@ -4,7 +4,7 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain, LoadErrorReason
+from buildstream.exceptions import ErrorDomain, LoadErrorReason
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils import filetypegenerator
diff --git a/tests/sources/pip.py b/tests/sources/pip.py
index aafdfaf1c..7020f19c2 100644
--- a/tests/sources/pip.py
+++ b/tests/sources/pip.py
@@ -4,8 +4,8 @@
import os
import pytest
-from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
+from buildstream.exceptions import ErrorDomain
from buildstream.plugins.sources.pip import _match_package_name
from buildstream.testing import cli # pylint: disable=unused-import
diff --git a/tests/sources/remote.py b/tests/sources/remote.py
index 76e469c60..00a7687b3 100644
--- a/tests/sources/remote.py
+++ b/tests/sources/remote.py
@@ -5,7 +5,7 @@ import os
import stat
import pytest
-from buildstream._exceptions import ErrorDomain
+from buildstream.testing import ErrorDomain
from buildstream import _yaml
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils.file_server import create_file_server
diff --git a/tests/sources/tar.py b/tests/sources/tar.py
index c3621c152..d35cc2964 100644
--- a/tests/sources/tar.py
+++ b/tests/sources/tar.py
@@ -11,8 +11,8 @@ import urllib.parse
import pytest
from buildstream import utils
-from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
from buildstream.testing._utils.site import HAVE_LZIP
from tests.testutils.file_server import create_file_server
diff --git a/tests/sources/zip.py b/tests/sources/zip.py
index dcb1e2637..7c47058b5 100644
--- a/tests/sources/zip.py
+++ b/tests/sources/zip.py
@@ -6,8 +6,8 @@ import zipfile
import pytest
-from buildstream._exceptions import ErrorDomain
from buildstream import _yaml
+from buildstream.exceptions import ErrorDomain
from buildstream.testing import cli # pylint: disable=unused-import
from tests.testutils.file_server import create_file_server
from . import list_dir_contents