8
8
import warnings
9
9
from abc import abstractmethod
10
10
from collections .abc import Callable
11
- from types import MappingProxyType , ModuleType
11
+ from types import ModuleType
12
12
from typing import TYPE_CHECKING , Any , TypeAlias
13
13
14
14
from typing_extensions import deprecated
@@ -115,24 +115,48 @@ def initializeAndRun(
115
115
argument_types : list [type [Any ]],
116
116
argument_values : list [str ],
117
117
fixtures : dict [str , Any ] | None = None ,
118
+ ** kwargs : dict [str , Any ],
118
119
) -> Any :
119
120
fixtures = {} if fixtures is None else fixtures
120
- arguments = []
121
+ workflow_args = []
121
122
for index , arg_value in enumerate (argument_values ):
122
123
arg_type = argument_types [index ] if index < len (argument_types ) else str
123
124
124
125
if arg_value is not None :
125
- arguments .append (arg_type (arg_value ))
126
+ workflow_args .append (arg_type (arg_value ))
126
127
else :
127
- arguments .append (None )
128
- fixtures ["workflow_args" ] = arguments
128
+ workflow_args .append (None )
129
+ fixtures ["workflow_args" ] = workflow_args
130
+
131
+ fixture_args = []
132
+ all_func_args = inspect .signature (self .run ).parameters
133
+ is_using_wf_args_fixture = "workflow_args" in all_func_args
134
+
129
135
try :
130
- func_args = inspect .signature (self .run ).parameters
136
+ if not is_using_wf_args_fixture :
137
+ fixture_or_kw_arguments = list (all_func_args )[len (workflow_args ) :]
138
+ else :
139
+ fixture_or_kw_arguments = list (all_func_args )
140
+
141
+ func_args = {k : all_func_args [k ] for k in fixture_or_kw_arguments }
142
+
143
+ kwargs_defaults = {
144
+ k : v .default
145
+ for k , v in func_args .items ()
146
+ if k not in fixtures
147
+ and v .kind != v .VAR_POSITIONAL
148
+ and not str (v ).startswith ("*" )
149
+ and v .default != v .empty
150
+ }
151
+ use_kwargs = {
152
+ k : (kwargs or {}).get (k , default_value )
153
+ for k , default_value in ({** kwargs_defaults , ** kwargs }).items ()
154
+ }
131
155
# If the user has specified *args, we skip injecting fixtures, and just
132
156
# pass the user configured arguments
133
157
if not any (p .kind == p .VAR_POSITIONAL for p in func_args .values ()):
134
158
try :
135
- arguments = self .insert_fixtures (func_args , fixtures )
159
+ fixture_args = self .insert_fixtures (func_args , fixtures , use_kwargs )
136
160
except ValueError as e :
137
161
# This is here for backwards compatibility, the user does not have *argv
138
162
# but positional arguments. Can not be mixed with using fixtures.
@@ -143,7 +167,20 @@ def initializeAndRun(
143
167
self ._ert = fixtures .get ("ert_config" )
144
168
self ._ensemble = fixtures .get ("ensemble" )
145
169
self ._storage = fixtures .get ("storage" )
146
- return self .run (* arguments )
170
+
171
+ positional_args = (
172
+ fixture_args
173
+ if is_using_wf_args_fixture
174
+ else [* workflow_args , * fixture_args ]
175
+ )
176
+ if not positional_args and not use_kwargs :
177
+ return self .run ()
178
+ elif positional_args and not use_kwargs :
179
+ return self .run (* positional_args )
180
+ elif not positional_args and use_kwargs :
181
+ return self .run (** use_kwargs )
182
+ else :
183
+ return self .run (* positional_args , ** use_kwargs )
147
184
except AttributeError as e :
148
185
error_msg = str (e )
149
186
if not hasattr (self , "run" ):
@@ -169,20 +206,22 @@ def initializeAndRun(
169
206
170
207
def insert_fixtures (
171
208
self ,
172
- func_args : MappingProxyType [str , inspect .Parameter ],
209
+ func_args : dict [str , inspect .Parameter ],
173
210
fixtures : dict [str , Fixtures ],
211
+ kwargs : dict [str , Any ],
174
212
) -> list [Any ]:
175
213
arguments = []
176
214
errors = []
177
215
for val in func_args :
178
216
if val in fixtures :
179
217
arguments .append (fixtures [val ])
180
- else :
218
+ elif val not in kwargs :
181
219
errors .append (val )
182
220
if errors :
221
+ kwargs_str = "," .join (f"{ k } ='{ v } '" for k , v in kwargs .items ())
183
222
raise ValueError (
184
223
f"Plugin: { self .__class__ .__name__ } misconfigured, arguments: { errors } "
185
- f"not found in fixtures: { list (fixtures )} "
224
+ f"not found in fixtures: { list (fixtures )} or kwargs { kwargs_str } "
186
225
)
187
226
return arguments
188
227
0 commit comments