diff --git a/autofit/non_linear/search/updater.py b/autofit/non_linear/search/updater.py index 6f443418b..217eb3ee7 100644 --- a/autofit/non_linear/search/updater.py +++ b/autofit/non_linear/search/updater.py @@ -8,6 +8,7 @@ import psutil from autoconf import conf +from autoconf.test_mode import skip_latents from autofit import exc from autofit.non_linear.paths.database import DatabasePaths @@ -232,6 +233,8 @@ def _compute_latent_samples( during_analysis: bool, ) -> Optional[Samples]: """Compute and persist latent variable samples if configured.""" + if skip_latents(): + return None if not ( (during_analysis and conf.instance["output"]["latent_during_fit"]) or (not during_analysis and conf.instance["output"]["latent_after_fit"]) diff --git a/test_autofit/non_linear/search/test_updater.py b/test_autofit/non_linear/search/test_updater.py new file mode 100644 index 000000000..fab31aa8c --- /dev/null +++ b/test_autofit/non_linear/search/test_updater.py @@ -0,0 +1,82 @@ +import logging +from unittest.mock import MagicMock + +from autoconf import conf + +from autofit.non_linear.search.updater import SearchUpdater + + +def _make_updater() -> SearchUpdater: + return SearchUpdater( + paths=MagicMock(), + timer=MagicMock(), + search_logger=logging.getLogger("test_updater"), + plot_results_func=MagicMock(), + samples_from_func=MagicMock(), + disable_output=False, + iterations_per_full_update=1.0, + ) + + +def test__compute_latent_samples__skipped_in_test_mode(monkeypatch): + monkeypatch.setenv("PYAUTO_TEST_MODE", "1") + monkeypatch.delenv("PYAUTO_SKIP_LATENTS", raising=False) + + analysis = MagicMock() + result = _make_updater()._compute_latent_samples( + samples=MagicMock(), + samples_save=MagicMock(), + analysis=analysis, + fitness=MagicMock(), + during_analysis=False, + ) + + assert result is None + analysis.compute_latent_samples.assert_not_called() + + +def test__compute_latent_samples__skipped_by_explicit_env_var(monkeypatch): + monkeypatch.delenv("PYAUTO_TEST_MODE", raising=False) + monkeypatch.setenv("PYAUTO_SKIP_LATENTS", "1") + + analysis = MagicMock() + result = _make_updater()._compute_latent_samples( + samples=MagicMock(), + samples_save=MagicMock(), + analysis=analysis, + fitness=MagicMock(), + during_analysis=False, + ) + + assert result is None + analysis.compute_latent_samples.assert_not_called() + + +def test__compute_latent_samples__config_gate_still_works(monkeypatch): + """ + With neither env var set, the existing ``latent_after_fit`` / + ``latent_during_fit`` config gate must still short-circuit + when both are disabled. Regression for the new skip_latents() + check not bypassing the original logic. + """ + monkeypatch.delenv("PYAUTO_TEST_MODE", raising=False) + monkeypatch.delenv("PYAUTO_SKIP_LATENTS", raising=False) + + original_after = conf.instance["output"]["latent_after_fit"] + original_during = conf.instance["output"]["latent_during_fit"] + conf.instance["output"]["latent_after_fit"] = False + conf.instance["output"]["latent_during_fit"] = False + try: + analysis = MagicMock() + result = _make_updater()._compute_latent_samples( + samples=MagicMock(), + samples_save=MagicMock(), + analysis=analysis, + fitness=MagicMock(), + during_analysis=False, + ) + assert result is None + analysis.compute_latent_samples.assert_not_called() + finally: + conf.instance["output"]["latent_after_fit"] = original_after + conf.instance["output"]["latent_during_fit"] = original_during