@@ -183,12 +183,17 @@ def extract_function_inputs_and_outputs(
183183 input_types [p .name ] = type_hints .get (p .name , ty .Any )
184184 if p .default is not inspect .Parameter .empty :
185185 input_defaults [p .name ] = p .default
186- if inputs :
186+ if inputs is not None :
187187 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 }
192197 if not has_varargs :
193198 if unrecognised := set (inputs ) - set (input_types ):
194199 raise ValueError (
@@ -218,41 +223,43 @@ def extract_function_inputs_and_outputs(
218223 f"value { default } "
219224 )
220225 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
241249 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 = {}
256263 else :
257264 outputs = {"out" : return_type }
258265 return inputs , outputs
0 commit comments