bugfix: ensure all bootstrap context managers are exception-safe

When context managers are used to save and restore values, we need to remember
to use try/finally around the yield in case an exception is thrown.  Otherwise,
the cleanup will be skipped.
This commit is contained in:
Todd Gamblin 2021-08-02 21:51:33 -07:00 committed by Massimiliano Culpo
parent 693c4d8f3a
commit 0a0338ddfa
4 changed files with 37 additions and 27 deletions

View File

@ -593,17 +593,20 @@ def use_platform(new_platform):
assert isinstance(new_platform, Platform), msg.format(new_platform) assert isinstance(new_platform, Platform), msg.format(new_platform)
original_platform_fn, original_all_platforms_fn = platform, all_platforms original_platform_fn, original_all_platforms_fn = platform, all_platforms
platform = _PickleableCallable(new_platform)
all_platforms = _PickleableCallable([type(new_platform)])
# Clear configuration and compiler caches try:
spack.config.config.clear_caches() platform = _PickleableCallable(new_platform)
spack.compilers._cache_config_files = [] all_platforms = _PickleableCallable([type(new_platform)])
yield new_platform # Clear configuration and compiler caches
spack.config.config.clear_caches()
spack.compilers._cache_config_files = []
platform, all_platforms = original_platform_fn, original_all_platforms_fn yield new_platform
# Clear configuration and compiler caches finally:
spack.config.config.clear_caches() platform, all_platforms = original_platform_fn, original_all_platforms_fn
spack.compilers._cache_config_files = []
# Clear configuration and compiler caches
spack.config.config.clear_caches()
spack.compilers._cache_config_files = []

View File

@ -1238,11 +1238,12 @@ def use_configuration(*scopes_or_paths):
saved_config, config = config, configuration saved_config, config = config, configuration
yield configuration try:
yield configuration
# Restore previous config files finally:
spack.compilers._cache_config_file = saved_compiler_cache # Restore previous config files
config = saved_config spack.compilers._cache_config_file = saved_compiler_cache
config = saved_config
@llnl.util.lang.memoized @llnl.util.lang.memoized

View File

@ -1299,19 +1299,24 @@ def use_repositories(*paths_and_repos):
""" """
global path global path
remove_from_meta = None
# Construct a temporary RepoPath object from # Construct a temporary RepoPath object from
temporary_repositories = RepoPath(*paths_and_repos) temporary_repositories = RepoPath(*paths_and_repos)
# Swap the current repository out # Swap the current repository out
saved = path saved = path
remove_from_meta = set_path(temporary_repositories)
yield temporary_repositories try:
remove_from_meta = set_path(temporary_repositories)
# Restore _path and sys.meta_path yield temporary_repositories
if remove_from_meta:
sys.meta_path.remove(temporary_repositories) finally:
path = saved # Restore _path and sys.meta_path
if remove_from_meta:
sys.meta_path.remove(temporary_repositories)
path = saved
class RepoError(spack.error.SpackError): class RepoError(spack.error.SpackError):

View File

@ -301,9 +301,10 @@ def use_store(store_or_path):
db, layout = store.db, store.layout db, layout = store.db, store.layout
root, unpadded_root = store.root, store.unpadded_root root, unpadded_root = store.root, store.unpadded_root
yield temporary_store try:
yield temporary_store
# Restore the original store finally:
store = original_store # Restore the original store
db, layout = original_store.db, original_store.layout store = original_store
root, unpadded_root = original_store.root, original_store.unpadded_root db, layout = original_store.db, original_store.layout
root, unpadded_root = original_store.root, original_store.unpadded_root