From 60110c257b4871c84d983c6b34bd754623b619b9 Mon Sep 17 00:00:00 2001 From: Matthew Newville Date: Sun, 15 Dec 2024 15:42:06 -0600 Subject: [PATCH 1/3] add basic test for model function with barestar to indicate keyword-only arguments --- tests/test_model.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_model.py b/tests/test_model.py index 7f4bbdfb..368496e1 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1697,3 +1697,16 @@ def test_model_refitting(): assert result.init_values['peak_amplitude'] < 21 assert result.init_values['peak_sigma'] > 2 assert result.init_values['peak_sigma'] < 4 + + +def test_model_barestar(): + """Github #976 (and discussion #975)""" + def foo(x, *, a=1, b=1, kind='linear'): + if kind == 'linear': + return a + b * x + elif kind == 'exponential': + return a * np.exp(b * x) + + modl = lmfit.Model(foo) + assert modl.independent_vars == ['x', 'kind'] + assert modl._param_names == ['a', 'b'] From 085fe1c68f2280ff6103588bd6da8dfff564a3f8 Mon Sep 17 00:00:00 2001 From: Matthew Newville Date: Sun, 15 Dec 2024 15:43:34 -0600 Subject: [PATCH 2/3] add support for "bare star" and keyword-only arguments in model function signatures --- lmfit/model.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lmfit/model.py b/lmfit/model.py index 34a78c78..289da872 100644 --- a/lmfit/model.py +++ b/lmfit/model.py @@ -529,16 +529,20 @@ def _parse_params(self): for fnam, fpar in sig.parameters.items(): if fpar.kind == fpar.VAR_KEYWORD: keywords_ = fnam - elif fpar.kind in (fpar.POSITIONAL_ONLY, fpar.POSITIONAL_OR_KEYWORD): + elif fpar.kind in (fpar.KEYWORD_ONLY, + fpar.POSITIONAL_OR_KEYWORD): default_vals[fnam] = fpar.default if (isinstance(fpar.default, (float, int, complex)) and not isinstance(fpar.default, bool)): kw_args[fnam] = fpar.default + pos_args.append(fnam) elif fpar.default == fpar.empty: pos_args.append(fnam) else: kw_args[fnam] = fpar.default indep_vars.append(fnam) + elif fpar.kind == fpar.POSITIONAL_ONLY: + raise ValueError("positional only arguments with '/' are not supported") elif fpar.kind == fpar.VAR_POSITIONAL: raise ValueError(f"varargs '*{fnam}' is not supported") # inspection done From 200b069869a8c9178b2d57f04d6317127e0eb972 Mon Sep 17 00:00:00 2001 From: Matthew Newville Date: Sun, 15 Dec 2024 16:15:33 -0600 Subject: [PATCH 3/3] add test for bareslash, asserting ValueError --- tests/test_model.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_model.py b/tests/test_model.py index 368496e1..a77b94a6 100644 --- a/tests/test_model.py +++ b/tests/test_model.py @@ -1710,3 +1710,19 @@ def foo(x, *, a=1, b=1, kind='linear'): modl = lmfit.Model(foo) assert modl.independent_vars == ['x', 'kind'] assert modl._param_names == ['a', 'b'] + + +def test_model_bareslash(): + """Github #976 (and discussion #975)""" + def foo(x, /, a=1, b=1, kind='linear'): + if kind == 'linear': + return a + b * x + elif kind == 'exponential': + return a * np.exp(b * x) + try: + lmfit.Model(foo) + that_failed = False + except ValueError: + that_failed = True + + assert that_failed