@@ -53,11 +53,14 @@ class _ArgData:
53
53
"Whether or not the argument must be passed in"
54
54
55
55
default : Any
56
- "Value of the argument if the argument isn't passed in. This gets ignored if is_required"
56
+ "Value of the argument if the argument isn't passed in. This gets ignored if ` is_required` "
57
57
58
58
description : Optional [str ] = ""
59
59
"Human-readable description of the argument"
60
60
61
+ is_positional_only : bool = False
62
+ "Whether or not the argument must be provided positionally"
63
+
61
64
62
65
@dataclasses .dataclass (frozen = True )
63
66
class _TapData :
@@ -218,6 +221,7 @@ def _tap_data_from_class_or_function(
218
221
is_required = is_required ,
219
222
default = default ,
220
223
description = param_to_description .get (param .name ),
224
+ is_positional_only = param .kind == inspect .Parameter .POSITIONAL_ONLY ,
221
225
)
222
226
args_data .append (arg_data )
223
227
return _TapData (args_data , has_kwargs , known_only )
@@ -255,6 +259,10 @@ def _tap_data(class_or_function: _ClassOrFunction, param_to_description: Dict[st
255
259
256
260
257
261
def _tap_class (args_data : Sequence [_ArgData ]) -> Type [Tap ]:
262
+ """
263
+ Transfers argument data to a :class:`tap.Tap` class. Arguments will be added to the parser on initialization.
264
+ """
265
+
258
266
class ArgParser (Tap ):
259
267
# Overwriting configure would force a user to remember to call super().configure if they want to overwrite it
260
268
# Instead, overwrite _configure
@@ -298,14 +306,14 @@ def tapify(
298
306
299
307
:param class_or_function: The class or function to run with the provided arguments.
300
308
:param known_only: If true, ignores extra arguments and only parses known arguments.
301
- :param command_line_args: A list of command line style arguments to parse (e.g., ['--arg', 'value']).
302
- If None, arguments are parsed from the command line (default behavior).
303
- :param explicit_bool: Booleans can be specified on the command line as "--arg True" or "--arg False"
304
- rather than "--arg". Additionally, booleans can be specified by prefixes of True and False
305
- with any capitalization as well as 1 or 0.
306
- :param func_kwargs: Additional keyword arguments for the function. These act as default values when
307
- parsing the command line arguments and overwrite the function defaults but
308
- are overwritten by the parsed command line arguments.
309
+ :param command_line_args: A list of command line style arguments to parse (e.g., ['--arg', 'value']). If None,
310
+ arguments are parsed from the command line (default behavior).
311
+ :param explicit_bool: Booleans can be specified on the command line as "--arg True" or "--arg False" rather than
312
+ "--arg". Additionally, booleans can be specified by prefixes of True and False with any
313
+ capitalization as well as 1 or 0.
314
+ :param func_kwargs: Additional keyword arguments for the function. These act as default values when parsing the
315
+ command line arguments and overwrite the function defaults but are overwritten by the parsed
316
+ command line arguments.
309
317
"""
310
318
# We don't directly call to_tap_class b/c we need tap_data, not just tap_class
311
319
docstring = _docstring (class_or_function )
@@ -324,13 +332,21 @@ def tapify(
324
332
# Parse command line arguments
325
333
command_line_args : Tap = tap .parse_args (args = command_line_args , known_only = known_only )
326
334
327
- # Get command line arguments as a dictionary
335
+ # Prepare command line arguments for class_or_function, respecting positional-only args
336
+ class_or_function_args : list [Any ] = []
337
+ class_or_function_kwargs : Dict [str , Any ] = {}
328
338
command_line_args_dict = command_line_args .as_dict ()
339
+ for arg_data in tap_data .args_data :
340
+ arg_value = command_line_args_dict [arg_data .name ]
341
+ if arg_data .is_positional_only :
342
+ class_or_function_args .append (arg_value )
343
+ else :
344
+ class_or_function_kwargs [arg_data .name ] = arg_value
329
345
330
346
# Get **kwargs from extra command line arguments
331
347
if tap_data .has_kwargs :
332
348
kwargs = {tap .extra_args [i ].lstrip ("-" ): tap .extra_args [i + 1 ] for i in range (0 , len (tap .extra_args ), 2 )}
333
- command_line_args_dict .update (kwargs )
349
+ class_or_function_kwargs .update (kwargs )
334
350
335
351
# Initialize the class or run the function with the parsed arguments
336
- return class_or_function (** command_line_args_dict )
352
+ return class_or_function (* class_or_function_args , ** class_or_function_kwargs )
0 commit comments