cmdargparse 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cmdargparse/__init__.py +10 -0
- cmdargparse/argument.py +99 -0
- cmdargparse/command.py +200 -0
- cmdargparse/custom.py +120 -0
- cmdargparse/field.py +778 -0
- cmdargparse/namespace.py +37 -0
- cmdargparse/parser.py +40 -0
- cmdargparse/unset.py +79 -0
- cmdargparse-0.1.0.dist-info/METADATA +209 -0
- cmdargparse-0.1.0.dist-info/RECORD +13 -0
- cmdargparse-0.1.0.dist-info/WHEEL +5 -0
- cmdargparse-0.1.0.dist-info/licenses/LICENSE +21 -0
- cmdargparse-0.1.0.dist-info/top_level.txt +1 -0
cmdargparse/field.py
ADDED
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import dataclasses
|
|
3
|
+
from typing import (
|
|
4
|
+
TYPE_CHECKING,
|
|
5
|
+
Annotated,
|
|
6
|
+
Any,
|
|
7
|
+
Callable,
|
|
8
|
+
Collection,
|
|
9
|
+
Literal,
|
|
10
|
+
Mapping,
|
|
11
|
+
NamedTuple,
|
|
12
|
+
Never,
|
|
13
|
+
Sequence,
|
|
14
|
+
Tuple,
|
|
15
|
+
Type,
|
|
16
|
+
TypeAlias,
|
|
17
|
+
TypedDict,
|
|
18
|
+
TypeVar,
|
|
19
|
+
Union,
|
|
20
|
+
Unpack,
|
|
21
|
+
overload,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
from .unset import Unset, isunset, on_unset
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# NOTE Due to the complexity of the positional-only arguments of some overloads,
|
|
28
|
+
# we disable the overload concistency check reporting.
|
|
29
|
+
# pyright: reportInconsistentOverload=false
|
|
30
|
+
|
|
31
|
+
# NOTE Some overloads are wrongfully (in my opinion) recognized as overlapping.
|
|
32
|
+
# It most likely is caused by the unpacked typed dict used for additional
|
|
33
|
+
# keyword arguments.
|
|
34
|
+
# For now we just disable the overlapping overload reporting.
|
|
35
|
+
# pyright: reportOverlappingOverload=false
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ################################ TYPING ######################################
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
T = TypeVar("T")
|
|
42
|
+
|
|
43
|
+
TONCE: TypeAlias = Any
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
_FieldType: TypeAlias = Annotated[Any, dataclasses.Field]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
_DeclFormSpecifier: TypeAlias = Literal["--", "-"]
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
# ################################ TYPES #######################################
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class _FieldDecls(NamedTuple):
|
|
56
|
+
|
|
57
|
+
form: _DeclFormSpecifier | None
|
|
58
|
+
"""Specifies the default form of the ... declaration."""
|
|
59
|
+
|
|
60
|
+
decl: Annotated[
|
|
61
|
+
str | None,
|
|
62
|
+
Annotated[None, "[derived]"],
|
|
63
|
+
Annotated[None, "[augmented]"],
|
|
64
|
+
Annotated[str, "[explicit]"],
|
|
65
|
+
Annotated[str, "[keyword]"],
|
|
66
|
+
]
|
|
67
|
+
"""Specifies the primary ... declaration."""
|
|
68
|
+
|
|
69
|
+
altdecl: Annotated[
|
|
70
|
+
str | None,
|
|
71
|
+
Annotated[None, "[derived]"],
|
|
72
|
+
Annotated[str, "[augmented]"],
|
|
73
|
+
Annotated[str | None, "[explicit]"],
|
|
74
|
+
Annotated[str | None, "[keyword]"],
|
|
75
|
+
]
|
|
76
|
+
"""Specifies the alternative ... declaration."""
|
|
77
|
+
|
|
78
|
+
more_decls: Sequence[str] | None
|
|
79
|
+
"""Specifies additional ... declarations."""
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class _DeclsCompatibleArgs(TypedDict, total=False):
|
|
83
|
+
|
|
84
|
+
form: _DeclFormSpecifier
|
|
85
|
+
"""Specifies the default form of the ... declaration."""
|
|
86
|
+
decls: Tuple[str, str] | str
|
|
87
|
+
"""Explicitly specifies all ... declarations."""
|
|
88
|
+
more_decls: Sequence[str] | str
|
|
89
|
+
"""Specifies additional ... declarations."""
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# ################################ METACLASS ###################################
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class _cmdfield(type):
|
|
96
|
+
|
|
97
|
+
# Declarations Specification Formats
|
|
98
|
+
# - derived (default)
|
|
99
|
+
# The declaration name will be automatically derived from the field name.
|
|
100
|
+
# - augmented
|
|
101
|
+
# The specified declaration will replace the automatically derived
|
|
102
|
+
# declaration if both have the same form. Otherwise it will be added as
|
|
103
|
+
# an additional declaration.
|
|
104
|
+
# - explicit
|
|
105
|
+
# The specified declaration(s) (positional arguments) will replace the
|
|
106
|
+
# automatically derived declaration.
|
|
107
|
+
# - keyword
|
|
108
|
+
# The specified declaration(s) (`decls` keyword argument) will replace the
|
|
109
|
+
# automatically derived declaration.
|
|
110
|
+
|
|
111
|
+
# ################## ARGUMENT ##########################
|
|
112
|
+
|
|
113
|
+
class _ArgumentArgs(TypedDict, total=False):
|
|
114
|
+
|
|
115
|
+
type: Annotated[Any, Callable[[str], Annotated[Any, "FieldType"]]]
|
|
116
|
+
|
|
117
|
+
help: str
|
|
118
|
+
helpvar: str
|
|
119
|
+
|
|
120
|
+
@overload
|
|
121
|
+
# overload @ argument (required)
|
|
122
|
+
def argument(
|
|
123
|
+
cls,
|
|
124
|
+
/,
|
|
125
|
+
# *,
|
|
126
|
+
**args: Unpack[_ArgumentArgs],
|
|
127
|
+
) -> _FieldType: ...
|
|
128
|
+
|
|
129
|
+
@overload
|
|
130
|
+
# overload @ argument with default
|
|
131
|
+
def argument(
|
|
132
|
+
cls,
|
|
133
|
+
/,
|
|
134
|
+
*,
|
|
135
|
+
default: TONCE,
|
|
136
|
+
**args: Unpack[_ArgumentArgs],
|
|
137
|
+
) -> _FieldType: ...
|
|
138
|
+
|
|
139
|
+
@overload
|
|
140
|
+
# overload @ choice argument (required)
|
|
141
|
+
def argument(
|
|
142
|
+
cls,
|
|
143
|
+
/,
|
|
144
|
+
choices: Collection[T],
|
|
145
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
146
|
+
# *,
|
|
147
|
+
**args: Unpack[_ArgumentArgs],
|
|
148
|
+
) -> _FieldType: ...
|
|
149
|
+
|
|
150
|
+
@overload
|
|
151
|
+
# overload @ choice argument with default
|
|
152
|
+
def argument(
|
|
153
|
+
cls,
|
|
154
|
+
/,
|
|
155
|
+
choices: Collection[T],
|
|
156
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
157
|
+
*,
|
|
158
|
+
default: TONCE,
|
|
159
|
+
**args: Unpack[_ArgumentArgs],
|
|
160
|
+
) -> _FieldType: ...
|
|
161
|
+
|
|
162
|
+
def argument(
|
|
163
|
+
cls,
|
|
164
|
+
/,
|
|
165
|
+
choices: Collection[T] | None = None,
|
|
166
|
+
choicesmap: Mapping[T, T] | None = None,
|
|
167
|
+
*,
|
|
168
|
+
default: TONCE | Unset = ~Unset,
|
|
169
|
+
**args: Unpack[_ArgumentArgs],
|
|
170
|
+
) -> _FieldType:
|
|
171
|
+
"""
|
|
172
|
+
Defines a command-line argument. (positional)
|
|
173
|
+
|
|
174
|
+
:param choices:
|
|
175
|
+
The restricted set of values allowed for the argument.
|
|
176
|
+
:param choicesmap:
|
|
177
|
+
Additional values allowed for the argument that each map to the
|
|
178
|
+
specified value in the restricted set of values.
|
|
179
|
+
:param default:
|
|
180
|
+
The arguments default value if not specified.
|
|
181
|
+
(Providing a default value makes the argument optional.)
|
|
182
|
+
|
|
183
|
+
:param type:
|
|
184
|
+
Explicitly specifies the `type` to be used by `argparse`.
|
|
185
|
+
<br/> https://docs.python.org/3/library/argparse.html#type
|
|
186
|
+
|
|
187
|
+
:param help:
|
|
188
|
+
Brief description of the argument.
|
|
189
|
+
:param helpvar:
|
|
190
|
+
Reference name of the argument value in the help message.
|
|
191
|
+
|
|
192
|
+
"""
|
|
193
|
+
return _argparse(
|
|
194
|
+
None,
|
|
195
|
+
nargs=("?" if not isunset(default) else None),
|
|
196
|
+
choices=choices,
|
|
197
|
+
choicesmap=choicesmap,
|
|
198
|
+
default=on_unset(default, None),
|
|
199
|
+
type=args.get("type", None),
|
|
200
|
+
help=args.get("help", None),
|
|
201
|
+
metavar=args.get("helpvar", None),
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# ################## OPTION ############################
|
|
205
|
+
|
|
206
|
+
class _OptionArgs(TypedDict, total=False):
|
|
207
|
+
|
|
208
|
+
form: _DeclFormSpecifier
|
|
209
|
+
decls: Tuple[str, str] | str
|
|
210
|
+
more_decls: Sequence[str] | str
|
|
211
|
+
|
|
212
|
+
type: Annotated[Any, Callable[[str], Annotated[Any, "FieldType"]]]
|
|
213
|
+
|
|
214
|
+
required: bool
|
|
215
|
+
|
|
216
|
+
help: str
|
|
217
|
+
helpvar: str
|
|
218
|
+
|
|
219
|
+
@overload
|
|
220
|
+
# overload @ option [derived]
|
|
221
|
+
def option(
|
|
222
|
+
cls,
|
|
223
|
+
/,
|
|
224
|
+
# *,
|
|
225
|
+
**args: Unpack[_OptionArgs],
|
|
226
|
+
) -> _FieldType: ...
|
|
227
|
+
|
|
228
|
+
@overload
|
|
229
|
+
# overload @ option [augmented]
|
|
230
|
+
def option(
|
|
231
|
+
cls,
|
|
232
|
+
decl: str,
|
|
233
|
+
/,
|
|
234
|
+
# *,
|
|
235
|
+
**args: Unpack[_OptionArgs],
|
|
236
|
+
) -> _FieldType: ...
|
|
237
|
+
|
|
238
|
+
@overload
|
|
239
|
+
# overload @ option [explicit]
|
|
240
|
+
def option(
|
|
241
|
+
cls,
|
|
242
|
+
decl: str,
|
|
243
|
+
altdecl: str,
|
|
244
|
+
/,
|
|
245
|
+
# *,
|
|
246
|
+
**args: Unpack[_OptionArgs],
|
|
247
|
+
) -> _FieldType: ...
|
|
248
|
+
|
|
249
|
+
@overload
|
|
250
|
+
# overload @ option with default [derived]
|
|
251
|
+
def option(
|
|
252
|
+
cls,
|
|
253
|
+
/,
|
|
254
|
+
*,
|
|
255
|
+
default: TONCE,
|
|
256
|
+
**args: Unpack[_OptionArgs],
|
|
257
|
+
) -> _FieldType: ...
|
|
258
|
+
|
|
259
|
+
@overload
|
|
260
|
+
# overload @ option with default [augmented]
|
|
261
|
+
def option(
|
|
262
|
+
cls,
|
|
263
|
+
decl: str,
|
|
264
|
+
/,
|
|
265
|
+
*,
|
|
266
|
+
default: TONCE,
|
|
267
|
+
**args: Unpack[_OptionArgs],
|
|
268
|
+
) -> _FieldType: ...
|
|
269
|
+
|
|
270
|
+
@overload
|
|
271
|
+
# overload @ option with default [explicit]
|
|
272
|
+
def option(
|
|
273
|
+
cls,
|
|
274
|
+
decl: str,
|
|
275
|
+
altdecl: str,
|
|
276
|
+
/,
|
|
277
|
+
*,
|
|
278
|
+
default: TONCE,
|
|
279
|
+
**args: Unpack[_OptionArgs],
|
|
280
|
+
) -> _FieldType: ...
|
|
281
|
+
|
|
282
|
+
@overload
|
|
283
|
+
# overload @ choice option [derived]
|
|
284
|
+
def option(
|
|
285
|
+
cls,
|
|
286
|
+
/,
|
|
287
|
+
choices: Collection[T],
|
|
288
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
289
|
+
# *,
|
|
290
|
+
**args: Unpack[_OptionArgs],
|
|
291
|
+
) -> _FieldType: ...
|
|
292
|
+
|
|
293
|
+
@overload
|
|
294
|
+
# overload @ choice option [augmented]
|
|
295
|
+
def option(
|
|
296
|
+
cls,
|
|
297
|
+
decl: str,
|
|
298
|
+
/,
|
|
299
|
+
choices: Collection[T],
|
|
300
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
301
|
+
# *,
|
|
302
|
+
**args: Unpack[_OptionArgs],
|
|
303
|
+
) -> _FieldType: ...
|
|
304
|
+
|
|
305
|
+
@overload
|
|
306
|
+
# overload @ choice option [explicit]
|
|
307
|
+
def option(
|
|
308
|
+
cls,
|
|
309
|
+
decl: str,
|
|
310
|
+
altdecl: str,
|
|
311
|
+
/,
|
|
312
|
+
choices: Collection[T],
|
|
313
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
314
|
+
# *,
|
|
315
|
+
**args: Unpack[_OptionArgs],
|
|
316
|
+
) -> _FieldType: ...
|
|
317
|
+
|
|
318
|
+
@overload
|
|
319
|
+
# overload @ choice option with default [derived]
|
|
320
|
+
def option(
|
|
321
|
+
cls,
|
|
322
|
+
/,
|
|
323
|
+
choices: Collection[T],
|
|
324
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
325
|
+
*,
|
|
326
|
+
default: TONCE,
|
|
327
|
+
**args: Unpack[_OptionArgs],
|
|
328
|
+
) -> _FieldType: ...
|
|
329
|
+
|
|
330
|
+
@overload
|
|
331
|
+
# overload @ choice option with default [augmented]
|
|
332
|
+
def option(
|
|
333
|
+
cls,
|
|
334
|
+
decl: str,
|
|
335
|
+
/,
|
|
336
|
+
choices: Collection[T],
|
|
337
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
338
|
+
*,
|
|
339
|
+
default: TONCE,
|
|
340
|
+
**args: Unpack[_OptionArgs],
|
|
341
|
+
) -> _FieldType: ...
|
|
342
|
+
|
|
343
|
+
@overload
|
|
344
|
+
# overload @ choice option with default [explicit]
|
|
345
|
+
def option(
|
|
346
|
+
cls,
|
|
347
|
+
decl: str,
|
|
348
|
+
altdecl: str,
|
|
349
|
+
/,
|
|
350
|
+
choices: Collection[T],
|
|
351
|
+
choicesmap: Mapping[T, T] | None = ...,
|
|
352
|
+
*,
|
|
353
|
+
default: TONCE,
|
|
354
|
+
**args: Unpack[_OptionArgs],
|
|
355
|
+
) -> _FieldType: ...
|
|
356
|
+
|
|
357
|
+
def option(
|
|
358
|
+
cls,
|
|
359
|
+
decl: str | None = None,
|
|
360
|
+
altdecl: str | None = None,
|
|
361
|
+
/,
|
|
362
|
+
choices: Collection[T] | None = None,
|
|
363
|
+
choicesmap: Mapping[T, T] | None = None,
|
|
364
|
+
*,
|
|
365
|
+
default: TONCE | Unset = ~Unset,
|
|
366
|
+
**args: Unpack[_OptionArgs],
|
|
367
|
+
) -> _FieldType:
|
|
368
|
+
"""
|
|
369
|
+
Defines a command-line option. (non-positional, value-bound)
|
|
370
|
+
|
|
371
|
+
:param decl:
|
|
372
|
+
Specifies the primary option declaration.
|
|
373
|
+
:param altdecl:
|
|
374
|
+
Specifies the alternative option declaration.
|
|
375
|
+
|
|
376
|
+
:param choices:
|
|
377
|
+
The restricted set of values allowed for the option.
|
|
378
|
+
:param choicesmap:
|
|
379
|
+
Additional values allowed for the option that each map to the
|
|
380
|
+
specified value in the restricted set of values.
|
|
381
|
+
:param default:
|
|
382
|
+
The options default value if not specified.
|
|
383
|
+
|
|
384
|
+
:param form:
|
|
385
|
+
Specifies the default form of the option declaration.
|
|
386
|
+
:param decls:
|
|
387
|
+
Explicitly specifies all option declarations.
|
|
388
|
+
:param more_decls:
|
|
389
|
+
Specifies additional option declarations.
|
|
390
|
+
|
|
391
|
+
:param type:
|
|
392
|
+
Explicitly specifies the `type` to be used by `argparse`.
|
|
393
|
+
<br/> https://docs.python.org/3/library/argparse.html#type
|
|
394
|
+
|
|
395
|
+
:param required:
|
|
396
|
+
Marks the option as required.
|
|
397
|
+
|
|
398
|
+
:param help:
|
|
399
|
+
Brief description of the option.
|
|
400
|
+
:param helpvar:
|
|
401
|
+
Reference name of the option value in the help message.
|
|
402
|
+
|
|
403
|
+
"""
|
|
404
|
+
if decl is None:
|
|
405
|
+
decl, altdecl, choices = (
|
|
406
|
+
# 0 arguments
|
|
407
|
+
(None, None, None)
|
|
408
|
+
) # type: ignore
|
|
409
|
+
elif altdecl is None:
|
|
410
|
+
decl, altdecl, choices = (
|
|
411
|
+
# 1 argument
|
|
412
|
+
(decl, None, None)
|
|
413
|
+
if isinstance(decl, str)
|
|
414
|
+
else (None, None, decl)
|
|
415
|
+
) # type: ignore
|
|
416
|
+
elif choices is None:
|
|
417
|
+
decl, altdecl, choices = (
|
|
418
|
+
# 2 arguments
|
|
419
|
+
(decl, altdecl, None)
|
|
420
|
+
if isinstance(decl, str)
|
|
421
|
+
else (decl, None, altdecl)
|
|
422
|
+
) # type: ignore
|
|
423
|
+
else:
|
|
424
|
+
decl, altdecl, choices = (
|
|
425
|
+
# 3 arguments
|
|
426
|
+
(decl, altdecl, choices)
|
|
427
|
+
) # type: ignore
|
|
428
|
+
return _argparse(
|
|
429
|
+
_decls(decl, altdecl, args),
|
|
430
|
+
nargs=("?" if not isunset(default) else None),
|
|
431
|
+
choices=choices,
|
|
432
|
+
choicesmap=choicesmap,
|
|
433
|
+
default=on_unset(default, None),
|
|
434
|
+
required=args.get("required", False),
|
|
435
|
+
type=args.get("type", None),
|
|
436
|
+
help=args.get("help", None),
|
|
437
|
+
metavar=args.get("helpvar", None),
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
# ################## FLAG ##############################
|
|
441
|
+
|
|
442
|
+
class _FlagArgs(TypedDict, total=False):
|
|
443
|
+
|
|
444
|
+
form: _DeclFormSpecifier
|
|
445
|
+
decls: Tuple[str, str] | str
|
|
446
|
+
more_decls: Sequence[str] | str
|
|
447
|
+
|
|
448
|
+
type: Annotated[Any, Callable[[str], Annotated[Any, "FieldType"]]]
|
|
449
|
+
|
|
450
|
+
help: str
|
|
451
|
+
|
|
452
|
+
@overload
|
|
453
|
+
# overload @ flag [derived]
|
|
454
|
+
def flag(
|
|
455
|
+
cls,
|
|
456
|
+
/,
|
|
457
|
+
# *,
|
|
458
|
+
**args: Unpack[_FlagArgs],
|
|
459
|
+
) -> _FieldType: ...
|
|
460
|
+
|
|
461
|
+
@overload
|
|
462
|
+
# overload @ flag [augmented]
|
|
463
|
+
def flag(
|
|
464
|
+
cls,
|
|
465
|
+
decl: str,
|
|
466
|
+
/,
|
|
467
|
+
# *,
|
|
468
|
+
**args: Unpack[_FlagArgs],
|
|
469
|
+
) -> _FieldType: ...
|
|
470
|
+
|
|
471
|
+
@overload
|
|
472
|
+
# overload @ flag [explicit]
|
|
473
|
+
def flag(
|
|
474
|
+
cls,
|
|
475
|
+
decl: str,
|
|
476
|
+
altdecl: str,
|
|
477
|
+
/,
|
|
478
|
+
# *,
|
|
479
|
+
**args: Unpack[_FlagArgs],
|
|
480
|
+
) -> _FieldType: ...
|
|
481
|
+
|
|
482
|
+
@overload
|
|
483
|
+
# overload @ inverse flag [derived]
|
|
484
|
+
def flag(
|
|
485
|
+
cls,
|
|
486
|
+
/,
|
|
487
|
+
*,
|
|
488
|
+
invert: bool,
|
|
489
|
+
**args: Unpack[_FlagArgs],
|
|
490
|
+
) -> _FieldType: ...
|
|
491
|
+
|
|
492
|
+
@overload
|
|
493
|
+
# overload @ inverse flag [augmented]
|
|
494
|
+
def flag(
|
|
495
|
+
cls,
|
|
496
|
+
decl: str,
|
|
497
|
+
/,
|
|
498
|
+
*,
|
|
499
|
+
invert: bool,
|
|
500
|
+
**args: Unpack[_FlagArgs],
|
|
501
|
+
) -> _FieldType: ...
|
|
502
|
+
|
|
503
|
+
@overload
|
|
504
|
+
# overload @ inverse flag [explicit]
|
|
505
|
+
def flag(
|
|
506
|
+
cls,
|
|
507
|
+
decl: str,
|
|
508
|
+
altdecl: str,
|
|
509
|
+
/,
|
|
510
|
+
*,
|
|
511
|
+
invert: bool,
|
|
512
|
+
**args: Unpack[_FlagArgs],
|
|
513
|
+
) -> _FieldType: ...
|
|
514
|
+
|
|
515
|
+
@overload
|
|
516
|
+
# overload @ constant-valued flag [derived]
|
|
517
|
+
def flag(
|
|
518
|
+
cls,
|
|
519
|
+
/,
|
|
520
|
+
*,
|
|
521
|
+
const: TONCE,
|
|
522
|
+
**args: Unpack[_FlagArgs],
|
|
523
|
+
) -> _FieldType: ...
|
|
524
|
+
|
|
525
|
+
@overload
|
|
526
|
+
# overload @ constant-valued flag [augmented]
|
|
527
|
+
def flag(
|
|
528
|
+
cls,
|
|
529
|
+
decl: str,
|
|
530
|
+
/,
|
|
531
|
+
*,
|
|
532
|
+
const: TONCE,
|
|
533
|
+
**args: Unpack[_FlagArgs],
|
|
534
|
+
) -> _FieldType: ...
|
|
535
|
+
|
|
536
|
+
@overload
|
|
537
|
+
# overload @ constant-valued flag [explicit]
|
|
538
|
+
def flag(
|
|
539
|
+
cls,
|
|
540
|
+
decl: str,
|
|
541
|
+
altdecl: str,
|
|
542
|
+
/,
|
|
543
|
+
*,
|
|
544
|
+
const: TONCE,
|
|
545
|
+
**args: Unpack[_FlagArgs],
|
|
546
|
+
) -> _FieldType: ...
|
|
547
|
+
|
|
548
|
+
def flag(
|
|
549
|
+
cls,
|
|
550
|
+
decl: str | None = None,
|
|
551
|
+
altdecl: str | None = None,
|
|
552
|
+
/,
|
|
553
|
+
*,
|
|
554
|
+
invert: bool = False,
|
|
555
|
+
const: TONCE | Unset = ~Unset,
|
|
556
|
+
**args: Unpack[_FlagArgs],
|
|
557
|
+
) -> _FieldType:
|
|
558
|
+
"""
|
|
559
|
+
Defines a command-line flag. (non-positional, non-value)
|
|
560
|
+
|
|
561
|
+
:param decl:
|
|
562
|
+
Specifies the primary flag declaration.
|
|
563
|
+
:param altdecl:
|
|
564
|
+
Specifies the alternative flag declaration.
|
|
565
|
+
|
|
566
|
+
:param invert:
|
|
567
|
+
Sets the value `False` instead of `True` if the flag is specified.
|
|
568
|
+
:param const:
|
|
569
|
+
The value to set if the flag is specified.
|
|
570
|
+
|
|
571
|
+
:param form:
|
|
572
|
+
Specifies the default form of the flag declaration.
|
|
573
|
+
:param decls:
|
|
574
|
+
Explicitly specifies all flag declarations.
|
|
575
|
+
:param more_decls:
|
|
576
|
+
Specifies additional flag declarations.
|
|
577
|
+
|
|
578
|
+
:param type:
|
|
579
|
+
Explicitly specifies the `type` to be used by `argparse`.
|
|
580
|
+
<br/> https://docs.python.org/3/library/argparse.html#type
|
|
581
|
+
|
|
582
|
+
:param help:
|
|
583
|
+
Brief description of the flag.
|
|
584
|
+
|
|
585
|
+
"""
|
|
586
|
+
return _argparse(
|
|
587
|
+
_decls(decl, altdecl, args),
|
|
588
|
+
action=(
|
|
589
|
+
("store_false" if invert else "store_true")
|
|
590
|
+
if isunset(const)
|
|
591
|
+
else "store_const"
|
|
592
|
+
),
|
|
593
|
+
const=on_unset(const, None),
|
|
594
|
+
type=args.get("type", None),
|
|
595
|
+
help=args.get("help", None),
|
|
596
|
+
)
|
|
597
|
+
|
|
598
|
+
|
|
599
|
+
# ################################ CLASS #######################################
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
class cmdfield(metaclass=_cmdfield):
|
|
603
|
+
|
|
604
|
+
pass
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
# ################################ ARGPARSE ####################################
|
|
608
|
+
# https://docs.python.org/3/library/argparse.html#the-add-argument-method
|
|
609
|
+
|
|
610
|
+
if TYPE_CHECKING:
|
|
611
|
+
|
|
612
|
+
def _argparse(
|
|
613
|
+
decls: _FieldDecls | None,
|
|
614
|
+
/,
|
|
615
|
+
*,
|
|
616
|
+
# ####### argparse #############
|
|
617
|
+
action: Union[
|
|
618
|
+
Type[argparse.Action],
|
|
619
|
+
Literal[
|
|
620
|
+
"store",
|
|
621
|
+
"store_const",
|
|
622
|
+
"store_true",
|
|
623
|
+
"store_false",
|
|
624
|
+
"append",
|
|
625
|
+
"append_const",
|
|
626
|
+
"count",
|
|
627
|
+
"help",
|
|
628
|
+
"version",
|
|
629
|
+
"extend",
|
|
630
|
+
],
|
|
631
|
+
Annotated[Never, "<unspecified>"],
|
|
632
|
+
] = ...,
|
|
633
|
+
nargs: Union[
|
|
634
|
+
Annotated[int, "N"],
|
|
635
|
+
Literal["?", "*", "+"],
|
|
636
|
+
Annotated[None, "<unspecified>"],
|
|
637
|
+
] = ...,
|
|
638
|
+
const: Union[
|
|
639
|
+
Annotated[Any, TONCE],
|
|
640
|
+
Annotated[None, "<unspecified>"],
|
|
641
|
+
] = ...,
|
|
642
|
+
default: Union[
|
|
643
|
+
Annotated[Any, TONCE],
|
|
644
|
+
Annotated[None, "<unspecified>"],
|
|
645
|
+
] = ...,
|
|
646
|
+
type: Union[
|
|
647
|
+
Annotated[Any, Callable[[str], Annotated[Any, "FieldType"]]],
|
|
648
|
+
Annotated[None, "<unspecified>"],
|
|
649
|
+
] = ...,
|
|
650
|
+
choices: Union[
|
|
651
|
+
Collection[Annotated[Any, T]],
|
|
652
|
+
Annotated[None, "<unspecified>"],
|
|
653
|
+
] = ...,
|
|
654
|
+
required: Union[
|
|
655
|
+
bool,
|
|
656
|
+
Annotated[Never, "<unspecified>"],
|
|
657
|
+
] = ...,
|
|
658
|
+
help: Union[
|
|
659
|
+
str,
|
|
660
|
+
Annotated[None, "<unspecified>"],
|
|
661
|
+
] = ...,
|
|
662
|
+
metavar: Union[
|
|
663
|
+
Tuple[str, ...] | str,
|
|
664
|
+
Annotated[None, "<unspecified>"],
|
|
665
|
+
] = ...,
|
|
666
|
+
dest: Annotated[
|
|
667
|
+
Never, "Specifying 'dest' directly is not supported."
|
|
668
|
+
] = ...,
|
|
669
|
+
deprecated: Union[
|
|
670
|
+
bool,
|
|
671
|
+
Annotated[Never, "<unspecified>"],
|
|
672
|
+
] = ...,
|
|
673
|
+
version: Union[
|
|
674
|
+
str,
|
|
675
|
+
Annotated[Never, "<unspecified>"],
|
|
676
|
+
] = ...,
|
|
677
|
+
# ####### custom ###############
|
|
678
|
+
choicesmap: Union[
|
|
679
|
+
Mapping[Annotated[Any, T], Annotated[Any, T, "choices"]],
|
|
680
|
+
Annotated[None, "<unspecified>"],
|
|
681
|
+
] = ...,
|
|
682
|
+
) -> _FieldType: ...
|
|
683
|
+
|
|
684
|
+
else:
|
|
685
|
+
|
|
686
|
+
def _argparse(
|
|
687
|
+
decls: Any,
|
|
688
|
+
**args: Any,
|
|
689
|
+
) -> _FieldType:
|
|
690
|
+
return dataclasses.field(
|
|
691
|
+
init=False,
|
|
692
|
+
repr=False,
|
|
693
|
+
compare=False,
|
|
694
|
+
metadata={
|
|
695
|
+
"decls": decls,
|
|
696
|
+
"args": args,
|
|
697
|
+
},
|
|
698
|
+
)
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
def _decls(
|
|
702
|
+
decl: str | None,
|
|
703
|
+
altdecl: str | None,
|
|
704
|
+
/,
|
|
705
|
+
args: _DeclsCompatibleArgs,
|
|
706
|
+
) -> _FieldDecls:
|
|
707
|
+
(form, decls, more_decls) = (
|
|
708
|
+
args.get("form", None),
|
|
709
|
+
args.get("decls", None),
|
|
710
|
+
args.get("more_decls", None),
|
|
711
|
+
)
|
|
712
|
+
|
|
713
|
+
if isinstance(more_decls, str):
|
|
714
|
+
more_decls = (more_decls,)
|
|
715
|
+
|
|
716
|
+
if decls is not None:
|
|
717
|
+
# Declaration Specification Format: [keyword]
|
|
718
|
+
|
|
719
|
+
if decl is not None or altdecl is not None:
|
|
720
|
+
raise ValueError(
|
|
721
|
+
"Declarations cannot be specified using the positional "
|
|
722
|
+
"arguments if the 'decls' keyword argument is specified."
|
|
723
|
+
)
|
|
724
|
+
|
|
725
|
+
(_decl, _altdecl) = (
|
|
726
|
+
(decls, None)
|
|
727
|
+
if isinstance(decls, str)
|
|
728
|
+
else decls
|
|
729
|
+
# <format-break>
|
|
730
|
+
)
|
|
731
|
+
if (
|
|
732
|
+
(_decl and not _decl.startswith("-"))
|
|
733
|
+
or (_altdecl and not _altdecl.startswith("-"))
|
|
734
|
+
# <format-break>
|
|
735
|
+
):
|
|
736
|
+
raise ValueError(
|
|
737
|
+
"All declarations must start with either '--' or '-'."
|
|
738
|
+
)
|
|
739
|
+
|
|
740
|
+
return _FieldDecls(None, _decl, _altdecl, more_decls)
|
|
741
|
+
|
|
742
|
+
elif decl is None and altdecl is None:
|
|
743
|
+
# Declaration Specification Format: [derived]
|
|
744
|
+
|
|
745
|
+
return _FieldDecls(form, None, None, more_decls)
|
|
746
|
+
|
|
747
|
+
elif decl is not None and altdecl is not None:
|
|
748
|
+
# Declaration Specification Format: [explicit]
|
|
749
|
+
|
|
750
|
+
if not decl.startswith("-") or not altdecl.startswith("-"):
|
|
751
|
+
raise ValueError(
|
|
752
|
+
"All declarations must start with either '--' or '-'."
|
|
753
|
+
)
|
|
754
|
+
elif (
|
|
755
|
+
(decl.startswith("--") and altdecl.startswith("--"))
|
|
756
|
+
or (not decl.startswith("--") and not altdecl.startswith("--"))
|
|
757
|
+
# <format-break>
|
|
758
|
+
):
|
|
759
|
+
raise ValueError(
|
|
760
|
+
"Declarations specified using the positional arguments must "
|
|
761
|
+
"have different forms."
|
|
762
|
+
)
|
|
763
|
+
|
|
764
|
+
return _FieldDecls(form, decl, altdecl, more_decls)
|
|
765
|
+
|
|
766
|
+
else:
|
|
767
|
+
# Declaration Specification Format: [augmented]
|
|
768
|
+
assert decl is not None and altdecl is None, (
|
|
769
|
+
"The augmented declaration specification format should always have "
|
|
770
|
+
"'decl' specified and 'altdecl' unspecified."
|
|
771
|
+
)
|
|
772
|
+
|
|
773
|
+
if not decl.startswith("-"):
|
|
774
|
+
raise ValueError(
|
|
775
|
+
"All declarations must start with either '--' or '-'."
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
return _FieldDecls(form, None, decl, more_decls)
|