1919import functools
2020import logging
2121import threading
22- from typing import Any , Callable , Dict , TypeVar , overload
22+ from typing import Any , Callable , Dict , Sequence , TypeVar , overload
2323
2424from fiddle ._src import config as config_lib
2525from fiddle ._src import daglish
@@ -60,20 +60,28 @@ def _format_arg(arg: Any) -> str:
6060 return f'<ERROR FORMATTING { type (arg )} ARGUMENT>'
6161
6262
63- def _make_message (current_path : daglish .Path , buildable : config_lib .Buildable ,
64- arguments : Dict [str , Any ]) -> str :
63+ def _make_message (
64+ current_path : daglish .Path ,
65+ buildable : config_lib .Buildable ,
66+ args : Sequence [Any ],
67+ kwargs : Dict [str , Any ],
68+ ) -> str :
6569 """Returns Fiddle-related debugging information for an exception."""
6670 path_str = '<root>' + daglish .path_str (current_path )
6771 fn_or_cls = config_lib .get_callable (buildable )
6872 try :
6973 fn_or_cls_name = fn_or_cls .__qualname__
7074 except AttributeError :
7175 fn_or_cls_name = str (fn_or_cls ) # callable instances, etc.
76+ args_str = ', ' .join (f'{ _format_arg (value )} ' for value in args )
7277 kwargs_str = ', ' .join (
73- f'{ name } ={ _format_arg (value )} ' for name , value in arguments .items ())
78+ f'{ name } ={ _format_arg (value )} ' for name , value in kwargs .items ()
79+ )
7480
7581 tag_information = ''
76- bound_args = buildable .__signature_info__ .signature .bind_partial (** arguments )
82+ bound_args = buildable .__signature_info__ .signature .bind_partial (
83+ * args , ** kwargs
84+ )
7785 bound_args .apply_defaults ()
7886 unset_arg_tags = []
7987 for param in buildable .__signature_info__ .parameters :
@@ -90,7 +98,8 @@ def _make_message(current_path: daglish.Path, buildable: config_lib.Buildable,
9098 return (
9199 '\n \n Fiddle context: failed to construct or call '
92100 f'{ fn_or_cls_name } at { path_str } '
93- f'with arguments ({ kwargs_str } ){ tag_information } '
101+ f'with positional arguments: ({ args_str } ), '
102+ f'keyword arguments: ({ kwargs_str } ){ tag_information } .'
94103 )
95104
96105
@@ -100,10 +109,25 @@ def call_buildable(
100109 * ,
101110 current_path : daglish .Path ,
102111) -> Any :
103- make_message = functools .partial (_make_message , current_path , buildable ,
104- arguments )
112+ """Prepare positional arguments and actually build the buildable."""
113+ positional_only , keyword_or_positional , var_positional = (
114+ buildable .__signature_info__ .get_positional_names ()
115+ )
116+ positional_arguments = []
117+ for name in positional_only :
118+ if name in arguments :
119+ positional_arguments .append (arguments .pop (name ))
120+ if var_positional is not None :
121+ for name in keyword_or_positional :
122+ if name in arguments :
123+ positional_arguments .append (arguments .pop (name ))
124+ if var_positional in arguments :
125+ positional_arguments .extend (arguments .pop (var_positional ))
126+ make_message = functools .partial (
127+ _make_message , current_path , buildable , positional_arguments , arguments
128+ )
105129 with reraised_exception .try_with_lazy_message (make_message ):
106- return buildable .__build__ (** arguments )
130+ return buildable .__build__ (* positional_arguments , * *arguments )
107131
108132
109133# Define typing overload for `build(Partial[T])`
0 commit comments