click-extended 1.0.2__py3-none-any.whl → 1.0.4__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.
@@ -9,12 +9,14 @@ from click_extended.core.decorators.option import option
9
9
  from click_extended.core.decorators.prompt import prompt
10
10
  from click_extended.core.decorators.selection import selection
11
11
  from click_extended.core.decorators.tag import tag
12
+ from click_extended.core.other.get_context import get_context
12
13
 
13
14
  __all__ = [
14
15
  "argument",
15
16
  "command",
16
17
  "context",
17
18
  "env",
19
+ "get_context",
18
20
  "group",
19
21
  "option",
20
22
  "prompt",
@@ -1,7 +1,9 @@
1
1
  """Initialization file for the `click_extended.core.other` module."""
2
2
 
3
3
  from click_extended.core.other.context import Context
4
+ from click_extended.core.other.get_context import get_context
4
5
 
5
6
  __all__ = [
6
7
  "Context",
8
+ "get_context",
7
9
  ]
@@ -220,6 +220,15 @@ class Tree:
220
220
  "yes",
221
221
  )
222
222
 
223
+ parent_data: dict[str, Any] | None = None
224
+ if context.parent is not None:
225
+ parent_meta = context.parent.meta.get("click_extended", {})
226
+ parent_data = parent_meta.get("data")
227
+
228
+ data: dict[str, Any] = (
229
+ parent_data if isinstance(parent_data, dict) else {}
230
+ )
231
+
223
232
  context.meta["click_extended"] = {
224
233
  "current_scope": "root",
225
234
  "root_node": root_node,
@@ -228,7 +237,7 @@ class Tree:
228
237
  "parents": parents_dict,
229
238
  "tags": root_node.tree.tags,
230
239
  "children": children_dict,
231
- "data": {},
240
+ "data": data,
232
241
  "debug": debug,
233
242
  }
234
243
 
