diff options
author | Todd Gamblin <tgamblin@llnl.gov> | 2021-08-02 21:51:33 -0700 |
---|---|---|
committer | Massimiliano Culpo <massimiliano.culpo@gmail.com> | 2021-08-03 10:07:11 +0200 |
commit | 0a0338ddfa7b42a8cd630a664ea3fc40d4650408 (patch) | |
tree | c8f024a31aabe1d623b5a05687eddb20825037a3 /lib | |
parent | 693c4d8f3ad59dd8d9efa750398510e4a7f0f4ae (diff) | |
download | spack-0a0338ddfa7b42a8cd630a664ea3fc40d4650408.tar.gz spack-0a0338ddfa7b42a8cd630a664ea3fc40d4650408.tar.bz2 spack-0a0338ddfa7b42a8cd630a664ea3fc40d4650408.tar.xz spack-0a0338ddfa7b42a8cd630a664ea3fc40d4650408.zip |
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.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/architecture.py | 23 | ||||
-rw-r--r-- | lib/spack/spack/config.py | 11 | ||||
-rw-r--r-- | lib/spack/spack/repo.py | 17 | ||||
-rw-r--r-- | lib/spack/spack/store.py | 13 |
4 files changed, 37 insertions, 27 deletions
diff --git a/lib/spack/spack/architecture.py b/lib/spack/spack/architecture.py index 17fbc0e2f1..44ce51ddfd 100644 --- a/lib/spack/spack/architecture.py +++ b/lib/spack/spack/architecture.py @@ -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 = [] diff --git a/lib/spack/spack/config.py b/lib/spack/spack/config.py index 93399efb03..7ea89b7c98 100644 --- a/lib/spack/spack/config.py +++ b/lib/spack/spack/config.py @@ -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 diff --git a/lib/spack/spack/repo.py b/lib/spack/spack/repo.py index ef1d684cad..74c5cd2d87 100644 --- a/lib/spack/spack/repo.py +++ b/lib/spack/spack/repo.py @@ -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) + + yield temporary_repositories - # Restore _path and sys.meta_path - if remove_from_meta: - sys.meta_path.remove(temporary_repositories) - path = saved + finally: + # Restore _path and sys.meta_path + if remove_from_meta: + sys.meta_path.remove(temporary_repositories) + path = saved class RepoError(spack.error.SpackError): diff --git a/lib/spack/spack/store.py b/lib/spack/spack/store.py index a04ece2027..ed5539d7fb 100644 --- a/lib/spack/spack/store.py +++ b/lib/spack/spack/store.py @@ -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 |