@@ -23,28 +23,98 @@ By default:
2323
2424However, by using ` Arg ` , with syntax like
2525` name: Annotated[str, cappa.Arg(...)] ` , you can customize the behavior of the
26- field.
27-
28- - ` short=True ` (equivalent to ` short='-n' ` for this example) turns the option
29- from a positional argument into a flag.
30- - ` long ` works the same way as short (and can be used together), but for ` -- `
31- flags, like ` --name ` .
32- - ` count=True ` counts the number of flag instance. Frequently used for ` -v ` ,
33- ` -vv ` , ` -vvv ` verbosity handling.
34- - ` help='...' ` allows customizing the help text outside the docstring.
35- - ` parse=<callable> ` allows parsing of more complex input values the cannot be
36- handled through the type annotation system directly.
26+ field. For each field of customization, there is a default inferred value, based
27+ on the particulars of the dataclass and/or other configured fields.
28+
29+ Below we document when configuring a given field might ** imply** some other field by default
30+ (e.g. ` count=True ` ** implies** ` num_args=0 ` ), however in all cases, an explicitly
31+ provided value will take precedence over the default inference.
3732
3833``` {note}
3934See the [annotation docs](./annotation.md) for more details on how annotations
4035can be used and are interpreted to handle different kinds of CLI input.
4136```
4237
43- ``` {eval-rst}
44- .. autoapiclass:: cappa.Arg
45- :noindex:
38+ (arg-value-name)=
39+ ## ` Arg.value_name `
40+
41+ This field controls the name of the field in helptext/errors. By default it matches
42+ the dataclass' field name.
43+
44+ ``` python
45+ @dataclass
46+ class Command :
47+ foo: Annotated[int , cappa.Arg(value_name = " bar" )]
48+ happy: Annotated[int , cappa.Arg(value_name = " sad" , long = True )] = 1
4649```
4750
51+ Would yield help text like:
52+
53+ ```
54+ Options
55+ [--happy SAD]
56+
57+ Arguments
58+ BAR
59+ ```
60+
61+ (arg-short)=
62+ ## ` Arg.short `
63+
64+ By default, unannotated dataclass fields are assumed to be positional arguments.
65+
66+ An ` Arg.short ` argument is a non-positional argument which can be selected by a
67+ single ` - ` followed by the short name.
68+
69+ The value can be supplied in a few different ways:
70+
71+ * ` foo: Annotated[int, Arg(short=True)] ` : Rendered as ` -f ` . If there are more than one
72+ field starting with "f" with ` short=True ` , at least one will need to be disambiguated.
73+ * ` foo: Annotated[int, Arg(short='-b')] ` : Rendered as-is
74+ * ` foo: Annotated[int, Arg(short='b')] ` : Rendered as ` -b ` .
75+ * ` foo: Annotated[int, Arg(short=['-b', '-f'])] ` : Rendered as ** both/either** ` -b ` and ` -f ` .
76+ * ` foo: Annotated[int, Arg(short='-b/-f')] ` : Rendered as ** both/either** ` -b ` and ` -f ` .
77+
78+ (arg-long)=
79+ ## ` Arg.long `
80+
81+ By default, unannotated dataclass fields are assumed to be positional arguments.
82+
83+ An ` Arg.long ` argument is a non-positional argument which can be selected by a
84+ single ` -- ` followed by the long name.
85+
86+ ``` {note}
87+ `snake_case` field names will be converted to `dash-case` by default.
88+ ```
89+
90+ The value can be supplied in a few different ways:
91+
92+ * ` foo: Annotated[int, Arg(long=True)] ` : Rendered as ` --foo ` .
93+ field starting with "f" with ` long=True ` , at least one will need to be disambiguated.
94+ * ` foo: Annotated[int, Arg(long='--bar')] ` : Rendered as-is
95+ * ` foo: Annotated[int, Arg(long='bar')] ` : Rendered as ` --bar ` .
96+ * ` foo: Annotated[int, Arg(long=['--bar', '-foo'])] ` : Rendered as ** both/either** ` --bar ` and ` --foo ` .
97+ * ` foo: Annotated[int, Arg(long='--bar/--foo')] ` : Rendered as ** both/either** ` --bar ` and ` --foo ` .
98+
99+ (arg-count)=
100+ ## ` Arg.count `
101+
102+ Counts instances of the argument in question. This implies ` num_args=0 ` and ` action=ArgAction.count ` by default.
103+
104+ The canonical example of this is counting verbosity flags.
105+ ``` python
106+ @dataclass
107+ class Example :
108+ verbose: Annotated[int , cappa.Arg(short = " -v" , count = True ),
109+ ```
110+
111+ (arg- help )=
112+ # # `Arg.help`
113+ Controls the per- argument help text.
114+
115+ See [Help](./ help .md) for more details, but in short help text is inferred by
116+ default from a few different sources, including docstrings and " attribute docstrings" .
117+
48118(arg- action)=
49119# # `Arg.action`
50120
@@ -299,7 +369,7 @@ class Example:
299369 value: Annotated[int , cappa.Arg(default = cappa.ValueFrom(load_default, key = ' value' ))]
300370```
301371
302- This construct is able to be automatically supplied with [cappa.State](State), in the even shared
372+ This construct is able to be automatically supplied with [cappa.State](State), in the event shared
303373parse state is required to evaluate a field' s default.
304374
305375As noted above, a value produced by `ValueFrom` ** does not ** invoke the `Arg.parse` parser. This is
@@ -635,6 +705,37 @@ More injectable dependencies **could** be supported. In particular the `Arg` ins
635705it' s just not immediately obvious what that would be. File an issue if you have a usecase!
636706```
637707
708+ # # `Arg.choices`
709+
710+ This can be used to limit the set of valid inputs to one of a few literal values,
711+ for example, `Arg(choices = [' a' , ' b' , ' c' ]`.
712+
713+ Both `Literal` s (and literal unions) and `Enum` s automatically infer `choices` .
714+
715+ # # `Arg.completion`
716+
717+ This is an optional function which, if provided will be called during CLI (typically TAB )
718+ completion events in the shell. You can supply a function which accepts the partial
719+ input and returns an optional list of completions for that input .
720+
721+ ```{note}
722+ `Arg.choices` has a default completion implementation.
723+ ```
724+
725+ ```python
726+ def complete_file(raw: str ) -> list[cappa.Completion]:
727+ return [filename for filename in os.listdir() if filename.startswith(raw)]
728+
729+ @ dataclass
730+ class Foo:
731+ file : Annotated[str , cappa.Arg(completion = complete_file)
732+ ```
733+
734+ ```{note}
735+ Filename completion is actually natively supported by the shells, so this example is
736+ somewhat unnecessary to ** actually** implement yourself.
737+ ```
738+
638739# # `Arg.has_value`
639740
640741`Arg(has_value = True / False )` can be used to explicitly control whether the argument in question
@@ -798,3 +899,24 @@ Would yield:
798899Note, this is no different from use of `Arg.group` in any other context, except in that
799900the argument only exists at the declaration point, so any grouping configuration will
800901also propagate down into the way child commands render those arguments as well.
902+
903+ # # `Arg.hidden`
904+
905+ Controls whether an argument is displayed in help text.
906+
907+ # # `Arg.required`
908+
909+ Controls whether an argument is required.
910+
911+ # # `Arg.deprecated`
912+
913+ When truthy, will emit a deprecation message upon use of an argument. There is
914+ a default message generated, but supplying a string will yield ** that** as the
915+ deprecation message.
916+
917+ # # API
918+
919+ ```{eval - rst}
920+ .. autoapiclass:: cappa.Arg
921+ :noindex:
922+ ```
0 commit comments