lib-cli-exit-tools 2.2.2__py3-none-any.whl → 2.2.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.
- lib_cli_exit_tools/__init__conf__.py +1 -1
- {lib_cli_exit_tools-2.2.2.dist-info → lib_cli_exit_tools-2.2.4.dist-info}/METADATA +49 -42
- {lib_cli_exit_tools-2.2.2.dist-info → lib_cli_exit_tools-2.2.4.dist-info}/RECORD +6 -6
- {lib_cli_exit_tools-2.2.2.dist-info → lib_cli_exit_tools-2.2.4.dist-info}/WHEEL +0 -0
- {lib_cli_exit_tools-2.2.2.dist-info → lib_cli_exit_tools-2.2.4.dist-info}/entry_points.txt +0 -0
- {lib_cli_exit_tools-2.2.2.dist-info → lib_cli_exit_tools-2.2.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -24,7 +24,7 @@ name = "lib_cli_exit_tools"
|
|
|
24
24
|
#: Human-readable summary shown in CLI help output.
|
|
25
25
|
title = "CLI exit handling helpers: clean signals, exit codes, and error printing"
|
|
26
26
|
#: Current release version pulled from ``pyproject.toml`` by automation.
|
|
27
|
-
version = "2.2.
|
|
27
|
+
version = "2.2.4"
|
|
28
28
|
#: Repository homepage presented to users.
|
|
29
29
|
homepage = "https://github.com/bitranox/lib_cli_exit_tools"
|
|
30
30
|
#: Author attribution surfaced in CLI output.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lib_cli_exit_tools
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
4
4
|
Summary: CLI exit handling helpers: clean signals, exit codes, and error printing
|
|
5
5
|
Project-URL: Homepage, https://github.com/bitranox/lib_cli_exit_tools
|
|
6
6
|
Project-URL: Repository, https://github.com/bitranox/lib_cli_exit_tools.git
|
|
@@ -16,29 +16,29 @@ Classifier: Programming Language :: Python :: 3
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
17
|
Classifier: Typing :: Typed
|
|
18
18
|
Requires-Python: >=3.10
|
|
19
|
-
Requires-Dist: rich-click>=1.9.
|
|
19
|
+
Requires-Dist: rich-click>=1.9.6
|
|
20
20
|
Provides-Extra: dev
|
|
21
|
-
Requires-Dist: bandit>=1.9.
|
|
22
|
-
Requires-Dist: build>=1.
|
|
21
|
+
Requires-Dist: bandit>=1.9.3; extra == 'dev'
|
|
22
|
+
Requires-Dist: build>=1.4.0; extra == 'dev'
|
|
23
23
|
Requires-Dist: codecov-cli>=11.2.6; extra == 'dev'
|
|
24
|
-
Requires-Dist: coverage[toml]>=7.13.
|
|
25
|
-
Requires-Dist: hypothesis>=6.
|
|
24
|
+
Requires-Dist: coverage[toml]>=7.13.2; extra == 'dev'
|
|
25
|
+
Requires-Dist: hypothesis>=6.151.2; extra == 'dev'
|
|
26
26
|
Requires-Dist: import-linter>=2.9; extra == 'dev'
|
|
27
27
|
Requires-Dist: pip-audit>=2.10.0; extra == 'dev'
|
|
28
|
-
Requires-Dist: pyright>=1.1.
|
|
28
|
+
Requires-Dist: pyright[nodejs]>=1.1.408; extra == 'dev'
|
|
29
29
|
Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
|
|
30
30
|
Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
|
|
31
31
|
Requires-Dist: pytest>=9.0.2; extra == 'dev'
|
|
32
32
|
Requires-Dist: rtoml>=0.13.0; extra == 'dev'
|
|
33
|
-
Requires-Dist: ruff>=0.14.
|
|
34
|
-
Requires-Dist: textual>=
|
|
33
|
+
Requires-Dist: ruff>=0.14.14; extra == 'dev'
|
|
34
|
+
Requires-Dist: textual>=7.4.0; extra == 'dev'
|
|
35
35
|
Requires-Dist: twine>=6.2.0; extra == 'dev'
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
|
|
38
38
|
# lib_cli_exit_tools
|
|
39
39
|
|
|
40
40
|
<!-- Badges -->
|
|
41
|
-
[](https://github.com/bitranox/lib_cli_exit_tools/actions/workflows/default_cicd_public.yml)
|
|
42
42
|
[](https://github.com/bitranox/lib_cli_exit_tools/actions/workflows/codeql.yml)
|
|
43
43
|
[](LICENSE)
|
|
44
44
|
[](https://codespaces.new/bitranox/lib_cli_exit_tools?quickstart=1)
|
|
@@ -130,7 +130,7 @@ CLI that demonstrates configuration hooks and structured error handling.
|
|
|
130
130
|
```python
|
|
131
131
|
from __future__ import annotations
|
|
132
132
|
|
|
133
|
-
import click
|
|
133
|
+
import rich_click as click
|
|
134
134
|
|
|
135
135
|
from lib_cli_exit_tools import run_cli
|
|
136
136
|
|
|
@@ -138,7 +138,6 @@ from lib_cli_exit_tools import run_cli
|
|
|
138
138
|
@click.command()
|
|
139
139
|
def hello() -> None:
|
|
140
140
|
"""Say hello with automatic signal-aware exit handling."""
|
|
141
|
-
|
|
142
141
|
click.echo("Hello from lib_cli_exit_tools!")
|
|
143
142
|
|
|
144
143
|
|
|
@@ -157,29 +156,32 @@ python hello.py
|
|
|
157
156
|
```python
|
|
158
157
|
from __future__ import annotations
|
|
159
158
|
|
|
160
|
-
import click
|
|
161
|
-
|
|
162
|
-
from lib_cli_exit_tools import cli_session, run_cli
|
|
163
|
-
|
|
159
|
+
import rich_click as click
|
|
164
160
|
|
|
165
|
-
|
|
166
|
-
@click.option("--traceback", is_flag=True, help="Show full tracebacks on error")
|
|
167
|
-
def cli(traceback: bool) -> int:
|
|
168
|
-
with cli_session(overrides={"traceback": traceback}) as execute:
|
|
169
|
-
return execute(failable, argv=[])
|
|
161
|
+
from lib_cli_exit_tools import cli_session
|
|
170
162
|
|
|
171
163
|
|
|
172
164
|
@click.command()
|
|
173
165
|
def failable() -> None:
|
|
166
|
+
"""Command that always fails to demonstrate traceback handling."""
|
|
174
167
|
raise RuntimeError("toggle --traceback to see the full traceback")
|
|
175
168
|
|
|
176
169
|
|
|
170
|
+
def main(*, traceback: bool = False) -> int:
|
|
171
|
+
"""Run failable with optional traceback display."""
|
|
172
|
+
with cli_session(overrides={"traceback": traceback}) as run:
|
|
173
|
+
return run(failable)
|
|
174
|
+
|
|
175
|
+
|
|
177
176
|
if __name__ == "__main__":
|
|
178
|
-
|
|
177
|
+
import sys
|
|
178
|
+
|
|
179
|
+
enable_traceback = "--traceback" in sys.argv
|
|
180
|
+
raise SystemExit(main(traceback=enable_traceback))
|
|
179
181
|
```
|
|
180
182
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
+
Running `python cli.py --traceback` enables coloured tracebacks for that
|
|
184
|
+
session. The `cli_session` context manager restores configuration afterwards.
|
|
183
185
|
|
|
184
186
|
#### 3. Full-featured multi-command CLI
|
|
185
187
|
|
|
@@ -187,9 +189,10 @@ run and resets the configuration afterwards.
|
|
|
187
189
|
from __future__ import annotations
|
|
188
190
|
|
|
189
191
|
import json
|
|
192
|
+
import sys
|
|
190
193
|
from dataclasses import dataclass
|
|
191
194
|
|
|
192
|
-
import click
|
|
195
|
+
import rich_click as click
|
|
193
196
|
|
|
194
197
|
from lib_cli_exit_tools import SignalSpec, cli_session, default_signal_specs
|
|
195
198
|
|
|
@@ -197,21 +200,19 @@ from lib_cli_exit_tools import SignalSpec, cli_session, default_signal_specs
|
|
|
197
200
|
@dataclass(slots=True)
|
|
198
201
|
class Settings:
|
|
199
202
|
pretty: bool
|
|
200
|
-
traceback: bool
|
|
201
203
|
|
|
202
204
|
|
|
203
205
|
@click.group()
|
|
204
206
|
@click.option("--pretty/--no-pretty", default=True)
|
|
205
|
-
@click.option("--traceback", is_flag=True, help="Show full tracebacks on error")
|
|
206
207
|
@click.pass_context
|
|
207
|
-
def cli(ctx: click.Context, pretty: bool
|
|
208
|
-
ctx.obj = Settings(pretty=pretty
|
|
208
|
+
def cli(ctx: click.Context, pretty: bool) -> None:
|
|
209
|
+
ctx.obj = Settings(pretty=pretty)
|
|
209
210
|
|
|
210
211
|
|
|
211
212
|
@cli.command()
|
|
212
213
|
@click.pass_obj
|
|
213
214
|
def info(settings: Settings) -> None:
|
|
214
|
-
payload = {"
|
|
215
|
+
payload = {"pretty": settings.pretty}
|
|
215
216
|
click.echo(json.dumps(payload, indent=2 if settings.pretty else None))
|
|
216
217
|
|
|
217
218
|
|
|
@@ -223,20 +224,24 @@ def fail(settings: Settings) -> None:
|
|
|
223
224
|
|
|
224
225
|
|
|
225
226
|
def main() -> int:
|
|
226
|
-
|
|
227
|
+
# Parse --traceback early before entering cli_session
|
|
228
|
+
traceback = "--traceback" in sys.argv
|
|
229
|
+
argv = [arg for arg in sys.argv[1:] if arg != "--traceback"]
|
|
230
|
+
|
|
231
|
+
overrides = {"traceback": traceback, "traceback_force_color": traceback}
|
|
227
232
|
signals: list[SignalSpec] = default_signal_specs()
|
|
228
233
|
with cli_session(overrides=overrides) as execute:
|
|
229
|
-
return execute(cli, signal_specs=signals)
|
|
234
|
+
return execute(cli, argv=argv, signal_specs=signals)
|
|
230
235
|
|
|
231
236
|
|
|
232
237
|
if __name__ == "__main__":
|
|
233
238
|
raise SystemExit(main())
|
|
234
239
|
```
|
|
235
240
|
|
|
236
|
-
This version
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
`lib_cli_exit_tools`.
|
|
241
|
+
This version parses `--traceback` early (before Click sees it), then wires
|
|
242
|
+
configuration overrides, custom signal specs, and multiple commands into a
|
|
243
|
+
single composition point—mirroring how a production CLI can layer policy logic
|
|
244
|
+
around Click while still delegating exit-code translation to `lib_cli_exit_tools`.
|
|
240
245
|
|
|
241
246
|
#### 4. Custom signal handlers
|
|
242
247
|
|
|
@@ -251,7 +256,7 @@ import signal
|
|
|
251
256
|
from contextlib import ExitStack
|
|
252
257
|
from typing import Callable
|
|
253
258
|
|
|
254
|
-
import click
|
|
259
|
+
import rich_click as click
|
|
255
260
|
|
|
256
261
|
from lib_cli_exit_tools import SignalSpec, default_signal_specs, run_cli
|
|
257
262
|
|
|
@@ -271,6 +276,8 @@ def custom_signal_specs() -> list[SignalSpec]:
|
|
|
271
276
|
)
|
|
272
277
|
)
|
|
273
278
|
return specs
|
|
279
|
+
|
|
280
|
+
|
|
274
281
|
def install_custom_signals(specs: list[SignalSpec] | None) -> Callable[[], None]:
|
|
275
282
|
stack = ExitStack()
|
|
276
283
|
|
|
@@ -478,11 +485,11 @@ Compute a platform-aware exit status for arbitrary exceptions (errno mappings on
|
|
|
478
485
|
Parameters:
|
|
479
486
|
- `exc`: Exception instance to classify.
|
|
480
487
|
|
|
481
|
-
### `print_exception_message(trace_back=
|
|
488
|
+
### `print_exception_message(trace_back=None, length_limit=500, stream=None) -> None`
|
|
482
489
|
Emit the active exception using Rich formatting. Produces a coloured traceback when `trace_back` is `True`, otherwise prints a truncated summary in red. Respects `config.traceback_force_color` and mirrors the behaviour of `handle_cli_exception` (tracebacks are rendered before the helper returns an exit status).
|
|
483
490
|
|
|
484
491
|
Parameters:
|
|
485
|
-
- `trace_back`: Toggle between full traceback rendering (`True`) and short summary (`False`).
|
|
492
|
+
- `trace_back`: Toggle between full traceback rendering (`True`) and short summary (`False`). When `None` (default), uses `config.traceback`.
|
|
486
493
|
- `length_limit`: Maximum characters for summary output.
|
|
487
494
|
- `stream`: Target text stream; defaults to `sys.stderr`.
|
|
488
495
|
|
|
@@ -557,7 +564,8 @@ from __future__ import annotations
|
|
|
557
564
|
|
|
558
565
|
from typing import Sequence
|
|
559
566
|
|
|
560
|
-
import click
|
|
567
|
+
import rich_click as click
|
|
568
|
+
|
|
561
569
|
import lib_cli_exit_tools
|
|
562
570
|
|
|
563
571
|
from . import __init__conf__
|
|
@@ -614,7 +622,7 @@ def main(argv: Sequence[str] | None = None) -> int:
|
|
|
614
622
|
)
|
|
615
623
|
```
|
|
616
624
|
|
|
617
|
-
When installed,
|
|
625
|
+
When installed, your package's console scripts (defined in `pyproject.toml`) will import `your_package.cli:main`, and `python -m your_package` will follow the same code path via `__main__.py`.
|
|
618
626
|
|
|
619
627
|
## Exit Codes
|
|
620
628
|
|
|
@@ -643,5 +651,4 @@ When installed, the generated console scripts (`lib-cli-exit-tools`, `cli-exit-t
|
|
|
643
651
|
- [CONTRIBUTING](CONTRIBUTING.md)
|
|
644
652
|
- [DEVELOPMENT](DEVELOPMENT.md)
|
|
645
653
|
- [MODULE REFERENCE](docs/system-design/module_reference.md)
|
|
646
|
-
- [AGENTS_README](AGENTS_README.md)
|
|
647
654
|
- [LICENSE](LICENSE)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
lib_cli_exit_tools/__init__.py,sha256=Z-VXcrmjZCgJZ8NW0UCVIc0HBOsjQicCbzgHj7r22eA,1867
|
|
2
|
-
lib_cli_exit_tools/__init__conf__.py,sha256=
|
|
2
|
+
lib_cli_exit_tools/__init__conf__.py,sha256=8b5wcSJwywaIvuqYoosuL3G0mpUqQ8kuVjpp67wdON4,2521
|
|
3
3
|
lib_cli_exit_tools/__main__.py,sha256=wODJaNu_NyO7tknvlpPArq0MaDwDum8zqyb73-qshzo,257
|
|
4
4
|
lib_cli_exit_tools/cli.py,sha256=k7LC08nVfse4i9RbsOGKTc9y-rrVbR1nOSKiwBvNxrE,9322
|
|
5
5
|
lib_cli_exit_tools/lib_cli_exit_tools.py,sha256=-_kjKGiWyMQ715KxOqrS6uA57SXOgJmMeowU7AmtC8A,2525
|
|
@@ -11,8 +11,8 @@ lib_cli_exit_tools/application/runner.py,sha256=AlCWX5o4VTRzsCom9EgnEK0iVCIZwyId
|
|
|
11
11
|
lib_cli_exit_tools/core/__init__.py,sha256=aR7OIBWOQ1PsA33blOTgLrq5ffKDCuaMVBS5mbrDAZ8,531
|
|
12
12
|
lib_cli_exit_tools/core/configuration.py,sha256=Ro6R2cmOIFhdOUogjK1VOxEJInx24Wgme0t-ucYJGEg,5658
|
|
13
13
|
lib_cli_exit_tools/core/exit_codes.py,sha256=nqx-e6h-ji-FiECPnDV8b0yrjcLPJyU-3xf4zhfRCBE,12322
|
|
14
|
-
lib_cli_exit_tools-2.2.
|
|
15
|
-
lib_cli_exit_tools-2.2.
|
|
16
|
-
lib_cli_exit_tools-2.2.
|
|
17
|
-
lib_cli_exit_tools-2.2.
|
|
18
|
-
lib_cli_exit_tools-2.2.
|
|
14
|
+
lib_cli_exit_tools-2.2.4.dist-info/METADATA,sha256=RzJ0PBuOrRXwpWqnJkyjrd-mNlHxqi6jL2Nro9q2zoc,26234
|
|
15
|
+
lib_cli_exit_tools-2.2.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
16
|
+
lib_cli_exit_tools-2.2.4.dist-info/entry_points.txt,sha256=8R-_3UT0KcQ7HQ7idDx6rlG77GhHb0E2N5QnN41dj-M,161
|
|
17
|
+
lib_cli_exit_tools-2.2.4.dist-info/licenses/LICENSE,sha256=6s9SL2InRrwynPjJYiER7ONHBshbGj_yC5EBzfo7l9I,1072
|
|
18
|
+
lib_cli_exit_tools-2.2.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|