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:
parent
693c4d8f3a
commit
0a0338ddfa
4 changed files with 37 additions and 27 deletions
|
@ -593,17 +593,20 @@ def use_platform(new_platform):
|
|||
assert isinstance(new_platform, Platform), msg.format(new_platform)
|
||||
|
||||
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
|
||||
spack.config.config.clear_caches()
|
||||
spack.compilers._cache_config_files = []
|
||||
try:
|
||||
platform = _PickleableCallable(new_platform)
|
||||
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
|
||||
spack.config.config.clear_caches()
|
||||
spack.compilers._cache_config_files = []
|
||||
finally:
|
||||
platform, all_platforms = original_platform_fn, original_all_platforms_fn
|
||||
|
||||
# Clear configuration and compiler caches
|
||||
spack.config.config.clear_caches()
|
||||
spack.compilers._cache_config_files = []
|
||||
|
|
|
@ -1238,11 +1238,12 @@ def use_configuration(*scopes_or_paths):
|
|||
|
||||
saved_config, config = config, configuration
|
||||
|
||||
yield configuration
|
||||
|
||||
# Restore previous config files
|
||||
spack.compilers._cache_config_file = saved_compiler_cache
|
||||
config = saved_config
|
||||
try:
|
||||
yield configuration
|
||||
finally:
|
||||
# Restore previous config files
|
||||
spack.compilers._cache_config_file = saved_compiler_cache
|
||||
config = saved_config
|
||||
|
||||
|
||||
@llnl.util.lang.memoized
|
||||
|
|
|
@ -1299,19 +1299,24 @@ def use_repositories(*paths_and_repos):
|
|||
"""
|
||||
global path
|
||||
|
||||
remove_from_meta = None
|
||||
|
||||
# Construct a temporary RepoPath object from
|
||||
temporary_repositories = RepoPath(*paths_and_repos)
|
||||
|
||||
# Swap the current repository out
|
||||
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
|
||||
if remove_from_meta:
|
||||
sys.meta_path.remove(temporary_repositories)
|
||||
path = saved
|
||||
yield temporary_repositories
|
||||
|
||||
finally:
|
||||
# Restore _path and sys.meta_path
|
||||
if remove_from_meta:
|
||||
sys.meta_path.remove(temporary_repositories)
|
||||
path = saved
|
||||
|
||||
|
||||
class RepoError(spack.error.SpackError):
|
||||
|
|
|
@ -301,9 +301,10 @@ def use_store(store_or_path):
|
|||
db, layout = store.db, store.layout
|
||||
root, unpadded_root = store.root, store.unpadded_root
|
||||
|
||||
yield temporary_store
|
||||
|
||||
# Restore the original store
|
||||
store = original_store
|
||||
db, layout = original_store.db, original_store.layout
|
||||
root, unpadded_root = original_store.root, original_store.unpadded_root
|
||||
try:
|
||||
yield temporary_store
|
||||
finally:
|
||||
# Restore the original store
|
||||
store = original_store
|
||||
db, layout = original_store.db, original_store.layout
|
||||
root, unpadded_root = original_store.root, original_store.unpadded_root
|
||||
|
|
Loading…
Reference in a new issue