mininterface 1.1.4__tar.gz → 1.2.1__tar.gz
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.
- {mininterface-1.1.4 → mininterface-1.2.1}/PKG-INFO +2 -2
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/__main__.py +0 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/argparse_support.py +19 -6
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/auxiliary.py +11 -6
- mininterface-1.2.1/mininterface/_lib/cli_flags.py +234 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/cli_parser.py +187 -47
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/cli_utils.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/config_file.py +23 -21
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/dataclass_creation.py +137 -57
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/form_dict.py +13 -7
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/future_compatibility.py +2 -2
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/run.py +34 -27
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/start.py +4 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/tyro_patches.py +79 -81
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_mininterface/__init__.py +2 -5
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_mininterface/adaptor.py +4 -5
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_mininterface/mixin.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_text_interface/__init__.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_text_interface/timeout.py +16 -21
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/widgets.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/select_input.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/timeout.py +2 -3
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_web_interface/child_adaptor.py +1 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/cli.py +2 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/exceptions.py +16 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/datetime_tag.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/flag.py +4 -2
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/tag.py +23 -7
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/tag_factory.py +5 -2
- {mininterface-1.1.4 → mininterface-1.2.1}/pyproject.toml +2 -2
- mininterface-1.1.4/mininterface/_lib/cli_flags.py +0 -107
- {mininterface-1.1.4 → mininterface-1.2.1}/LICENSE +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/README.md +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/redirectable.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/shortcuts.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_lib/showcase.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_text_interface/adaptor.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_text_interface/facet.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/adaptor.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/button_contents.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/facet.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/file_picker_input.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/form_contents.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/secret_input.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/style.tcss +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/textual_app.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_textual_interface/timeout.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/adaptor.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/date_entry.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/external_fix.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/facet.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/redirect_text_tkinter.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/secret_entry.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_tk_interface/utils.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_web_interface/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_web_interface/app.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/_web_interface/parent_adaptor.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/experimental.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/facet/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/interfaces.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/settings.py +1 -1
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/__init__.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/alias.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/callback_tag.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/internal.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/path_tag.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/secret_tag.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/select_tag.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/tag/type_stubs.py +0 -0
- {mininterface-1.1.4 → mininterface-1.2.1}/mininterface/validators.py +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mininterface
|
|
3
|
-
Version: 1.1
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 1.2.1
|
|
4
|
+
Summary: CLI & dialog toolkit – a minimal interface to Python application (GUI, TUI, CLI + config files, web)
|
|
5
5
|
License: LGPL-3.0-or-later
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Author: Edvard Rejthar
|
|
@@ -1,9 +1,19 @@
|
|
|
1
1
|
import re
|
|
2
2
|
import sys
|
|
3
|
-
from argparse import (
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
from argparse import (
|
|
4
|
+
SUPPRESS,
|
|
5
|
+
Action,
|
|
6
|
+
ArgumentParser,
|
|
7
|
+
_AppendAction,
|
|
8
|
+
_AppendConstAction,
|
|
9
|
+
_CountAction,
|
|
10
|
+
_HelpAction,
|
|
11
|
+
_StoreConstAction,
|
|
12
|
+
_StoreFalseAction,
|
|
13
|
+
_StoreTrueAction,
|
|
14
|
+
_SubParsersAction,
|
|
15
|
+
_VersionAction,
|
|
16
|
+
)
|
|
7
17
|
from collections import defaultdict
|
|
8
18
|
from dataclasses import MISSING, Field, dataclass, field, make_dataclass
|
|
9
19
|
from functools import cached_property
|
|
@@ -65,7 +75,9 @@ class ArgparseField:
|
|
|
65
75
|
return self.action.dest in self.properties
|
|
66
76
|
|
|
67
77
|
|
|
68
|
-
def parser_to_dataclass(
|
|
78
|
+
def parser_to_dataclass(
|
|
79
|
+
parser: ArgumentParser, name: str = "Args"
|
|
80
|
+
) -> tuple[DataClass | list[DataClass], Optional[str]]:
|
|
69
81
|
"""
|
|
70
82
|
Note: Ex. parser.add_argument("--time", type=time) -> does work at all in argparse, here it works.
|
|
71
83
|
|
|
@@ -197,8 +209,9 @@ def _make_dataclass_from_actions(
|
|
|
197
209
|
if action.choices:
|
|
198
210
|
# With the drop of Python 3.10, use mere:
|
|
199
211
|
# arg_type = Literal[*action.choices]
|
|
200
|
-
if sys.version_info >= (3,11):
|
|
212
|
+
if sys.version_info >= (3, 11):
|
|
201
213
|
from .future_compatibility import literal
|
|
214
|
+
|
|
202
215
|
arg_type = literal(action.choices)
|
|
203
216
|
else:
|
|
204
217
|
# we do not prefer this option as tyro does not understand it
|
|
@@ -5,8 +5,7 @@ from argparse import ArgumentParser
|
|
|
5
5
|
from dataclasses import fields, is_dataclass
|
|
6
6
|
from functools import lru_cache
|
|
7
7
|
from types import UnionType
|
|
8
|
-
from typing import
|
|
9
|
-
get_args, get_origin, get_type_hints)
|
|
8
|
+
from typing import Any, Callable, Iterable, Optional, TypeVar, Union, Literal, get_args, get_origin, get_type_hints
|
|
10
9
|
|
|
11
10
|
from annotated_types import Ge, Gt, Le, Len, Lt, MultipleOf
|
|
12
11
|
|
|
@@ -75,7 +74,9 @@ def get_descriptions(parser: ArgumentParser) -> dict:
|
|
|
75
74
|
"""Load descriptions from the parser. Strip argparse info about the default value as it will be editable in the form."""
|
|
76
75
|
# clean-up tyro stuff that may have a meaning in the CLI, but not in the UI
|
|
77
76
|
return {
|
|
78
|
-
re.sub(r"\s\(positional\)$", "", action.dest).replace("-", "_"): re.sub(
|
|
77
|
+
re.sub(r"\s\(positional\)$", "", action.dest).replace("-", "_"): re.sub(
|
|
78
|
+
r"\((default|fixed to|required).*\)", "", action.help or ""
|
|
79
|
+
)
|
|
79
80
|
for action in parser._actions
|
|
80
81
|
}
|
|
81
82
|
|
|
@@ -201,7 +202,7 @@ def matches_annotation(value, annotation) -> bool:
|
|
|
201
202
|
if origin is list:
|
|
202
203
|
return all(matches_annotation(item, subtypes[0]) for item in value)
|
|
203
204
|
elif origin is tuple:
|
|
204
|
-
if len(subtypes) == 2 and subtypes[1] is Ellipsis:
|
|
205
|
+
if len(subtypes) == 2 and subtypes[1] is Ellipsis: # ex. tuple[int, ...]
|
|
205
206
|
return all(matches_annotation(v, subtypes[0]) for v in value)
|
|
206
207
|
if len(subtypes) != len(value):
|
|
207
208
|
return False
|
|
@@ -286,8 +287,9 @@ def merge_dicts(d1: dict, d2: dict):
|
|
|
286
287
|
d1[key] = value
|
|
287
288
|
return d1
|
|
288
289
|
|
|
290
|
+
|
|
289
291
|
def dict_diff(a: dict, b: dict) -> dict:
|
|
290
|
-
"""
|
|
292
|
+
"""Returns the B values where they differ."""
|
|
291
293
|
result = {}
|
|
292
294
|
for k in b:
|
|
293
295
|
if isinstance(a.get(k), dict) and isinstance(b.get(k), dict):
|
|
@@ -298,6 +300,7 @@ def dict_diff(a: dict, b: dict) -> dict:
|
|
|
298
300
|
result[k] = b[k]
|
|
299
301
|
return result
|
|
300
302
|
|
|
303
|
+
|
|
301
304
|
def naturalsize(value: float | str, *args) -> str:
|
|
302
305
|
"""For a bare interface, humanize might not be installed."""
|
|
303
306
|
if naturalsize_:
|
|
@@ -346,6 +349,7 @@ def allows_none(annotation) -> bool:
|
|
|
346
349
|
return any(arg is type(None) for arg in args)
|
|
347
350
|
return False
|
|
348
351
|
|
|
352
|
+
|
|
349
353
|
def strip_none(annotation):
|
|
350
354
|
"""Return the same annotation but without NoneType inside a Union/Optional."""
|
|
351
355
|
origin = get_origin(annotation)
|
|
@@ -358,7 +362,8 @@ def strip_none(annotation):
|
|
|
358
362
|
|
|
359
363
|
return annotation
|
|
360
364
|
|
|
361
|
-
|
|
365
|
+
|
|
366
|
+
@lru_cache(maxsize=1024 * 10)
|
|
362
367
|
def _get_origin(tp: Any):
|
|
363
368
|
"""
|
|
364
369
|
Cached version of typing.get_origin.
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
from argparse import ArgumentParser
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Optional, Sequence
|
|
5
|
+
|
|
6
|
+
from tyro.conf import FlagConversionOff
|
|
7
|
+
|
|
8
|
+
from .form_dict import EnvClass
|
|
9
|
+
|
|
10
|
+
from typing import List, Any, Optional
|
|
11
|
+
|
|
12
|
+
from tyro._fields import FieldDefinition
|
|
13
|
+
from tyro.conf._confstruct import _ArgConfig
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class CliFlags:
|
|
17
|
+
|
|
18
|
+
_add_verbose: bool = False
|
|
19
|
+
version: str = ""
|
|
20
|
+
_add_quiet: bool = False
|
|
21
|
+
|
|
22
|
+
default_verbosity: int = logging.WARNING
|
|
23
|
+
_verbosity_sequence: Optional[Sequence[int]] = None
|
|
24
|
+
|
|
25
|
+
config: bool = False
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
add_verbose: bool | int | Sequence[int] = False,
|
|
30
|
+
add_version: Optional[str] = None,
|
|
31
|
+
add_version_package: Optional[str] = None,
|
|
32
|
+
add_quiet: bool = False,
|
|
33
|
+
add_config: bool = False,
|
|
34
|
+
):
|
|
35
|
+
self._enabled = {"verbose": True, "version": True, "quiet": True, "config": True}
|
|
36
|
+
# verbosity
|
|
37
|
+
match add_verbose:
|
|
38
|
+
case bool():
|
|
39
|
+
self._add_verbose = add_verbose
|
|
40
|
+
case int():
|
|
41
|
+
self._add_verbose = True
|
|
42
|
+
self.default_verbosity = add_verbose
|
|
43
|
+
self._verbosity_sequence = list(range(add_verbose - 10, -1, -10))
|
|
44
|
+
case list() | tuple():
|
|
45
|
+
self._add_verbose = True
|
|
46
|
+
self.default_verbosity = add_verbose[0]
|
|
47
|
+
self._verbosity_sequence = add_verbose[1:]
|
|
48
|
+
self._add_quiet = add_quiet
|
|
49
|
+
|
|
50
|
+
# version
|
|
51
|
+
if add_version:
|
|
52
|
+
self.version = add_version
|
|
53
|
+
elif add_version_package:
|
|
54
|
+
try:
|
|
55
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
56
|
+
except ImportError:
|
|
57
|
+
self.version = f"cannot determine version"
|
|
58
|
+
try:
|
|
59
|
+
self.version = version(add_version_package)
|
|
60
|
+
except PackageNotFoundError:
|
|
61
|
+
self.version = f"package {add_version_package} not found"
|
|
62
|
+
|
|
63
|
+
# config
|
|
64
|
+
self.config = add_config
|
|
65
|
+
|
|
66
|
+
self.orig_stream = (
|
|
67
|
+
sys.stderr
|
|
68
|
+
) # NOTE might be removed now. Might be used if we redirect_stderr while setting basicConfig.
|
|
69
|
+
|
|
70
|
+
self.field_list: list[FieldDefinition] = []
|
|
71
|
+
""" List of FieldDefinitions corresponding to the arguments added via this helper"""
|
|
72
|
+
|
|
73
|
+
self.arguments_prepared: list[dict[str, Any]] = []
|
|
74
|
+
self.setup_done = False
|
|
75
|
+
""" Setup might be called multiple times – ex. parsing fails and we call tyro.cli in recursion. """
|
|
76
|
+
|
|
77
|
+
def should_add(self, env_classes: list[EnvClass]) -> bool:
|
|
78
|
+
# Flags are added only if neither the env_class nor any of the subcommands have the same-name flag already
|
|
79
|
+
self._enabled["verbose"] = self._add_verbose and self._attr_not_present("verbose", env_classes)
|
|
80
|
+
self._enabled["quiet"] = self._add_quiet and self._attr_not_present("quiet", env_classes)
|
|
81
|
+
self._enabled["version"] = self.version and self._attr_not_present("version", env_classes)
|
|
82
|
+
self._enabled["config"] = self.config and self._attr_not_present("config", env_classes)
|
|
83
|
+
|
|
84
|
+
return self.add_verbose or self.add_version or self.add_quiet or self.add_config
|
|
85
|
+
|
|
86
|
+
def _attr_not_present(self, flag, env_classes):
|
|
87
|
+
return all(flag not in cl.__annotations__ for cl in env_classes)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def add_verbose(self):
|
|
91
|
+
return self._add_verbose and self._enabled["verbose"]
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def add_version(self):
|
|
95
|
+
return self.version and self._enabled["version"]
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def add_quiet(self):
|
|
99
|
+
return self._add_quiet and self._enabled["quiet"]
|
|
100
|
+
|
|
101
|
+
@property
|
|
102
|
+
def add_config(self):
|
|
103
|
+
return self.config and self._enabled["config"]
|
|
104
|
+
|
|
105
|
+
def get_log_level(self, count):
|
|
106
|
+
"""
|
|
107
|
+
Ex.
|
|
108
|
+
* add_verbose = True ( default level = WARNING )
|
|
109
|
+
* -v -> logging.INFO
|
|
110
|
+
* -vv -> logging.DEBUG
|
|
111
|
+
* -vvv -> logging.NOTSET
|
|
112
|
+
* add_verbose = default level INFO
|
|
113
|
+
* -v -> logging.DEBUG
|
|
114
|
+
* -vv -> logging.NOTSET
|
|
115
|
+
* add_verbose = (40, 35, 30, 25)
|
|
116
|
+
* -v -> 35
|
|
117
|
+
* -vv -> logging.INFO
|
|
118
|
+
* -vvv -> 25
|
|
119
|
+
* -vvv -> logging.NOTSET
|
|
120
|
+
|
|
121
|
+
Args:
|
|
122
|
+
count: number of times `--verbose` flag is used. Negative count means the `--quiet` flag is used.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
int: log level
|
|
126
|
+
"""
|
|
127
|
+
if count == -1: # quiet flag
|
|
128
|
+
return logging.ERROR
|
|
129
|
+
if not count:
|
|
130
|
+
return self.default_verbosity
|
|
131
|
+
if not self._verbosity_sequence:
|
|
132
|
+
seq = logging.INFO, logging.DEBUG
|
|
133
|
+
else:
|
|
134
|
+
seq = self._verbosity_sequence
|
|
135
|
+
log_level = {i + 1: level for i, level in enumerate(seq)}.get(count, logging.NOTSET)
|
|
136
|
+
return log_level
|
|
137
|
+
|
|
138
|
+
def add_typed_argument(
|
|
139
|
+
self,
|
|
140
|
+
prefix: str,
|
|
141
|
+
*aliases: str,
|
|
142
|
+
action: Optional[str] = None,
|
|
143
|
+
default: Any = False,
|
|
144
|
+
helptext: Optional[str] = None,
|
|
145
|
+
metavar: Optional[str] = None,
|
|
146
|
+
version: Optional[str] = None,
|
|
147
|
+
) -> FieldDefinition:
|
|
148
|
+
# Prepare FieldDefinition
|
|
149
|
+
name = aliases[0]
|
|
150
|
+
aliases_ = tuple((prefix * (1 if len(n) == 1 else 2) + n) for n in aliases) if aliases else None
|
|
151
|
+
typ_ = bool if action in ("store_true", "store_false") else int if action == "count" else str
|
|
152
|
+
|
|
153
|
+
field = FieldDefinition(
|
|
154
|
+
intern_name=name,
|
|
155
|
+
extern_name=name,
|
|
156
|
+
type=typ_,
|
|
157
|
+
type_stripped=typ_,
|
|
158
|
+
default=default,
|
|
159
|
+
helptext=helptext,
|
|
160
|
+
markers={FlagConversionOff},
|
|
161
|
+
custom_constructor=False,
|
|
162
|
+
argconf=_ArgConfig(
|
|
163
|
+
name=aliases_[0],
|
|
164
|
+
metavar="",
|
|
165
|
+
help=helptext,
|
|
166
|
+
help_behavior_hint="",
|
|
167
|
+
aliases=aliases_[1:] or None,
|
|
168
|
+
prefix_name=False,
|
|
169
|
+
constructor_factory=None,
|
|
170
|
+
default=default,
|
|
171
|
+
),
|
|
172
|
+
mutex_group=None,
|
|
173
|
+
call_argname=name,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
self.field_list.append(field)
|
|
177
|
+
|
|
178
|
+
# prepare argparse
|
|
179
|
+
self.arguments_prepared.append(
|
|
180
|
+
{
|
|
181
|
+
"field": field,
|
|
182
|
+
"names": aliases_,
|
|
183
|
+
"kwargs": {
|
|
184
|
+
"action": action,
|
|
185
|
+
"default": default,
|
|
186
|
+
"help": helptext,
|
|
187
|
+
"metavar": metavar,
|
|
188
|
+
"version": version,
|
|
189
|
+
},
|
|
190
|
+
}
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
return field
|
|
194
|
+
|
|
195
|
+
def setup(self, parser: ArgumentParser):
|
|
196
|
+
if self.setup_done:
|
|
197
|
+
# tyro.cli might be called multiple times if some missing required fields
|
|
198
|
+
return
|
|
199
|
+
self.setup_done = True
|
|
200
|
+
prefix = "-" if "-" in parser.prefix_chars else parser.prefix_chars[0]
|
|
201
|
+
if self.add_verbose:
|
|
202
|
+
self.add_typed_argument(
|
|
203
|
+
prefix,
|
|
204
|
+
"verbose",
|
|
205
|
+
"v",
|
|
206
|
+
action="count",
|
|
207
|
+
default=0,
|
|
208
|
+
helptext="verbosity level, can be used multiple times to increase",
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
if self.add_version:
|
|
212
|
+
self.add_typed_argument(
|
|
213
|
+
prefix,
|
|
214
|
+
"version",
|
|
215
|
+
action="version",
|
|
216
|
+
version=self.version,
|
|
217
|
+
default="",
|
|
218
|
+
helptext=f"show program's version number ({self.version}) and exit",
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
if self.add_quiet:
|
|
222
|
+
self.add_typed_argument(
|
|
223
|
+
prefix, "quiet", "q", action="store_true", helptext="suppress warnings, display only errors"
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if self.add_config:
|
|
227
|
+
self.add_typed_argument(
|
|
228
|
+
prefix, "config", helptext=f"path to config file to fetch the defaults from", metavar="PATH"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
def apply_to_parser(self, parser):
|
|
232
|
+
for item in self.arguments_prepared:
|
|
233
|
+
kwargs = {k: v for k, v in item["kwargs"].items() if v is not None}
|
|
234
|
+
parser.add_argument(*item["names"], **kwargs)
|