@@ -183,12 +183,17 @@ def extract_function_inputs_and_outputs(
183
183
input_types [p .name ] = type_hints .get (p .name , ty .Any )
184
184
if p .default is not inspect .Parameter .empty :
185
185
input_defaults [p .name ] = p .default
186
- if inputs :
186
+ if inputs is not None :
187
187
if not isinstance (inputs , dict ):
188
- raise ValueError (
189
- f"Input names ({ inputs } ) should not be provided when "
190
- "wrapping/decorating a function as "
191
- )
188
+ if non_named_args := [
189
+ i for i in inputs if not isinstance (i , Arg ) or i .name is None
190
+ ]:
191
+ raise ValueError (
192
+ "Only named Arg objects should be provided as inputs (i.e. not names or "
193
+ "other objects should not be provided when wrapping/decorating a "
194
+ f"function: found { non_named_args } when wrapping/decorating { function !r} "
195
+ )
196
+ inputs = {i .name : i for i in inputs }
192
197
if not has_varargs :
193
198
if unrecognised := set (inputs ) - set (input_types ):
194
199
raise ValueError (
@@ -218,41 +223,43 @@ def extract_function_inputs_and_outputs(
218
223
f"value { default } "
219
224
)
220
225
return_type = type_hints .get ("return" , ty .Any )
221
- if outputs and len (outputs ) > 1 :
222
- if return_type is not ty .Any :
223
- if ty .get_origin (return_type ) is not tuple :
224
- raise ValueError (
225
- f"Multiple outputs specified ({ outputs } ) but non-tuple "
226
- f"return value { return_type } "
227
- )
228
- return_types = ty .get_args (return_type )
229
- if len (return_types ) != len (outputs ):
230
- raise ValueError (
231
- f"Length of the outputs ({ outputs } ) does not match that "
232
- f"of the return types ({ return_types } )"
233
- )
234
- output_types = dict (zip (outputs , return_types ))
235
- else :
236
- output_types = {o : ty .Any for o in outputs }
237
- if isinstance (outputs , dict ):
238
- for output_name , output in outputs .items ():
239
- if isinstance (output , Out ) and output .type is ty .Any :
240
- output .type = output_types [output_name ]
226
+ if outputs :
227
+ if len (outputs ) > 1 :
228
+ if return_type is not ty .Any :
229
+ if ty .get_origin (return_type ) is not tuple :
230
+ raise ValueError (
231
+ f"Multiple outputs specified ({ outputs } ) but non-tuple "
232
+ f"return value { return_type } "
233
+ )
234
+ return_types = ty .get_args (return_type )
235
+ if len (return_types ) != len (outputs ):
236
+ raise ValueError (
237
+ f"Length of the outputs ({ outputs } ) does not match that "
238
+ f"of the return types ({ return_types } )"
239
+ )
240
+ output_types = dict (zip (outputs , return_types ))
241
+ else :
242
+ output_types = {o : ty .Any for o in outputs }
243
+ if isinstance (outputs , dict ):
244
+ for output_name , output in outputs .items ():
245
+ if isinstance (output , Out ) and output .type is ty .Any :
246
+ output .type = output_types [output_name ]
247
+ else :
248
+ outputs = output_types
241
249
else :
242
- outputs = output_types
243
-
244
- elif outputs :
245
- if isinstance (outputs , dict ):
246
- output_name , output = next (iter (outputs .items ()))
247
- elif isinstance (outputs , list ):
248
- output_name = outputs [0 ]
249
- output = ty .Any
250
- if isinstance (output , Out ):
251
- if output .type is ty .Any :
252
- output .type = return_type
253
- elif output is ty .Any :
254
- output = return_type
255
- outputs = {output_name : output }
250
+ if isinstance (outputs , dict ):
251
+ output_name , output = next (iter (outputs .items ()))
252
+ elif isinstance (outputs , list ):
253
+ output_name = outputs [0 ]
254
+ output = ty .Any
255
+ if isinstance (output , Out ):
256
+ if output .type is ty .Any :
257
+ output .type = return_type
258
+ elif output is ty .Any :
259
+ output = return_type
260
+ outputs = {output_name : output }
261
+ elif outputs == [] or return_type in (None , type (None )):
262
+ outputs = {}
256
263
else :
257
264
outputs = {"out" : return_type }
258
265
return inputs , outputs
0 commit comments