From fcb54edd04c53e88d4b8125731d4dc3263e813f7 Mon Sep 17 00:00:00 2001 From: Jammy2211 Date: Fri, 15 May 2026 13:59:59 +0100 Subject: [PATCH] fix: dedupe number_of_cores in Drawer for from_dict round-trip Drawer.__init__ hardcoded `number_of_cores=1` while also forwarding `**kwargs` to super(). A round-tripped Drawer.search.json carries `number_of_cores` at the top level (the resolved value), so `from_dict(saved_dict)` crashed with: TypeError: AbstractMLE.__init__() got multiple values for keyword argument 'number_of_cores' Pop `number_of_cores` from kwargs before forwarding. Drawer is single-core only by design, so the saved value is always 1 and discarding it is safe. Surfaced by the autogalaxy_workspace `scripts/ellipse/database.py` example, which scrapes Drawer fits via the aggregator. Co-Authored-By: Claude Opus 4.7 (1M context) --- autofit/non_linear/search/mle/drawer/search.py | 5 +++++ .../non_linear/search/optimize/test_drawer.py | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/autofit/non_linear/search/mle/drawer/search.py b/autofit/non_linear/search/mle/drawer/search.py index 34b827285..6bda0cab1 100644 --- a/autofit/non_linear/search/mle/drawer/search.py +++ b/autofit/non_linear/search/mle/drawer/search.py @@ -66,6 +66,11 @@ def __init__( An SQLalchemy session instance so the results of the model-fit are written to an SQLite database. """ + # Drawer is single-core only; drop any saved number_of_cores so a + # round-tripped search.json (which records the resolved value) can be + # deserialized without colliding with the hardcoded kwarg below. + kwargs.pop("number_of_cores", None) + super().__init__( name=name, path_prefix=path_prefix, diff --git a/test_autofit/non_linear/search/optimize/test_drawer.py b/test_autofit/non_linear/search/optimize/test_drawer.py index ad6d2c352..3ee000877 100644 --- a/test_autofit/non_linear/search/optimize/test_drawer.py +++ b/test_autofit/non_linear/search/optimize/test_drawer.py @@ -1,6 +1,7 @@ import pytest import autofit as af +from autoconf.dictable import from_dict, to_dict pytestmark = pytest.mark.filterwarnings("ignore::FutureWarning") @@ -21,3 +22,17 @@ def test__explicit_params(): assert search.total_draws == 50 assert isinstance(search.initializer, af.InitializerBall) + + +def test__dict_round_trip_with_number_of_cores(): + # A round-tripped Drawer.search.json carries `number_of_cores` at the top + # level (the resolved value, always 1). Before the fix, this collided with + # the hardcoded super().__init__(number_of_cores=1, **kwargs) call and + # raised `TypeError: got multiple values for keyword argument`. + dictionary = to_dict(af.Drawer(total_draws=3)) + assert "number_of_cores" in dictionary["arguments"] + + restored = from_dict(dictionary) + assert isinstance(restored, af.Drawer) + assert restored.total_draws == 3 + assert restored.number_of_cores == 1