Skip to content

Commit dd913f1

Browse files
authored
Merge pull request #5377 from yaochengchen/bugfix_profile_decorator_safety
Ensure preserve_source_parameters restores state on exception
2 parents 0836313 + 1226b8e commit dd913f1

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

yt/data_objects/profiles.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,13 @@ def save_state(*args, **kwargs):
5050
if hasattr(source, "field_parameters"):
5151
old_params = source.field_parameters
5252
source.field_parameters = prof._data_source.field_parameters
53-
tr = func(*args, **kwargs)
54-
source.field_parameters = old_params
55-
else:
56-
tr = func(*args, **kwargs)
57-
return tr
53+
try:
54+
return func(*args, **kwargs)
55+
finally:
56+
# restore field_parameter state even if func raises an exception
57+
# see https://github.com/yt-project/yt/pull/5377
58+
source.field_parameters = old_params
59+
return func(*args, **kwargs)
5860

5961
return save_state
6062

yt/data_objects/tests/test_profiles.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,3 +749,34 @@ def test_export_pandas():
749749
prof.standard_deviation["gas", "density"].d,
750750
np.nan_to_num(df3["density_stddev"]),
751751
)
752+
753+
754+
def test_preserve_source_parameters_restores_field_parameters_on_exception():
755+
# Regression test for preserve_source_parameters:
756+
# the decorator must restore source.field_parameters even if the wrapped
757+
# function raises.
758+
from yt.data_objects.profiles import preserve_source_parameters
759+
760+
class Dummy:
761+
pass
762+
763+
prof = Dummy()
764+
prof._data_source = Dummy()
765+
prof._data_source.field_parameters = {"from_data_source": 1}
766+
767+
source = Dummy()
768+
original_params = {"original": True}
769+
source.field_parameters = original_params
770+
771+
@preserve_source_parameters
772+
def boom(_prof, _source):
773+
# While executing, field_parameters should be temporarily redirected
774+
assert _source.field_parameters is _prof._data_source.field_parameters
775+
raise RuntimeError("boom")
776+
777+
with assert_raises(RuntimeError):
778+
boom(prof, source)
779+
780+
# The key: even after an exception, state should be restored
781+
assert source.field_parameters is original_params
782+
assert_equal(source.field_parameters, {"original": True})

0 commit comments

Comments
 (0)