click-extended 0.0.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.
@@ -0,0 +1,5 @@
1
+ ![Banner](./assets/click-extended-authors-banner.png)
2
+
3
+ # Authors
4
+
5
+ - Marcus Fredriksson [@marcusfrdk](https://github.com/marcusfrdk)
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Marcus Fredriksson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.4
2
+ Name: click_extended
3
+ Version: 0.0.1
4
+ Summary: An extension to Click with additional features like automatic async support, aliasing and a modular decorator system.
5
+ Author-email: Marcus Fredriksson <marcus@marcusfredriksson.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Marcus Fredriksson
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/marcusfrdk/click-extended
29
+ Project-URL: Repository, https://github.com/marcusfrdk/click-extended
30
+ Project-URL: Issues, https://github.com/marcusfrdk/click-extended/issues
31
+ Keywords: click,cli,command-line,alias,aliasing,command,group,decorator,terminal,console
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: OS Independent
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.10
37
+ Classifier: Programming Language :: Python :: 3.11
38
+ Classifier: Programming Language :: Python :: 3.12
39
+ Classifier: Programming Language :: Python :: 3.13
40
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
41
+ Classifier: Topic :: System :: Shells
42
+ Classifier: Topic :: Utilities
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: >=3.10
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ License-File: AUTHORS.md
48
+ Requires-Dist: click>=8.3.0
49
+ Requires-Dist: python-dotenv>=1.2.1
50
+ Provides-Extra: build
51
+ Requires-Dist: build; extra == "build"
52
+ Requires-Dist: twine; extra == "build"
53
+ Provides-Extra: dev
54
+ Requires-Dist: pytest>=8.4.2; extra == "dev"
55
+ Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
56
+ Requires-Dist: pytest-asyncio>=1.2.0; extra == "dev"
57
+ Requires-Dist: mypy>=1.18.2; extra == "dev"
58
+ Requires-Dist: pylint>=3.0.0; extra == "dev"
59
+ Requires-Dist: isort>=5.12.0; extra == "dev"
60
+ Requires-Dist: black>=25.9.0; extra == "dev"
61
+ Requires-Dist: pre-commit>=4.3.0; extra == "dev"
62
+ Dynamic: license-file
63
+
64
+ ![Banner](./assets/click-extended-banner.png)
65
+
66
+ # Click Extended
67
+
68
+ TBD
69
+
70
+ ## Installation
71
+
72
+ ```bash
73
+ pip install click-extended
74
+ ```
75
+
76
+ ## Requirements
77
+
78
+ TBD
79
+
80
+ ## License
81
+
82
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
83
+
84
+ ## Contributing
85
+
86
+ TBD
87
+
88
+ ## Acknowledgements
89
+
90
+ This project is built on top of the [Click](https://github.com/pallets/click) library.
@@ -0,0 +1,27 @@
1
+ ![Banner](./assets/click-extended-banner.png)
2
+
3
+ # Click Extended
4
+
5
+ TBD
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install click-extended
11
+ ```
12
+
13
+ ## Requirements
14
+
15
+ TBD
16
+
17
+ ## License
18
+
19
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
20
+
21
+ ## Contributing
22
+
23
+ TBD
24
+
25
+ ## Acknowledgements
26
+
27
+ This project is built on top of the [Click](https://github.com/pallets/click) library.
@@ -0,0 +1,21 @@
1
+ """Initialization file for the 'click_extended' module."""
2
+
3
+ from click_extended.core._child_node import ChildNode
4
+ from click_extended.core._parent_node import ParentNode
5
+ from click_extended.core.argument import argument
6
+ from click_extended.core.command import command
7
+ from click_extended.core.env import env
8
+ from click_extended.core.group import group
9
+ from click_extended.core.option import option
10
+ from click_extended.core.tag import tag
11
+
12
+ __all__ = [
13
+ "ChildNode",
14
+ "ParentNode",
15
+ "argument",
16
+ "command",
17
+ "env",
18
+ "group",
19
+ "option",
20
+ "tag",
21
+ ]
@@ -0,0 +1,128 @@
1
+ """Exceptions used in the `click_extended` library."""
2
+
3
+ # pylint: disable=too-many-arguments
4
+ # pylint: disable=too-many-positional-arguments
5
+
6
+
7
+ class ClickExtendedError(Exception):
8
+ """Base exception for exceptions defined in the `click_extended` library."""
9
+
10
+ def __init__(self, message: str) -> None:
11
+ """
12
+ Initialize a new `ClickExtendedError` instance.
13
+
14
+ Args:
15
+ message (str):
16
+ The message to show.
17
+ """
18
+ super().__init__(message)
19
+
20
+
21
+ class NoParentError(ClickExtendedError):
22
+ """Exception raised when no `ParentNode` has been defined."""
23
+
24
+ def __init__(self, name: str) -> None:
25
+ """
26
+ Initialize a new `NoParentError` instance.
27
+
28
+ Args:
29
+ name (str):
30
+ The name of the child node.
31
+ """
32
+
33
+ message = (
34
+ f"Failed to register the child node '{name}' as no parent is "
35
+ "defined. Ensure a parent node is registered before registering a "
36
+ "child node."
37
+ )
38
+ super().__init__(message)
39
+
40
+
41
+ class NoRootError(ClickExtendedError):
42
+ """Exception raised when there is no `RootNode` defined."""
43
+
44
+ def __init__(self, message: str | None = None) -> None:
45
+ """Initialize a new `NoRootError` instance."""
46
+ super().__init__(message or "No root node is defined in the tree.")
47
+
48
+
49
+ class ParentNodeExistsError(ClickExtendedError):
50
+ """Exception raised when a parent node already exists with the same name."""
51
+
52
+ def __init__(self, name: str) -> None:
53
+ """
54
+ Initialize a new `ParentNodeExistsError` instance.
55
+
56
+ Args:
57
+ name (str):
58
+ The name of the parent node.
59
+ """
60
+ message = (
61
+ f"Cannot register parent node '{name}' as a parent node with this "
62
+ "name already exists. "
63
+ f"Parent node names must be unique within the tree."
64
+ )
65
+ super().__init__(message)
66
+
67
+
68
+ class RootNodeExistsError(ClickExtendedError):
69
+ """Exception raised when a root node already exists for the tree."""
70
+
71
+ def __init__(self) -> None:
72
+ """Initialize a new `RootNodeExistsError` instance."""
73
+ message = (
74
+ "Cannot register root node as a root node has already been "
75
+ "defined. Only one root node is allowed per tree instance."
76
+ )
77
+ super().__init__(message)
78
+
79
+
80
+ class InvalidChildOnTagError(ClickExtendedError):
81
+ """Exception raised when a transformation child is attached to a tag."""
82
+
83
+ def __init__(self, child_name: str, tag_name: str) -> None:
84
+ """
85
+ Initialize a new `InvalidChildOnTagError` instance.
86
+
87
+ Args:
88
+ child_name (str):
89
+ The name of the child node.
90
+ tag_name (str):
91
+ The name of the tag.
92
+ """
93
+ message = (
94
+ f"Cannot attach transformation child '{child_name}' to tag "
95
+ f"'{tag_name}'. Tags can only have validation-only children "
96
+ "(no return statement or return None)."
97
+ )
98
+ super().__init__(message)
99
+
100
+
101
+ class DuplicateNameError(ClickExtendedError):
102
+ """Exception raised when a name collision is detected."""
103
+
104
+ def __init__(
105
+ self, name: str, type1: str, type2: str, location1: str, location2: str
106
+ ) -> None:
107
+ """
108
+ Initialize a new `DuplicateNameError` instance.
109
+
110
+ Args:
111
+ name (str):
112
+ The conflicting name.
113
+ type1 (str):
114
+ The type of the first node (e.g., "option", "tag").
115
+ type2 (str):
116
+ The type of the second node.
117
+ location1 (str):
118
+ Description of where the first node is defined.
119
+ location2 (str):
120
+ Description of where the second node is defined.
121
+ """
122
+ message = (
123
+ f"The name '{name}' is used by both "
124
+ f"{type1} {location1} and {type2} {location2}. "
125
+ f"All names (options, arguments, environment variables, and tags) "
126
+ f"must be unique within a command."
127
+ )
128
+ super().__init__(message)
@@ -0,0 +1,34 @@
1
+ """Types used in `click_extended` which can be useful for users."""
2
+
3
+ from click_extended.core._child_node import ChildNode
4
+ from click_extended.core._node import Node
5
+ from click_extended.core._parent_node import ParentNode
6
+ from click_extended.core._root_node import RootNode
7
+ from click_extended.core._tree import Tree
8
+ from click_extended.core.argument import Argument
9
+ from click_extended.core.command import Command
10
+ from click_extended.core.env import Env
11
+ from click_extended.core.group import Group
12
+ from click_extended.core.option import Option
13
+ from click_extended.core.tag import Tag
14
+
15
+ Tags = dict[str, Tag]
16
+ Siblings = list[str]
17
+ Parent = ParentNode | Tag
18
+
19
+ __all__ = [
20
+ "ChildNode",
21
+ "Node",
22
+ "Parent",
23
+ "ParentNode",
24
+ "RootNode",
25
+ "Tree",
26
+ "Argument",
27
+ "Command",
28
+ "Env",
29
+ "Group",
30
+ "Option",
31
+ "Siblings",
32
+ "Tag",
33
+ "Tags",
34
+ ]
@@ -0,0 +1,90 @@
1
+ Metadata-Version: 2.4
2
+ Name: click_extended
3
+ Version: 0.0.1
4
+ Summary: An extension to Click with additional features like automatic async support, aliasing and a modular decorator system.
5
+ Author-email: Marcus Fredriksson <marcus@marcusfredriksson.com>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Marcus Fredriksson
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://github.com/marcusfrdk/click-extended
29
+ Project-URL: Repository, https://github.com/marcusfrdk/click-extended
30
+ Project-URL: Issues, https://github.com/marcusfrdk/click-extended/issues
31
+ Keywords: click,cli,command-line,alias,aliasing,command,group,decorator,terminal,console
32
+ Classifier: Intended Audience :: Developers
33
+ Classifier: License :: OSI Approved :: MIT License
34
+ Classifier: Operating System :: OS Independent
35
+ Classifier: Programming Language :: Python :: 3
36
+ Classifier: Programming Language :: Python :: 3.10
37
+ Classifier: Programming Language :: Python :: 3.11
38
+ Classifier: Programming Language :: Python :: 3.12
39
+ Classifier: Programming Language :: Python :: 3.13
40
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
41
+ Classifier: Topic :: System :: Shells
42
+ Classifier: Topic :: Utilities
43
+ Classifier: Typing :: Typed
44
+ Requires-Python: >=3.10
45
+ Description-Content-Type: text/markdown
46
+ License-File: LICENSE
47
+ License-File: AUTHORS.md
48
+ Requires-Dist: click>=8.3.0
49
+ Requires-Dist: python-dotenv>=1.2.1
50
+ Provides-Extra: build
51
+ Requires-Dist: build; extra == "build"
52
+ Requires-Dist: twine; extra == "build"
53
+ Provides-Extra: dev
54
+ Requires-Dist: pytest>=8.4.2; extra == "dev"
55
+ Requires-Dist: pytest-cov>=7.0.0; extra == "dev"
56
+ Requires-Dist: pytest-asyncio>=1.2.0; extra == "dev"
57
+ Requires-Dist: mypy>=1.18.2; extra == "dev"
58
+ Requires-Dist: pylint>=3.0.0; extra == "dev"
59
+ Requires-Dist: isort>=5.12.0; extra == "dev"
60
+ Requires-Dist: black>=25.9.0; extra == "dev"
61
+ Requires-Dist: pre-commit>=4.3.0; extra == "dev"
62
+ Dynamic: license-file
63
+
64
+ ![Banner](./assets/click-extended-banner.png)
65
+
66
+ # Click Extended
67
+
68
+ TBD
69
+
70
+ ## Installation
71
+
72
+ ```bash
73
+ pip install click-extended
74
+ ```
75
+
76
+ ## Requirements
77
+
78
+ TBD
79
+
80
+ ## License
81
+
82
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
83
+
84
+ ## Contributing
85
+
86
+ TBD
87
+
88
+ ## Acknowledgements
89
+
90
+ This project is built on top of the [Click](https://github.com/pallets/click) library.
@@ -0,0 +1,23 @@
1
+ AUTHORS.md
2
+ LICENSE
3
+ README.md
4
+ pyproject.toml
5
+ click_extended/__init__.py
6
+ click_extended/errors.py
7
+ click_extended/types.py
8
+ click_extended.egg-info/PKG-INFO
9
+ click_extended.egg-info/SOURCES.txt
10
+ click_extended.egg-info/dependency_links.txt
11
+ click_extended.egg-info/requires.txt
12
+ click_extended.egg-info/top_level.txt
13
+ tests/test_argument.py
14
+ tests/test_child_node.py
15
+ tests/test_command.py
16
+ tests/test_env.py
17
+ tests/test_group.py
18
+ tests/test_option.py
19
+ tests/test_parent_node.py
20
+ tests/test_root_node.py
21
+ tests/test_tag.py
22
+ tests/test_transform.py
23
+ tests/test_tree.py
@@ -0,0 +1,16 @@
1
+ click>=8.3.0
2
+ python-dotenv>=1.2.1
3
+
4
+ [build]
5
+ build
6
+ twine
7
+
8
+ [dev]
9
+ pytest>=8.4.2
10
+ pytest-cov>=7.0.0
11
+ pytest-asyncio>=1.2.0
12
+ mypy>=1.18.2
13
+ pylint>=3.0.0
14
+ isort>=5.12.0
15
+ black>=25.9.0
16
+ pre-commit>=4.3.0
@@ -0,0 +1 @@
1
+ click_extended
@@ -0,0 +1,134 @@
1
+ [project]
2
+ name = "click_extended"
3
+ version = "0.0.1"
4
+ description = "An extension to Click with additional features like automatic async support, aliasing and a modular decorator system."
5
+ authors = [
6
+ { name = "Marcus Fredriksson", email = "marcus@marcusfredriksson.com" },
7
+ ]
8
+ classifiers = [
9
+ "Intended Audience :: Developers",
10
+ "License :: OSI Approved :: MIT License",
11
+ "Operating System :: OS Independent",
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.10",
14
+ "Programming Language :: Python :: 3.11",
15
+ "Programming Language :: Python :: 3.12",
16
+ "Programming Language :: Python :: 3.13",
17
+ "Topic :: Software Development :: Libraries :: Python Modules",
18
+ "Topic :: System :: Shells",
19
+ "Topic :: Utilities",
20
+ "Typing :: Typed",
21
+ ]
22
+ license = { file = "LICENSE" }
23
+ requires-python = ">=3.10"
24
+ readme = "README.md"
25
+ keywords = [
26
+ "click",
27
+ "cli",
28
+ "command-line",
29
+ "alias",
30
+ "aliasing",
31
+ "command",
32
+ "group",
33
+ "decorator",
34
+ "terminal",
35
+ "console"
36
+ ]
37
+ dependencies = [
38
+ "click>=8.3.0",
39
+ "python-dotenv>=1.2.1",
40
+ ]
41
+
42
+ [project.optional-dependencies]
43
+ build = ["build", "twine"]
44
+ dev = [
45
+ "pytest>=8.4.2",
46
+ "pytest-cov>=7.0.0",
47
+ "pytest-asyncio>=1.2.0",
48
+ "mypy>=1.18.2",
49
+ "pylint>=3.0.0",
50
+ "isort>=5.12.0",
51
+ "black>=25.9.0",
52
+ "pre-commit>=4.3.0"
53
+ ]
54
+
55
+ [build-system]
56
+ requires = ["setuptools", "wheel"]
57
+ build-backend = "setuptools.build_meta"
58
+
59
+ [tool.setuptools]
60
+ packages = ["click_extended"]
61
+
62
+ [tool.pylint.master]
63
+ ignore = [
64
+ "venv",
65
+ ".venv",
66
+ "__pycache__",
67
+ ".git",
68
+ "tests",
69
+ "docs",
70
+ "build",
71
+ "dist",
72
+ ".pytest_cache",
73
+ ".mypy_cache",
74
+ "*.egg-info",
75
+ ]
76
+ ignore-paths = ["^tests/.*$", "^docs/.*$", "^\\..*$"]
77
+ persistent = true
78
+
79
+ [tool.pylint.messages_control]
80
+ disable = ["duplicate-code"]
81
+
82
+ [tool.pylint.format]
83
+ max-line-length = 80
84
+
85
+ [tool.pytest.ini_options]
86
+ minversion = "6.0"
87
+ addopts = "-ra"
88
+ testpaths = ["tests"]
89
+ asyncio_mode = "auto"
90
+ asyncio_default_fixture_loop_scope = "function"
91
+
92
+ [tool.coverage.run]
93
+ source = ["click_extended"]
94
+ omit = ["*/tests/*", "*/__pycache__/*", "*/.venv/*"]
95
+
96
+ [tool.coverage.report]
97
+ exclude_lines = [
98
+ "pragma: no cover",
99
+ "def __repr__",
100
+ "raise AssertionError",
101
+ "raise NotImplementedError",
102
+ "if __name__ == .__main__.:",
103
+ "if TYPE_CHECKING:",
104
+ "class .*\\bProtocol\\):",
105
+ "@(abc\\.)?abstractmethod",
106
+ ]
107
+
108
+ [tool.black]
109
+ line-length = 80
110
+ target-version = ["py310", "py311", "py312", "py313"]
111
+
112
+ [tool.isort]
113
+ profile = "black"
114
+ line_length = 80
115
+
116
+ [tool.mypy]
117
+ python_version = "3.10"
118
+ strict = true
119
+ warn_return_any = true
120
+ warn_unused_configs = true
121
+ disallow_untyped_defs = true
122
+ disallow_any_unimported = false
123
+ no_implicit_optional = true
124
+ warn_redundant_casts = true
125
+ warn_unused_ignores = false
126
+ warn_no_return = true
127
+ check_untyped_defs = true
128
+ strict_equality = true
129
+ disable_error_code = ["override", "unused-ignore"]
130
+
131
+ [project.urls]
132
+ Homepage = "https://github.com/marcusfrdk/click-extended"
133
+ Repository = "https://github.com/marcusfrdk/click-extended"
134
+ Issues = "https://github.com/marcusfrdk/click-extended/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+