bonus-click 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,7 @@
1
+
2
+ # Credits
3
+
4
+ The following people have been involved in one way or another with this project.
5
+
6
+ * Devon Bray <dev@esologic.com>
7
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Devon Bray
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
13
+ all 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
21
+ THE SOFTWARE.
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.4
2
+ Name: bonus_click
3
+ Version: 0.0.1
4
+ Summary: Convenience wrappers around helpful click patterns.
5
+ License-File: AUTHORS.md
6
+ License-File: LICENSE.md
7
+ Author: Devon Bray
8
+ Requires-Python: >=3.10,<4.0
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Requires-Dist: click (>=8.3.0,<9.0.0)
16
+ Description-Content-Type: text/markdown
17
+
18
+ # Bonus Click - `bonus_click`
19
+
20
+ ![](./logo.jpeg)
21
+
22
+ Convenience wrappers around helpful [click](https://click.palletsprojects.com/en/stable/) patterns.
23
+
24
+ ## Getting Started
25
+
26
+ ### Python Dependencies
27
+
28
+ Poetry is required to manage Python dependencies. You can install it easily by following the
29
+ operating system specific instructions [here](https://python-poetry.org/docs/#installation).
30
+
31
+ `pyproject.toml` contains dependencies for required Python modules for building, testing, and
32
+ developing. They can all be installed in a [virtual environment](https://docs.python.org/3/library/venv.html)
33
+ using the follow commands:
34
+
35
+ ```
36
+ python3.10 -m venv .venv
37
+ source ./.venv/bin/activate
38
+ poetry install
39
+ ```
40
+
41
+ There's also a bin script to do this, and will install poetry if you don't already have it:
42
+
43
+ ```
44
+ ./tools/create_venv.sh
45
+ ```
46
+
47
+ ## Developer Guide
48
+
49
+ The following is documentation for developers that would like to contribute
50
+ to Bonus Click.
51
+
52
+ ### Testing
53
+
54
+ This project uses pytest to manage and run unit tests. Unit tests located in the `test` directory
55
+ are automatically run during the CI build. You can run them manually with:
56
+
57
+ ```
58
+ ./tools/run_tests.sh
59
+ ```
60
+
61
+ ### Local Linting
62
+
63
+ There are a few linters/code checks included with this project to speed up the development process:
64
+
65
+ * Black - An automatic code formatter, never think about python style again.
66
+ * Isort - Automatically organizes imports in your modules.
67
+ * Pylint - Check your code against many of the python style guide rules.
68
+ * Mypy - Check your code to make sure it is properly typed.
69
+
70
+ You can run these tools automatically in check mode, meaning you will get an error if any of them
71
+ would not pass with:
72
+
73
+ ```
74
+ ./tools/run_checks.sh
75
+ ```
76
+
77
+ Or actually automatically apply the fixes with:
78
+
79
+ ```
80
+ ./tools/apply_linters.sh
81
+ ```
82
+
83
+ There are also scripts in `./tools/` that include run/check for each individual tool.
84
+
85
+
86
+ ### Using pre-commit
87
+
88
+ Upon cloning the repo, to use pre-commit, you'll need to install the hooks with:
89
+
90
+ ```
91
+ pre-commit install --hook-type pre-commit --hook-type pre-push
92
+ ```
93
+
94
+ By default:
95
+
96
+ * black
97
+ * pylint
98
+ * isort
99
+ * mypy
100
+
101
+ Are all run in apply-mode and must pass in order to actually make the commit.
102
+
103
+ Also by default, pytest needs to pass before you can push.
104
+
105
+ If you'd like skip these checks you can commit with:
106
+
107
+ ```
108
+ git commit --no-verify
109
+ ```
110
+
111
+ If you'd like to quickly run these pre-commit checks on all files (not just the staged ones) you
112
+ can run:
113
+
114
+ ```
115
+ pre-commit run --all-files
116
+ ```
117
+
118
+
119
+
@@ -0,0 +1,101 @@
1
+ # Bonus Click - `bonus_click`
2
+
3
+ ![](./logo.jpeg)
4
+
5
+ Convenience wrappers around helpful [click](https://click.palletsprojects.com/en/stable/) patterns.
6
+
7
+ ## Getting Started
8
+
9
+ ### Python Dependencies
10
+
11
+ Poetry is required to manage Python dependencies. You can install it easily by following the
12
+ operating system specific instructions [here](https://python-poetry.org/docs/#installation).
13
+
14
+ `pyproject.toml` contains dependencies for required Python modules for building, testing, and
15
+ developing. They can all be installed in a [virtual environment](https://docs.python.org/3/library/venv.html)
16
+ using the follow commands:
17
+
18
+ ```
19
+ python3.10 -m venv .venv
20
+ source ./.venv/bin/activate
21
+ poetry install
22
+ ```
23
+
24
+ There's also a bin script to do this, and will install poetry if you don't already have it:
25
+
26
+ ```
27
+ ./tools/create_venv.sh
28
+ ```
29
+
30
+ ## Developer Guide
31
+
32
+ The following is documentation for developers that would like to contribute
33
+ to Bonus Click.
34
+
35
+ ### Testing
36
+
37
+ This project uses pytest to manage and run unit tests. Unit tests located in the `test` directory
38
+ are automatically run during the CI build. You can run them manually with:
39
+
40
+ ```
41
+ ./tools/run_tests.sh
42
+ ```
43
+
44
+ ### Local Linting
45
+
46
+ There are a few linters/code checks included with this project to speed up the development process:
47
+
48
+ * Black - An automatic code formatter, never think about python style again.
49
+ * Isort - Automatically organizes imports in your modules.
50
+ * Pylint - Check your code against many of the python style guide rules.
51
+ * Mypy - Check your code to make sure it is properly typed.
52
+
53
+ You can run these tools automatically in check mode, meaning you will get an error if any of them
54
+ would not pass with:
55
+
56
+ ```
57
+ ./tools/run_checks.sh
58
+ ```
59
+
60
+ Or actually automatically apply the fixes with:
61
+
62
+ ```
63
+ ./tools/apply_linters.sh
64
+ ```
65
+
66
+ There are also scripts in `./tools/` that include run/check for each individual tool.
67
+
68
+
69
+ ### Using pre-commit
70
+
71
+ Upon cloning the repo, to use pre-commit, you'll need to install the hooks with:
72
+
73
+ ```
74
+ pre-commit install --hook-type pre-commit --hook-type pre-push
75
+ ```
76
+
77
+ By default:
78
+
79
+ * black
80
+ * pylint
81
+ * isort
82
+ * mypy
83
+
84
+ Are all run in apply-mode and must pass in order to actually make the commit.
85
+
86
+ Also by default, pytest needs to pass before you can push.
87
+
88
+ If you'd like skip these checks you can commit with:
89
+
90
+ ```
91
+ git commit --no-verify
92
+ ```
93
+
94
+ If you'd like to quickly run these pre-commit checks on all files (not just the staged ones) you
95
+ can run:
96
+
97
+ ```
98
+ pre-commit run --all-files
99
+ ```
100
+
101
+
@@ -0,0 +1,6 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """Top-level package for Bonus Click."""
4
+
5
+ __author__ = """Devon Bray"""
6
+ __email__ = "dev@esologic.com"
File without changes
@@ -0,0 +1,85 @@
1
+ """
2
+ Uses enums to define different choices the user can make in your CLI.
3
+ """
4
+
5
+ from enum import Enum
6
+ from typing import Callable, Optional, TypeVar
7
+
8
+ import click
9
+ from click import Context, Parameter
10
+ from click.decorators import FC
11
+
12
+ # A generic type variable for Enum subclasses, essentially any enum subclass.
13
+ E = TypeVar("E", bound=Enum)
14
+ T = TypeVar("T")
15
+
16
+
17
+ def create_enum_option( # pylint: disable=too-many-positional-arguments
18
+ arg_flag: str,
19
+ help_message: str,
20
+ default: E,
21
+ input_enum: type[E],
22
+ lookup_fn: Optional[Callable[[E], T]] = None,
23
+ envvar: Optional[str] = None,
24
+ ) -> Callable[[FC], FC]:
25
+ """
26
+ Creates a Click option for an Enum type. Resulting input can be given as an index or as the
27
+ string value from the enum.
28
+
29
+ :param arg_flag: The argument flag for the Click option (e.g., "--output").
30
+ :param help_message: Will be included in the --help message alongside the acceptable inputs
31
+ to the Enum.
32
+ :param default: The default value for the Click option, must be a member of `input_enum`.
33
+ :param lookup_fn: If given, the resolved value will be passed to this function, then the click
34
+ command will get whatever is returned as an argument.
35
+ :param input_enum: The Enum class from which the option values are derived.
36
+ :param envvar: Passed to the click option.
37
+ :return: A Click option configured for the specified Enum.
38
+ """
39
+
40
+ try:
41
+ input_enum(default)
42
+ except ValueError as e:
43
+ raise ValueError("Default value was not a member of the enum!") from e
44
+
45
+ options_string = "\n".join(
46
+ [f" {idx}: {enum_member.value}" for idx, enum_member in enumerate(input_enum)]
47
+ )
48
+
49
+ help_string = (
50
+ f"\b\n{help_message}\nOptions below. Either provide index or value:\n{options_string}"
51
+ )
52
+
53
+ def callback(_ctx: Context, _param: Parameter, value: str) -> "T | E":
54
+ enum_options = list(input_enum)
55
+ try:
56
+ # Try interpreting as an index
57
+ index = int(value)
58
+ if 0 <= index < len(enum_options):
59
+ return enum_options[index]
60
+ else:
61
+ raise click.BadParameter(
62
+ f"Index out of range. Valid range: 0-{len(enum_options)-1}."
63
+ )
64
+ except ValueError:
65
+ # If not an index, validate as a string
66
+ try:
67
+ resolved: E = input_enum(value)
68
+ return lookup_fn(resolved) if lookup_fn else resolved
69
+ except ValueError as e:
70
+ valid_choices = ", ".join([e.value for e in enum_options])
71
+ raise click.BadParameter(
72
+ "Invalid choice. "
73
+ f"Valid names: {valid_choices}, or indices 0-{len(enum_options)-1}."
74
+ ) from e
75
+
76
+ return click.option(
77
+ arg_flag,
78
+ type=click.STRING,
79
+ callback=callback,
80
+ help=help_string,
81
+ default=default.value, # Ensure we use the string value for the default
82
+ show_default=True,
83
+ envvar=envvar,
84
+ show_envvar=True,
85
+ )
@@ -0,0 +1,9 @@
1
+ """
2
+ Exposes the set of custom click options implemented in the project.
3
+ """
4
+
5
+ # pylint: disable=protected-access
6
+
7
+ from bonus_click._options.enum_option import create_enum_option
8
+
9
+ __all__ = ["create_enum_option"]
File without changes
@@ -0,0 +1,68 @@
1
+ [build-system]
2
+ build-backend = "poetry.core.masonry.api"
3
+ requires = ["poetry-core"]
4
+
5
+ [tool.black]
6
+ line-length = 100
7
+ target-version = ['py310']
8
+
9
+ [tool.isort]
10
+ extra_standard_library = "setuptools,typing_extensions"
11
+ force_grid_wrap = 0
12
+ include_trailing_comma = true
13
+ line_length = 100
14
+ multi_line_output = 3
15
+ skip = ["/home/circleci/repo/venv", "./venv", "./.venv"]
16
+ use_parentheses = true
17
+
18
+ [tool.mypy]
19
+ allow_redefinition = false
20
+ check_untyped_defs = true
21
+ disallow_any_explicit = true
22
+ disallow_any_generics = true
23
+ disallow_incomplete_defs = true
24
+ disallow_subclassing_any = true
25
+ disallow_untyped_calls = true
26
+ disallow_untyped_defs = true
27
+ ignore_missing_imports = true
28
+ mypy_path = ".:test:bonus_click"
29
+ no_implicit_optional = true
30
+ scripts_are_modules = true
31
+ strict_optional = false
32
+ warn_incomplete_stub = true
33
+ warn_redundant_casts = true
34
+ warn_return_any = true
35
+ warn_unused_ignores = true
36
+
37
+ [tool.poetry]
38
+ authors = ["Devon Bray"]
39
+ description = "Convenience wrappers around helpful click patterns."
40
+ name = "bonus_click"
41
+ readme = "README.md"
42
+ version = "0.0.1"
43
+
44
+ [tool.poetry.dependencies]
45
+ python = "^3.10"
46
+ click = "^8.3.0"
47
+
48
+ [tool.poetry.group.dev.dependencies]
49
+ black = "*"
50
+ isort = "*"
51
+ mypy = "*"
52
+ pre-commit = "*"
53
+ pylint = "*"
54
+ pydevd-pycharm = ">=231.8109.197,<231.8110.0"
55
+ wheel = "^0.38"
56
+
57
+ [tool.poetry.group.test.dependencies]
58
+ coverage = "*"
59
+ pytest = "*"
60
+ pytest-cov = "*"
61
+
62
+ [tool.pytest.ini_options]
63
+ addopts = "-rsxX --showlocals --strict-markers"
64
+
65
+ [tool.pytest.ini_options.markers]
66
+ devtest = "temporary development mark that can be used as needed (should not be merged to master)"
67
+ integration = "tests that access outside services (s3, APIs), don't run in CircleCI"
68
+ timeout = "timeout for test in seconds, from `pytest-timeout` module"