click-extended 0.4.0__py3-none-any.whl → 1.0.1__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.
- click_extended/__init__.py +10 -6
- click_extended/classes.py +12 -8
- click_extended/core/__init__.py +10 -0
- click_extended/core/decorators/__init__.py +21 -0
- click_extended/core/decorators/argument.py +227 -0
- click_extended/core/decorators/command.py +93 -0
- click_extended/core/decorators/env.py +155 -0
- click_extended/core/decorators/group.py +96 -0
- click_extended/core/decorators/option.py +347 -0
- click_extended/core/decorators/prompt.py +69 -0
- click_extended/core/decorators/selection.py +155 -0
- click_extended/core/decorators/tag.py +109 -0
- click_extended/core/nodes/__init__.py +21 -0
- click_extended/core/nodes/_root_node.py +1012 -0
- click_extended/core/nodes/argument_node.py +165 -0
- click_extended/core/nodes/child_node.py +555 -0
- click_extended/core/nodes/child_validation_node.py +100 -0
- click_extended/core/nodes/node.py +55 -0
- click_extended/core/nodes/option_node.py +205 -0
- click_extended/core/nodes/parent_node.py +220 -0
- click_extended/core/nodes/validation_node.py +124 -0
- click_extended/core/other/__init__.py +7 -0
- click_extended/core/other/_click_command.py +60 -0
- click_extended/core/other/_click_group.py +246 -0
- click_extended/core/other/_tree.py +491 -0
- click_extended/core/other/context.py +496 -0
- click_extended/decorators/__init__.py +29 -0
- click_extended/decorators/check/__init__.py +57 -0
- click_extended/decorators/check/conflicts.py +149 -0
- click_extended/decorators/check/contains.py +69 -0
- click_extended/decorators/check/dependencies.py +115 -0
- click_extended/decorators/check/divisible_by.py +48 -0
- click_extended/decorators/check/ends_with.py +85 -0
- click_extended/decorators/check/exclusive.py +75 -0
- click_extended/decorators/check/falsy.py +37 -0
- click_extended/decorators/check/is_email.py +43 -0
- click_extended/decorators/check/is_hex_color.py +41 -0
- click_extended/decorators/check/is_hostname.py +47 -0
- click_extended/decorators/check/is_ipv4.py +46 -0
- click_extended/decorators/check/is_ipv6.py +46 -0
- click_extended/decorators/check/is_json.py +40 -0
- click_extended/decorators/check/is_mac_address.py +40 -0
- click_extended/decorators/check/is_negative.py +37 -0
- click_extended/decorators/check/is_non_zero.py +37 -0
- click_extended/decorators/check/is_port.py +39 -0
- click_extended/decorators/check/is_positive.py +37 -0
- click_extended/decorators/check/is_url.py +75 -0
- click_extended/decorators/check/is_uuid.py +40 -0
- click_extended/decorators/check/length.py +68 -0
- click_extended/decorators/check/not_empty.py +49 -0
- click_extended/decorators/check/regex.py +47 -0
- click_extended/decorators/check/requires.py +190 -0
- click_extended/decorators/check/starts_with.py +87 -0
- click_extended/decorators/check/truthy.py +37 -0
- click_extended/decorators/compare/__init__.py +15 -0
- click_extended/decorators/compare/at_least.py +57 -0
- click_extended/decorators/compare/at_most.py +57 -0
- click_extended/decorators/compare/between.py +119 -0
- click_extended/decorators/compare/greater_than.py +183 -0
- click_extended/decorators/compare/less_than.py +183 -0
- click_extended/decorators/convert/__init__.py +31 -0
- click_extended/decorators/convert/convert_angle.py +94 -0
- click_extended/decorators/convert/convert_area.py +123 -0
- click_extended/decorators/convert/convert_bits.py +211 -0
- click_extended/decorators/convert/convert_distance.py +154 -0
- click_extended/decorators/convert/convert_energy.py +155 -0
- click_extended/decorators/convert/convert_power.py +128 -0
- click_extended/decorators/convert/convert_pressure.py +131 -0
- click_extended/decorators/convert/convert_speed.py +122 -0
- click_extended/decorators/convert/convert_temperature.py +89 -0
- click_extended/decorators/convert/convert_time.py +108 -0
- click_extended/decorators/convert/convert_volume.py +218 -0
- click_extended/decorators/convert/convert_weight.py +158 -0
- click_extended/decorators/load/__init__.py +13 -0
- click_extended/decorators/load/load_csv.py +117 -0
- click_extended/decorators/load/load_json.py +61 -0
- click_extended/decorators/load/load_toml.py +47 -0
- click_extended/decorators/load/load_yaml.py +72 -0
- click_extended/decorators/math/__init__.py +37 -0
- click_extended/decorators/math/absolute.py +35 -0
- click_extended/decorators/math/add.py +48 -0
- click_extended/decorators/math/ceil.py +36 -0
- click_extended/decorators/math/clamp.py +51 -0
- click_extended/decorators/math/divide.py +42 -0
- click_extended/decorators/math/floor.py +36 -0
- click_extended/decorators/math/maximum.py +39 -0
- click_extended/decorators/math/minimum.py +39 -0
- click_extended/decorators/math/modulo.py +39 -0
- click_extended/decorators/math/multiply.py +51 -0
- click_extended/decorators/math/normalize.py +76 -0
- click_extended/decorators/math/power.py +39 -0
- click_extended/decorators/math/rounded.py +39 -0
- click_extended/decorators/math/sqrt.py +39 -0
- click_extended/decorators/math/subtract.py +39 -0
- click_extended/decorators/math/to_percent.py +63 -0
- click_extended/decorators/misc/__init__.py +17 -0
- click_extended/decorators/misc/choice.py +139 -0
- click_extended/decorators/misc/confirm_if.py +147 -0
- click_extended/decorators/misc/default.py +95 -0
- click_extended/decorators/misc/deprecated.py +131 -0
- click_extended/decorators/misc/experimental.py +79 -0
- click_extended/decorators/misc/now.py +42 -0
- click_extended/decorators/random/__init__.py +21 -0
- click_extended/decorators/random/random_bool.py +49 -0
- click_extended/decorators/random/random_choice.py +63 -0
- click_extended/decorators/random/random_datetime.py +140 -0
- click_extended/decorators/random/random_float.py +62 -0
- click_extended/decorators/random/random_integer.py +56 -0
- click_extended/decorators/random/random_prime.py +196 -0
- click_extended/decorators/random/random_string.py +77 -0
- click_extended/decorators/random/random_uuid.py +119 -0
- click_extended/decorators/transform/__init__.py +71 -0
- click_extended/decorators/transform/add_prefix.py +58 -0
- click_extended/decorators/transform/add_suffix.py +58 -0
- click_extended/decorators/transform/apply.py +35 -0
- click_extended/decorators/transform/basename.py +44 -0
- click_extended/decorators/transform/dirname.py +44 -0
- click_extended/decorators/transform/expand_vars.py +36 -0
- click_extended/decorators/transform/remove_prefix.py +57 -0
- click_extended/decorators/transform/remove_suffix.py +57 -0
- click_extended/decorators/transform/replace.py +46 -0
- click_extended/decorators/transform/slugify.py +45 -0
- click_extended/decorators/transform/split.py +43 -0
- click_extended/decorators/transform/strip.py +148 -0
- click_extended/decorators/transform/to_case.py +216 -0
- click_extended/decorators/transform/to_date.py +75 -0
- click_extended/decorators/transform/to_datetime.py +83 -0
- click_extended/decorators/transform/to_path.py +274 -0
- click_extended/decorators/transform/to_time.py +77 -0
- click_extended/decorators/transform/to_timestamp.py +114 -0
- click_extended/decorators/transform/truncate.py +47 -0
- click_extended/types.py +1 -1
- click_extended/utils/__init__.py +13 -0
- click_extended/utils/casing.py +169 -0
- click_extended/utils/checks.py +48 -0
- click_extended/utils/dispatch.py +1016 -0
- click_extended/utils/format.py +101 -0
- click_extended/utils/humanize.py +209 -0
- click_extended/utils/naming.py +238 -0
- click_extended/utils/process.py +294 -0
- click_extended/utils/selection.py +267 -0
- click_extended/utils/time.py +46 -0
- {click_extended-0.4.0.dist-info → click_extended-1.0.1.dist-info}/METADATA +100 -29
- click_extended-1.0.1.dist-info/RECORD +149 -0
- click_extended-0.4.0.dist-info/RECORD +0 -10
- {click_extended-0.4.0.dist-info → click_extended-1.0.1.dist-info}/WHEEL +0 -0
- {click_extended-0.4.0.dist-info → click_extended-1.0.1.dist-info}/licenses/AUTHORS.md +0 -0
- {click_extended-0.4.0.dist-info → click_extended-1.0.1.dist-info}/licenses/LICENSE +0 -0
- {click_extended-0.4.0.dist-info → click_extended-1.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
"""Context with a unified all contextual information across the context."""
|
|
2
|
+
|
|
3
|
+
# pylint: disable=too-many-instance-attributes
|
|
4
|
+
# pylint: disable=too-many-public-methods
|
|
5
|
+
# pylint: disable=import-outside-toplevel
|
|
6
|
+
# pylint: disable=protected-access
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import TYPE_CHECKING, Any, overload
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from click import Context as ClickContext
|
|
13
|
+
|
|
14
|
+
from click_extended.core.decorators.argument import Argument
|
|
15
|
+
from click_extended.core.decorators.env import Env
|
|
16
|
+
from click_extended.core.decorators.option import Option
|
|
17
|
+
from click_extended.core.decorators.tag import Tag
|
|
18
|
+
from click_extended.core.nodes._root_node import RootNode
|
|
19
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
20
|
+
from click_extended.core.nodes.node import Node
|
|
21
|
+
from click_extended.core.nodes.parent_node import ParentNode
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True)
|
|
25
|
+
class Context:
|
|
26
|
+
"""
|
|
27
|
+
Context with a unified all contextual information across the context.
|
|
28
|
+
|
|
29
|
+
Attributes:
|
|
30
|
+
root (RootNode):
|
|
31
|
+
The root command node of the entire CLI tree.
|
|
32
|
+
current (Node | None):
|
|
33
|
+
The current node being processed.
|
|
34
|
+
parent (ParentNode | Tag):
|
|
35
|
+
The parent node (Option, Argument, Env, or Tag) that contains
|
|
36
|
+
the current child.
|
|
37
|
+
click_context (ClickContext):
|
|
38
|
+
The Click context object.
|
|
39
|
+
nodes (dict[str, Node]):
|
|
40
|
+
All registered nodes in the tree.
|
|
41
|
+
parents (dict[str, ParentNode]):
|
|
42
|
+
All parent nodes (Option/Argument/Env).
|
|
43
|
+
tags (dict[str, Tag]):
|
|
44
|
+
All tag instances by name.
|
|
45
|
+
children (dict[str, ChildNode]):
|
|
46
|
+
All child node instances.
|
|
47
|
+
data (dict[str, Any]):
|
|
48
|
+
Shared data store accessible across all nodes. Use this to pass
|
|
49
|
+
custom data between nodes.
|
|
50
|
+
debug (bool):
|
|
51
|
+
Debug mode flag. When `True`, handler exceptions show full tracebacks.
|
|
52
|
+
Set via `@debug()` decorator.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
root: "RootNode"
|
|
56
|
+
current: "Node | None"
|
|
57
|
+
parent: "ParentNode | Tag | None"
|
|
58
|
+
click_context: "ClickContext"
|
|
59
|
+
nodes: dict[str, "Node"]
|
|
60
|
+
parents: dict[str, "ParentNode"]
|
|
61
|
+
tags: dict[str, "Tag"]
|
|
62
|
+
children: dict[str, "ChildNode"]
|
|
63
|
+
data: dict[str, Any]
|
|
64
|
+
debug: bool = False
|
|
65
|
+
|
|
66
|
+
def is_root(self) -> bool:
|
|
67
|
+
"""
|
|
68
|
+
Check if the current node is a `RootNode` instance.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
bool:
|
|
72
|
+
`True` if current node is a `RootNode`, `False` otherwise.
|
|
73
|
+
"""
|
|
74
|
+
from click_extended.core.nodes._root_node import RootNode
|
|
75
|
+
|
|
76
|
+
return isinstance(self.current, RootNode)
|
|
77
|
+
|
|
78
|
+
def is_parent(self) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
Check if the current node is a `ParentNode` instance.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
bool:
|
|
84
|
+
`True` if current node is a `ParentNode`, `False` otherwise.
|
|
85
|
+
"""
|
|
86
|
+
from click_extended.core.nodes.parent_node import ParentNode
|
|
87
|
+
|
|
88
|
+
return isinstance(self.current, ParentNode)
|
|
89
|
+
|
|
90
|
+
def is_tag(self) -> bool:
|
|
91
|
+
"""
|
|
92
|
+
Check if the parent node is a `Tag` instance.
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
bool:
|
|
96
|
+
`True` if parent is a `Tag`, `False` otherwise.
|
|
97
|
+
"""
|
|
98
|
+
from click_extended.core.decorators.tag import Tag
|
|
99
|
+
|
|
100
|
+
return isinstance(self.parent, Tag)
|
|
101
|
+
|
|
102
|
+
def is_child(self) -> bool:
|
|
103
|
+
"""
|
|
104
|
+
Check if the current node is a `ChildNode` instance.
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
bool:
|
|
108
|
+
`True` if current node is a `ChildNode`, `False` otherwise.
|
|
109
|
+
"""
|
|
110
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
111
|
+
|
|
112
|
+
return isinstance(self.current, ChildNode)
|
|
113
|
+
|
|
114
|
+
def is_argument(self) -> bool:
|
|
115
|
+
"""
|
|
116
|
+
Check if the current node is an `Argument` instance.
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
bool:
|
|
120
|
+
`True` if current node is an `Argument`, `False` otherwise.
|
|
121
|
+
"""
|
|
122
|
+
from click_extended.core.decorators.argument import Argument
|
|
123
|
+
|
|
124
|
+
return isinstance(self.current, Argument)
|
|
125
|
+
|
|
126
|
+
def is_option(self) -> bool:
|
|
127
|
+
"""
|
|
128
|
+
Check if the current node is an `Option` instance.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
bool:
|
|
132
|
+
`True` if current node is an `Option`, `False` otherwise.
|
|
133
|
+
"""
|
|
134
|
+
from click_extended.core.decorators.option import Option
|
|
135
|
+
|
|
136
|
+
return isinstance(self.current, Option)
|
|
137
|
+
|
|
138
|
+
def is_env(self) -> bool:
|
|
139
|
+
"""
|
|
140
|
+
Check if the current node is an `Env` instance.
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
bool:
|
|
144
|
+
`True` if current node is an `Env`, `False` otherwise.
|
|
145
|
+
"""
|
|
146
|
+
from click_extended.core.decorators.env import Env
|
|
147
|
+
|
|
148
|
+
return isinstance(self.current, Env)
|
|
149
|
+
|
|
150
|
+
def is_tagged(self) -> bool:
|
|
151
|
+
"""
|
|
152
|
+
Check if the current instance is tagged.
|
|
153
|
+
|
|
154
|
+
Returns:
|
|
155
|
+
bool:
|
|
156
|
+
`True` if current node has tags, `False` otherwise.
|
|
157
|
+
"""
|
|
158
|
+
from click_extended.core.nodes.parent_node import ParentNode
|
|
159
|
+
|
|
160
|
+
if isinstance(self.current, ParentNode):
|
|
161
|
+
return len(self.current.tags) > 0
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
def get_root(self) -> "RootNode":
|
|
165
|
+
"""
|
|
166
|
+
Get the root node.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
RootNode:
|
|
170
|
+
The root node of the tree.
|
|
171
|
+
"""
|
|
172
|
+
return self.root
|
|
173
|
+
|
|
174
|
+
def get_children(self, name: str | None = None) -> list["ChildNode"]:
|
|
175
|
+
"""
|
|
176
|
+
Get a list of all children defined under the same parent.
|
|
177
|
+
|
|
178
|
+
Args:
|
|
179
|
+
name (str | None, optional):
|
|
180
|
+
The parent name to get children from. If `None`,
|
|
181
|
+
uses the current parent.
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
list[ChildNode]:
|
|
185
|
+
List of child nodes under the specified parent.
|
|
186
|
+
"""
|
|
187
|
+
from click_extended.core.decorators.tag import Tag
|
|
188
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
189
|
+
from click_extended.core.nodes.parent_node import ParentNode
|
|
190
|
+
|
|
191
|
+
if name is not None:
|
|
192
|
+
parent: "ParentNode | Tag | None" = self.get_parent(name)
|
|
193
|
+
if parent is None:
|
|
194
|
+
return []
|
|
195
|
+
elif isinstance(self.parent, (ParentNode, Tag)):
|
|
196
|
+
parent = self.parent
|
|
197
|
+
else:
|
|
198
|
+
return []
|
|
199
|
+
|
|
200
|
+
if not parent.children:
|
|
201
|
+
return []
|
|
202
|
+
|
|
203
|
+
return [
|
|
204
|
+
child
|
|
205
|
+
for child in parent.children.values()
|
|
206
|
+
if isinstance(child, ChildNode)
|
|
207
|
+
]
|
|
208
|
+
|
|
209
|
+
def get_siblings(self) -> list["ChildNode"]:
|
|
210
|
+
"""
|
|
211
|
+
Get a list of all siblings in the current parent, excluding the
|
|
212
|
+
current child.
|
|
213
|
+
|
|
214
|
+
Returns:
|
|
215
|
+
list[ChildNode]:
|
|
216
|
+
List of sibling child nodes.
|
|
217
|
+
"""
|
|
218
|
+
from click_extended.core.nodes.child_node import ChildNode
|
|
219
|
+
|
|
220
|
+
if not isinstance(self.current, ChildNode):
|
|
221
|
+
return []
|
|
222
|
+
|
|
223
|
+
all_children = self.get_children()
|
|
224
|
+
return [child for child in all_children if child is not self.current]
|
|
225
|
+
|
|
226
|
+
def get_parent(self, name: str) -> "ParentNode | None":
|
|
227
|
+
"""
|
|
228
|
+
Get a parent node by name.
|
|
229
|
+
|
|
230
|
+
Args:
|
|
231
|
+
name (str):
|
|
232
|
+
The parent node name to retrieve.
|
|
233
|
+
|
|
234
|
+
Returns:
|
|
235
|
+
ParentNode | None:
|
|
236
|
+
The parent node if found, `None` otherwise.
|
|
237
|
+
"""
|
|
238
|
+
return self.parents.get(name)
|
|
239
|
+
|
|
240
|
+
def get_node(self, name: str) -> "Node | None":
|
|
241
|
+
"""
|
|
242
|
+
Get any node by name.
|
|
243
|
+
|
|
244
|
+
Args:
|
|
245
|
+
name (str):
|
|
246
|
+
The node name to retrieve.
|
|
247
|
+
|
|
248
|
+
Returns:
|
|
249
|
+
Node | None:
|
|
250
|
+
The node if found, `None` otherwise.
|
|
251
|
+
"""
|
|
252
|
+
return self.nodes.get(name)
|
|
253
|
+
|
|
254
|
+
def get_tag(self, name: str) -> "Tag | None":
|
|
255
|
+
"""
|
|
256
|
+
Get a tag by name.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
name (str):
|
|
260
|
+
The tag name to retrieve.
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
Tag | None:
|
|
264
|
+
The tag if found, `None` otherwise.
|
|
265
|
+
"""
|
|
266
|
+
return self.tags.get(name)
|
|
267
|
+
|
|
268
|
+
@overload
|
|
269
|
+
def get_tagged(self) -> dict[str, list["ParentNode"]]: ...
|
|
270
|
+
|
|
271
|
+
@overload
|
|
272
|
+
def get_tagged(self, name: str) -> list["ParentNode"]: ...
|
|
273
|
+
|
|
274
|
+
def get_tagged(
|
|
275
|
+
self, name: str | None = None
|
|
276
|
+
) -> dict[str, list["ParentNode"]] | list["ParentNode"]:
|
|
277
|
+
"""
|
|
278
|
+
Get tagged parent nodes, either all tags or a specific tag.
|
|
279
|
+
|
|
280
|
+
Args:
|
|
281
|
+
name (str | None, optional):
|
|
282
|
+
The tag name to get parents for. If `None`, returns all tags.
|
|
283
|
+
|
|
284
|
+
Returns:
|
|
285
|
+
dict[str, list[ParentNode]] | list[ParentNode]:
|
|
286
|
+
If `name` is `None`, returns a dictionary mapping tag names to
|
|
287
|
+
lists of parent nodes. If `name` is provided, returns a list
|
|
288
|
+
of parent nodes with that tag.
|
|
289
|
+
"""
|
|
290
|
+
result: dict[str, list["ParentNode"]] = {}
|
|
291
|
+
|
|
292
|
+
for parent in self.parents.values():
|
|
293
|
+
for tag in parent.tags:
|
|
294
|
+
if tag not in result:
|
|
295
|
+
result[tag] = []
|
|
296
|
+
result[tag].append(parent)
|
|
297
|
+
|
|
298
|
+
if name is None:
|
|
299
|
+
return result
|
|
300
|
+
|
|
301
|
+
return result.get(name, [])
|
|
302
|
+
|
|
303
|
+
def get_values(self) -> dict[str, Any]:
|
|
304
|
+
"""
|
|
305
|
+
Get the processed value of all source nodes.
|
|
306
|
+
|
|
307
|
+
Returns:
|
|
308
|
+
dict[str, Any]:
|
|
309
|
+
Dictionary mapping parent names to their processed values.
|
|
310
|
+
"""
|
|
311
|
+
return {
|
|
312
|
+
name: parent.get_value() for name, parent in self.parents.items()
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
def get_provided_arguments(self) -> list["Argument"]:
|
|
316
|
+
"""
|
|
317
|
+
Get all provided positional arguments.
|
|
318
|
+
|
|
319
|
+
Returns:
|
|
320
|
+
list[Argument]:
|
|
321
|
+
List of provided argument nodes.
|
|
322
|
+
"""
|
|
323
|
+
from click_extended.core.decorators.argument import Argument
|
|
324
|
+
|
|
325
|
+
return [
|
|
326
|
+
parent
|
|
327
|
+
for parent in self.parents.values()
|
|
328
|
+
if isinstance(parent, Argument) and parent.was_provided
|
|
329
|
+
]
|
|
330
|
+
|
|
331
|
+
def get_provided_options(self) -> list["Option"]:
|
|
332
|
+
"""
|
|
333
|
+
Get all provided keyword arguments.
|
|
334
|
+
|
|
335
|
+
Returns:
|
|
336
|
+
list[Option]:
|
|
337
|
+
List of provided option nodes.
|
|
338
|
+
"""
|
|
339
|
+
from click_extended.core.decorators.option import Option
|
|
340
|
+
|
|
341
|
+
return [
|
|
342
|
+
parent
|
|
343
|
+
for parent in self.parents.values()
|
|
344
|
+
if isinstance(parent, Option) and parent.was_provided
|
|
345
|
+
]
|
|
346
|
+
|
|
347
|
+
def get_provided_envs(self) -> list["Env"]:
|
|
348
|
+
"""
|
|
349
|
+
Get all provided environment variables.
|
|
350
|
+
|
|
351
|
+
Returns:
|
|
352
|
+
list[Env]:
|
|
353
|
+
List of provided env nodes.
|
|
354
|
+
"""
|
|
355
|
+
from click_extended.core.decorators.env import Env
|
|
356
|
+
|
|
357
|
+
return [
|
|
358
|
+
parent
|
|
359
|
+
for parent in self.parents.values()
|
|
360
|
+
if isinstance(parent, Env) and parent.was_provided
|
|
361
|
+
]
|
|
362
|
+
|
|
363
|
+
def get_provided_value(self, name: str) -> Any:
|
|
364
|
+
"""
|
|
365
|
+
Get the provided raw value of a parent node (before processing).
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
name (str):
|
|
369
|
+
The parent node name.
|
|
370
|
+
|
|
371
|
+
Returns:
|
|
372
|
+
Any:
|
|
373
|
+
The raw value if parent exists and was provided, `None`
|
|
374
|
+
otherwise.
|
|
375
|
+
"""
|
|
376
|
+
parent = self.get_parent(name)
|
|
377
|
+
if parent is not None and parent.was_provided:
|
|
378
|
+
return parent.raw_value # type: ignore
|
|
379
|
+
return None
|
|
380
|
+
|
|
381
|
+
def get_provided_values(self) -> dict[str, Any]:
|
|
382
|
+
"""
|
|
383
|
+
Get the provided raw values in the context (before processing).
|
|
384
|
+
|
|
385
|
+
Returns:
|
|
386
|
+
dict[str, Any]:
|
|
387
|
+
The provided raw values in the context.
|
|
388
|
+
"""
|
|
389
|
+
provided: dict[str, Any] = {}
|
|
390
|
+
for name, parent in self.parents.items():
|
|
391
|
+
if parent.was_provided:
|
|
392
|
+
provided[name] = parent.raw_value
|
|
393
|
+
return provided
|
|
394
|
+
|
|
395
|
+
def get_missing_arguments(self) -> list["Argument"]:
|
|
396
|
+
"""
|
|
397
|
+
Get all missing positional arguments.
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
list[Argument]:
|
|
401
|
+
List of all argument nodes.
|
|
402
|
+
"""
|
|
403
|
+
from click_extended.core.decorators.argument import Argument
|
|
404
|
+
|
|
405
|
+
return [
|
|
406
|
+
parent
|
|
407
|
+
for parent in self.parents.values()
|
|
408
|
+
if isinstance(parent, Argument) and not parent.was_provided
|
|
409
|
+
]
|
|
410
|
+
|
|
411
|
+
def get_missing_options(self) -> list["Option"]:
|
|
412
|
+
"""
|
|
413
|
+
Get all missing keyword arguments.
|
|
414
|
+
|
|
415
|
+
Returns:
|
|
416
|
+
list[Option]:
|
|
417
|
+
List of all option nodes.
|
|
418
|
+
"""
|
|
419
|
+
from click_extended.core.decorators.option import Option
|
|
420
|
+
|
|
421
|
+
return [
|
|
422
|
+
parent
|
|
423
|
+
for parent in self.parents.values()
|
|
424
|
+
if isinstance(parent, Option) and not parent.was_provided
|
|
425
|
+
]
|
|
426
|
+
|
|
427
|
+
def get_missing_envs(self) -> list["Env"]:
|
|
428
|
+
"""
|
|
429
|
+
Get all missing environment variables.
|
|
430
|
+
|
|
431
|
+
Returns:
|
|
432
|
+
list[Env]:
|
|
433
|
+
List of all env nodes.
|
|
434
|
+
"""
|
|
435
|
+
from click_extended.core.decorators.env import Env
|
|
436
|
+
|
|
437
|
+
return [
|
|
438
|
+
parent
|
|
439
|
+
for parent in self.parents.values()
|
|
440
|
+
if isinstance(parent, Env) and not parent.was_provided
|
|
441
|
+
]
|
|
442
|
+
|
|
443
|
+
def get_current_tags(self) -> list[str]:
|
|
444
|
+
"""
|
|
445
|
+
Get a list of the tags of the current node.
|
|
446
|
+
|
|
447
|
+
Returns:
|
|
448
|
+
list[str]:
|
|
449
|
+
List of tag names for the current node.
|
|
450
|
+
"""
|
|
451
|
+
from click_extended.core.nodes.parent_node import ParentNode
|
|
452
|
+
|
|
453
|
+
if isinstance(self.current, ParentNode):
|
|
454
|
+
return list(self.current.tags)
|
|
455
|
+
return []
|
|
456
|
+
|
|
457
|
+
def get_current_parent_as_parent(self) -> "ParentNode":
|
|
458
|
+
"""
|
|
459
|
+
Get the current parent node as a `ParentNode`.
|
|
460
|
+
|
|
461
|
+
Returns:
|
|
462
|
+
ParentNode:
|
|
463
|
+
The current parent node.
|
|
464
|
+
|
|
465
|
+
Raises:
|
|
466
|
+
RuntimeError:
|
|
467
|
+
If called outside child node context or the parent is a `Tag`.
|
|
468
|
+
"""
|
|
469
|
+
from click_extended.core.decorators.tag import Tag
|
|
470
|
+
|
|
471
|
+
if self.parent is None:
|
|
472
|
+
raise RuntimeError("No parent node in current context")
|
|
473
|
+
if isinstance(self.parent, Tag):
|
|
474
|
+
raise RuntimeError("Parent node is not a ParentNode instance.")
|
|
475
|
+
return self.parent
|
|
476
|
+
|
|
477
|
+
def get_current_parent_as_tag(self) -> "Tag":
|
|
478
|
+
"""
|
|
479
|
+
Get the current parent node as a `Tag`.
|
|
480
|
+
|
|
481
|
+
Returns:
|
|
482
|
+
Tag:
|
|
483
|
+
The current parent node.
|
|
484
|
+
|
|
485
|
+
Raises:
|
|
486
|
+
RuntimeError:
|
|
487
|
+
If called outside child node context or
|
|
488
|
+
the parent is a `ParentNode`.
|
|
489
|
+
"""
|
|
490
|
+
from click_extended.core.nodes.parent_node import ParentNode
|
|
491
|
+
|
|
492
|
+
if self.parent is None:
|
|
493
|
+
raise RuntimeError("No parent node in current context")
|
|
494
|
+
if isinstance(self.parent, ParentNode):
|
|
495
|
+
raise RuntimeError("Parent node is not a Tag instance.")
|
|
496
|
+
return self.parent
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Initialization file for the `click_extended.decorators` module."""
|
|
2
|
+
|
|
3
|
+
from click_extended.decorators.check import *
|
|
4
|
+
from click_extended.decorators.check import __all__ as check_all
|
|
5
|
+
from click_extended.decorators.compare import *
|
|
6
|
+
from click_extended.decorators.compare import __all__ as compare_all
|
|
7
|
+
from click_extended.decorators.convert import *
|
|
8
|
+
from click_extended.decorators.convert import __all__ as convert_all
|
|
9
|
+
from click_extended.decorators.load import *
|
|
10
|
+
from click_extended.decorators.load import __all__ as load_all
|
|
11
|
+
from click_extended.decorators.math import *
|
|
12
|
+
from click_extended.decorators.math import __all__ as math_all
|
|
13
|
+
from click_extended.decorators.misc import *
|
|
14
|
+
from click_extended.decorators.misc import __all__ as misc_all
|
|
15
|
+
from click_extended.decorators.random import *
|
|
16
|
+
from click_extended.decorators.random import __all__ as random_all
|
|
17
|
+
from click_extended.decorators.transform import *
|
|
18
|
+
from click_extended.decorators.transform import __all__ as transform_all
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
*check_all,
|
|
22
|
+
*compare_all,
|
|
23
|
+
*convert_all,
|
|
24
|
+
*load_all,
|
|
25
|
+
*math_all,
|
|
26
|
+
*misc_all,
|
|
27
|
+
*random_all,
|
|
28
|
+
*transform_all,
|
|
29
|
+
] # type: ignore
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Initialization file for the `click_extended.decorators.check` module."""
|
|
2
|
+
|
|
3
|
+
from click_extended.decorators.check.conflicts import conflicts
|
|
4
|
+
from click_extended.decorators.check.contains import contains
|
|
5
|
+
from click_extended.decorators.check.dependencies import dependencies
|
|
6
|
+
from click_extended.decorators.check.divisible_by import divisible_by
|
|
7
|
+
from click_extended.decorators.check.ends_with import ends_with
|
|
8
|
+
from click_extended.decorators.check.exclusive import exclusive
|
|
9
|
+
from click_extended.decorators.check.falsy import falsy
|
|
10
|
+
from click_extended.decorators.check.is_email import is_email
|
|
11
|
+
from click_extended.decorators.check.is_hex_color import is_hex_color
|
|
12
|
+
from click_extended.decorators.check.is_hostname import is_hostname
|
|
13
|
+
from click_extended.decorators.check.is_ipv4 import is_ipv4
|
|
14
|
+
from click_extended.decorators.check.is_ipv6 import is_ipv6
|
|
15
|
+
from click_extended.decorators.check.is_json import is_json
|
|
16
|
+
from click_extended.decorators.check.is_mac_address import is_mac_address
|
|
17
|
+
from click_extended.decorators.check.is_negative import is_negative
|
|
18
|
+
from click_extended.decorators.check.is_non_zero import is_non_zero
|
|
19
|
+
from click_extended.decorators.check.is_port import is_port
|
|
20
|
+
from click_extended.decorators.check.is_positive import is_positive
|
|
21
|
+
from click_extended.decorators.check.is_url import is_url
|
|
22
|
+
from click_extended.decorators.check.is_uuid import is_uuid
|
|
23
|
+
from click_extended.decorators.check.length import length
|
|
24
|
+
from click_extended.decorators.check.not_empty import not_empty
|
|
25
|
+
from click_extended.decorators.check.regex import regex
|
|
26
|
+
from click_extended.decorators.check.requires import requires
|
|
27
|
+
from click_extended.decorators.check.starts_with import starts_with
|
|
28
|
+
from click_extended.decorators.check.truthy import truthy
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"conflicts",
|
|
32
|
+
"contains",
|
|
33
|
+
"dependencies",
|
|
34
|
+
"divisible_by",
|
|
35
|
+
"ends_with",
|
|
36
|
+
"exclusive",
|
|
37
|
+
"falsy",
|
|
38
|
+
"is_email",
|
|
39
|
+
"is_hex_color",
|
|
40
|
+
"is_hostname",
|
|
41
|
+
"is_ipv4",
|
|
42
|
+
"is_ipv6",
|
|
43
|
+
"is_json",
|
|
44
|
+
"is_mac_address",
|
|
45
|
+
"is_negative",
|
|
46
|
+
"is_non_zero",
|
|
47
|
+
"is_port",
|
|
48
|
+
"is_positive",
|
|
49
|
+
"regex",
|
|
50
|
+
"is_url",
|
|
51
|
+
"is_uuid",
|
|
52
|
+
"length",
|
|
53
|
+
"not_empty",
|
|
54
|
+
"requires",
|
|
55
|
+
"starts_with",
|
|
56
|
+
"truthy",
|
|
57
|
+
]
|