@@ -0,0 +1,105 @@
1
+ """Function to get the active context."""
2
+
3
+ # pylint: disable=too-many-branches
4
+ # pylint: disable=used-before-assignment
5
+
6
+ from __future__ import annotations
7
+
8
+ from typing import TYPE_CHECKING, Any, cast
9
+
10
+ import click
11
+
12
+ from click_extended.core.other.context import Context
13
+
14
+ if TYPE_CHECKING:
15
+ from click_extended.core.decorators.tag import Tag
16
+ from click_extended.core.nodes._root_node import RootNode
17
+ from click_extended.core.nodes.child_node import ChildNode
18
+ from click_extended.core.nodes.node import Node
19
+ from click_extended.core.nodes.parent_node import ParentNode
20
+
21
+
22
+ def get_context() -> Context:
23
+ """
24
+ Get the active context.
25
+
26
+ Returns:
27
+ Context:
28
+ The active context.
29
+
30
+ Raises:
31
+ RuntimeError:
32
+ If called outside a Click command or before initialization.
33
+ """
34
+ click_context = click.get_current_context(silent=True)
35
+ if click_context is None:
36
+ raise RuntimeError("No active Click context is available.")
37
+
38
+ meta_raw = click_context.meta.get("click_extended")
39
+ if not isinstance(meta_raw, dict) or not meta_raw:
40
+ raise RuntimeError(
41
+ "click-extended context has not been initialized yet."
42
+ )
43
+
44
+ meta: dict[str, Any] = cast(dict[str, Any], meta_raw)
45
+
46
+ root_node = meta.get("root_node")
47
+ if root_node is None:
48
+ raise RuntimeError(
49
+ "click-extended root node is not available in context."
50
+ )
51
+
52
+ parents: dict[str, Any] = meta.get("parents", {})
53
+ tags: dict[str, Any] = meta.get("tags", {})
54
+ children: dict[str, Any] = meta.get("children", {})
55
+ globals_nodes: dict[str, Any] = meta.get("globals", {})
56
+
57
+ if not isinstance(parents, dict):
58
+ parents = {}
59
+ if not isinstance(tags, dict):
60
+ tags = {}
61
+ if not isinstance(children, dict):
62
+ children = {}
63
+ if not isinstance(globals_nodes, dict):
64
+ globals_nodes = {}
65
+
66
+ all_nodes: dict[str, Any] = {}
67
+ if isinstance(parents, dict):
68
+ all_nodes.update(parents)
69
+ if isinstance(tags, dict):
70
+ all_nodes.update(tags)
71
+ if isinstance(children, dict):
72
+ all_nodes.update(children)
73
+ if isinstance(globals_nodes, dict):
74
+ all_nodes.update(globals_nodes)
75
+ if root_node is not None:
76
+ all_nodes[root_node.name] = root_node
77
+
78
+ current_scope = meta.get("current_scope", "root")
79
+ if current_scope not in ("root", "parent", "child"):
80
+ current_scope = "root"
81
+ parent_node = meta.get("parent_node")
82
+ child_node = meta.get("child_node")
83
+
84
+ current = None
85
+ parent = None
86
+ if current_scope == "root":
87
+ current = root_node
88
+ elif current_scope == "parent":
89
+ current = parent_node
90
+ elif current_scope == "child":
91
+ current = child_node
92
+ parent = parent_node
93
+
94
+ return Context(
95
+ root=cast(RootNode, root_node),
96
+ current=cast(Node | None, current),
97
+ parent=cast(ParentNode | Tag | None, parent),
98
+ click_context=click_context,
99
+ nodes=cast(dict[str, Node], all_nodes),
100
+ parents=cast(dict[str, ParentNode], parents),
101
+ tags=cast(dict[str, Tag], tags),
102
+ children=cast(dict[str, ChildNode], children),
103
+ data=meta.get("data", {}),
104
+ debug=bool(meta.get("debug", False)),
105
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: click_extended
3
- Version: 1.0.2
3
+ Version: 1.0.4
4
4
  Summary: An extension to Click with additional features like automatic async support, aliasing and a modular decorator system.
5
5
  Author-email: Marcus Fredriksson <marcus@marcusfredriksson.com>
6
6
  License: MIT License
@@ -96,6 +96,7 @@ An extension of the [Click](https://github.com/pallets/click) library with addit
96
96
  - **Full Type Support**: Built with type-hinting from the ground up, meaning everything is fully typed.
97
97
  - **Improved Errors**: Improved error output like tips, debugging, and more.
98
98
  - **Short Flag Concatenation**: Automatically support concatenating short hand flags where `-r -f` is the same as `-rf`.
99
+ - **Global state**: Access global state through the context's `data` property.
99
100
 
100
101
  ## Installation
101
102
 
@@ -1,4 +1,4 @@
1
- click_extended/__init__.py,sha256=mF6rVnQnG-IiMSo-hX16ZzgSv8F-F3BoAyX5PDx6x90,714
1
+ click_extended/__init__.py,sha256=E0-jE6thELe-ZP3oqx4ah-OvBSttcLuRUnUP0Yku7JI,795
2
2
  click_extended/classes.py,sha256=SdwglQ7O5ahjYeVnaM9_hCU14BYZBv8C0ZjWQIo7A_I,837
3
3
  click_extended/errors.py,sha256=tkvAXs4oUZ8SFgX37KhYrHAlsxmOGrSFLIezCH9NDQI,13897
4
4
  click_extended/types.py,sha256=0YT4QN269H-01RVxDGSpMT_hJm8cTcONonpX4_YxJlg,238
@@ -22,11 +22,12 @@ click_extended/core/nodes/node.py,sha256=Q5OgaSNhz1dAIcYNDQOaAS2eCdu9XMMyDA5lXfZ
22
22
  click_extended/core/nodes/option_node.py,sha256=fCYrnW846mz1aDyf9sTQAnuIYUGd5g6XyUN6aBMIWgE,7055
23
23
  click_extended/core/nodes/parent_node.py,sha256=x526r7XjfsUypsB1N-5aXjEbP2d06eLF30G6IszxV3w,7352
24
24
  click_extended/core/nodes/validation_node.py,sha256=9X_dBbr1BB-OYRxnGsM8CoKRbKT1MuQ29Injtf_Iu_E,4020
25
- click_extended/core/other/__init__.py,sha256=xZl7jM1Wud-g2c0l-CQYSMNwsJqwNwFDLE8FGL57XjA,155
25
+ click_extended/core/other/__init__.py,sha256=ZYPlENo4widfcRWcg4yojmkNf_E89Y7U_8hRFCTOZoY,236
26
26
  click_extended/core/other/_click_command.py,sha256=NR7e-GyKiqyVJC8X5NjRXz5ehsYl9axVIxZCSejzUg4,1738
27
27
  click_extended/core/other/_click_group.py,sha256=BoEQoyx13n27Qy1-h_Dkaie68MlyPClIVB8cNtfPGdY,7714
28
- click_extended/core/other/_tree.py,sha256=3tRivUtKbMst_oF1uICvl7ufRotSVtISGXkBIui09l8,16081
28
+ click_extended/core/other/_tree.py,sha256=IFSA3aQ-1tHjdjLO392-RLzQrpxO9b4JsyXvjdoJZ6k,16404
29
29
  click_extended/core/other/context.py,sha256=KrXfDGoVV_xuIv6fFskF0hHtWDyRDETWoSXw24GxYs8,14619
30
+ click_extended/core/other/get_context.py,sha256=FtoyCJmSRAVdqJZTTYFnfWinF6phv3u3z5yA97WgpGA,3255
30
31
  click_extended/decorators/__init__.py,sha256=BzOreglycbxGITsWLSB3VkN8e37F-ADYlGOWoO1aO7A,1142
31
32
  click_extended/decorators/check/__init__.py,sha256=WKwRFBWFQHxA69DcHgO23fBZfLRzM8N9uUlkrl7UCS4,2180
32
33
  click_extended/decorators/check/conflicts.py,sha256=qnu4k9uAWWFkzuOUXWtDS6M8VlIjzfEAH3m4qLUdwH8,4557
@@ -142,9 +143,9 @@ click_extended/utils/naming.py,sha256=kNmzOqidgZZ1dE5aMYrxpWt4VwcLuEiFunpumpfHuZ
142
143
  click_extended/utils/process.py,sha256=sU3ZCMjBgjKcDnTRLKPdQ_TAjk0AT7Q8SatagD0JyHA,9729
143
144
  click_extended/utils/selection.py,sha256=_OQC88pGPUh29boxmS5ugXEi9jZGqAG180S27PeQaj0,9875
144
145
  click_extended/utils/time.py,sha256=H5m5caIEau_1GHkiYgKL_LcTtVdw2TkFVbkqJu7A9rQ,1067
145
- click_extended-1.0.2.dist-info/licenses/AUTHORS.md,sha256=NkShPinjqtnRDQVRyVnfJuOGM56sejauE3WRoYCcbtw,132
146
- click_extended-1.0.2.dist-info/licenses/LICENSE,sha256=gjO8hzM4mFSBXFikktaXVSgmXGcre91_GPJ-E_yP56E,1075
147
- click_extended-1.0.2.dist-info/METADATA,sha256=LoKIzHzO5csaGIpPD68v1R800kVlUM7ai_ACXolUxzs,10762
148
- click_extended-1.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
149
- click_extended-1.0.2.dist-info/top_level.txt,sha256=2G3bm6tCNv80okRm773jKTk-_z1ElY-seaozZrn_TxA,15
150
- click_extended-1.0.2.dist-info/RECORD,,
146
+ click_extended-1.0.4.dist-info/licenses/AUTHORS.md,sha256=NkShPinjqtnRDQVRyVnfJuOGM56sejauE3WRoYCcbtw,132
147
+ click_extended-1.0.4.dist-info/licenses/LICENSE,sha256=gjO8hzM4mFSBXFikktaXVSgmXGcre91_GPJ-E_yP56E,1075
148
+ click_extended-1.0.4.dist-info/METADATA,sha256=T9OnyBvzTlf1Eyo2y635O8x0oYjvx77TwJ2JbSK3dX8,10841
149
+ click_extended-1.0.4.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
150
+ click_extended-1.0.4.dist-info/top_level.txt,sha256=2G3bm6tCNv80okRm773jKTk-_z1ElY-seaozZrn_TxA,15
151
+ click_extended-1.0.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5