lib-cli-exit-tools 2.1.0__tar.gz → 2.2.0__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.
Files changed (89) hide show
  1. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.github/workflows/ci.yml +54 -8
  2. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.github/workflows/codeql.yml +1 -1
  3. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.github/workflows/release.yml +13 -5
  4. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.gitignore +1 -0
  5. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/CHANGELOG.md +24 -0
  6. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/INSTALL.md +1 -1
  7. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/Makefile +7 -1
  8. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/PKG-INFO +18 -16
  9. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/README.md +3 -2
  10. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/pyproject.toml +66 -16
  11. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/_utils.py +310 -89
  12. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/build.py +12 -0
  13. lib_cli_exit_tools-2.2.0/scripts/clean.py +75 -0
  14. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/cli.py +20 -1
  15. lib_cli_exit_tools-2.2.0/scripts/dependencies.py +590 -0
  16. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/menu.py +33 -19
  17. lib_cli_exit_tools-2.2.0/scripts/push.py +309 -0
  18. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/release.py +3 -1
  19. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/target_metadata.py +32 -4
  20. lib_cli_exit_tools-2.2.0/scripts/test.py +1004 -0
  21. lib_cli_exit_tools-2.2.0/scripts/toml_config.py +455 -0
  22. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/__init__conf__.py +8 -1
  23. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/application/runner.py +48 -8
  24. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/cli.py +69 -15
  25. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/core/configuration.py +43 -11
  26. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/core/exit_codes.py +18 -1
  27. lib_cli_exit_tools-2.2.0/tests/conftest.py +110 -0
  28. lib_cli_exit_tools-2.2.0/tests/test_adapters_signals.py +198 -0
  29. lib_cli_exit_tools-2.2.0/tests/test_application_runner.py +476 -0
  30. lib_cli_exit_tools-2.2.0/tests/test_behaviors.py +226 -0
  31. lib_cli_exit_tools-2.2.0/tests/test_cli.py +307 -0
  32. lib_cli_exit_tools-2.2.0/tests/test_core_configuration.py +164 -0
  33. lib_cli_exit_tools-2.2.0/tests/test_core_exit_codes.py +358 -0
  34. lib_cli_exit_tools-2.2.0/tests/test_metadata.py +223 -0
  35. lib_cli_exit_tools-2.2.0/tests/test_module_entry.py +262 -0
  36. lib_cli_exit_tools-2.2.0/tests/test_signals_integration.py +219 -0
  37. lib_cli_exit_tools-2.1.0/scripts/clean.py +0 -48
  38. lib_cli_exit_tools-2.1.0/scripts/push.py +0 -77
  39. lib_cli_exit_tools-2.1.0/scripts/test.py +0 -535
  40. lib_cli_exit_tools-2.1.0/tests/conftest.py +0 -57
  41. lib_cli_exit_tools-2.1.0/tests/test_adapters_signals.py +0 -65
  42. lib_cli_exit_tools-2.1.0/tests/test_application_runner.py +0 -385
  43. lib_cli_exit_tools-2.1.0/tests/test_behaviors.py +0 -99
  44. lib_cli_exit_tools-2.1.0/tests/test_cli.py +0 -164
  45. lib_cli_exit_tools-2.1.0/tests/test_core_configuration.py +0 -47
  46. lib_cli_exit_tools-2.1.0/tests/test_core_exit_codes.py +0 -265
  47. lib_cli_exit_tools-2.1.0/tests/test_metadata.py +0 -47
  48. lib_cli_exit_tools-2.1.0/tests/test_module_entry.py +0 -137
  49. lib_cli_exit_tools-2.1.0/tests/test_signals_integration.py +0 -122
  50. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.codacy/cli-config.yaml +0 -0
  51. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.codacy/cli.sh +0 -0
  52. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.codacy/codacy.yaml +0 -0
  53. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.codacy/tools-configs/lizard.yaml +0 -0
  54. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.codacy/tools-configs/trivy.yaml +0 -0
  55. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.devcontainer/devcontainer.json +0 -0
  56. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.devcontainer/settings.json +0 -0
  57. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.env.example +0 -0
  58. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.github/dependabot.yml +0 -0
  59. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.qlty/qlty.toml +0 -0
  60. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/.snyk +0 -0
  61. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/AGENTS.md +0 -0
  62. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/AGENTS_README.md +0 -0
  63. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/CONTRIBUTING.md +0 -0
  64. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/DEVELOPMENT.md +0 -0
  65. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/LICENSE +0 -0
  66. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/codecov.yml +0 -0
  67. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/docs/system-design/module_reference.md +0 -0
  68. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/notebooks/Quickstart.ipynb +0 -0
  69. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/__init__.py +0 -0
  70. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/__main__.py +0 -0
  71. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/bump.py +0 -0
  72. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/bump_major.py +0 -0
  73. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/bump_minor.py +0 -0
  74. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/bump_patch.py +0 -0
  75. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/bump_version.py +0 -0
  76. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/dev.py +0 -0
  77. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/help.py +0 -0
  78. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/install.py +0 -0
  79. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/run_cli.py +0 -0
  80. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/scripts/version_current.py +0 -0
  81. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/__init__.py +0 -0
  82. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/__main__.py +0 -0
  83. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/adapters/__init__.py +0 -0
  84. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/adapters/signals.py +0 -0
  85. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/application/__init__.py +0 -0
  86. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/core/__init__.py +0 -0
  87. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +0 -0
  88. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/src/lib_cli_exit_tools/py.typed +0 -0
  89. {lib_cli_exit_tools-2.1.0 → lib_cli_exit_tools-2.2.0}/tests/test_scripts.py +0 -0
@@ -5,6 +5,9 @@ on:
5
5
  branches: [ main, master ]
6
6
  pull_request:
7
7
  branches: [ main, master ]
8
+ schedule:
9
+ # Run daily at 3:17 AM UTC (off-peak hours, odd minute to avoid congestion)
10
+ - cron: '17 3 * * *'
8
11
 
9
12
  jobs:
10
13
  test:
@@ -15,19 +18,32 @@ jobs:
15
18
  matrix:
16
19
  os: [ubuntu-latest, macos-latest, windows-latest]
17
20
  # Test against Python 3.13 and the latest 3.x available on Actions runners
18
- python: ["3.13", "3.x"]
21
+ python: ["3.10","3.11","3.12","3.13", "3.x"]
22
+ env:
23
+ PYO3_USE_ABI3_FORWARD_COMPATIBILITY: "1"
24
+ PYTHONIOENCODING: "utf-8"
19
25
  steps:
20
- - uses: actions/checkout@v5
26
+ - uses: actions/checkout@v6
21
27
  - uses: actions/setup-python@v6
22
28
  with:
23
29
  python-version: ${{ matrix.python }}
30
+ cache: 'pip'
31
+ cache-dependency-path: 'pyproject.toml'
32
+ - name: Install uv
33
+ uses: astral-sh/setup-uv@v7
34
+ with:
35
+ enable-cache: true
24
36
  - name: Extract project metadata
25
37
  shell: python
26
38
  run: |
27
39
  import os
28
- import tomllib
29
40
  from pathlib import Path
30
41
 
42
+ try:
43
+ import tomllib
44
+ except ModuleNotFoundError:
45
+ import pip._vendor.tomli as tomllib
46
+
31
47
  data = tomllib.loads(Path('pyproject.toml').read_text('utf-8'))
32
48
  project = data['project']['name']
33
49
  module = project.replace('-', '_')
@@ -45,6 +61,13 @@ jobs:
45
61
  run: |
46
62
  choco install -y make
47
63
  echo "C:\\ProgramData\\chocolatey\\bin" >> $env:GITHUB_PATH
64
+ - name: Install journald prerequisites
65
+ if: runner.os == 'Linux'
66
+ shell: bash
67
+ run: |
68
+ sudo apt-get update
69
+ sudo apt-get install -y python3-systemd
70
+
48
71
  - name: Upgrade pip
49
72
  shell: bash
50
73
  run: python -m pip install --upgrade pip
@@ -52,13 +75,28 @@ jobs:
52
75
  - name: Install dev deps
53
76
  shell: bash
54
77
  run: |
55
- pip install -e .[dev]
78
+ uv pip install -e .[dev] --system
56
79
 
57
80
  - name: Install Windows Event Log prerequisites
58
81
  if: runner.os == 'Windows'
59
82
  shell: bash
60
83
  run: |
61
- pip install pywin32
84
+ uv pip install pywin32 --system
85
+ - name: Cache ruff
86
+ uses: actions/cache@v4
87
+ with:
88
+ path: .ruff_cache
89
+ key: ruff-${{ runner.os }}-${{ github.sha }}
90
+ restore-keys: |
91
+ ruff-${{ runner.os }}-
92
+ - name: Cache pyright
93
+ uses: actions/cache@v4
94
+ with:
95
+ path: .pyright
96
+ key: pyright-${{ runner.os }}-py${{ matrix.python }}-${{ github.sha }}
97
+ restore-keys: |
98
+ pyright-${{ runner.os }}-py${{ matrix.python }}-
99
+ pyright-${{ runner.os }}-
62
100
  - name: Run full test suite (lint, types, tests, coverage, codecov)
63
101
  shell: bash
64
102
  env:
@@ -79,17 +117,23 @@ jobs:
79
117
  name: pipx/uv verification (ubuntu)
80
118
  runs-on: ubuntu-latest
81
119
  steps:
82
- - uses: actions/checkout@v5
120
+ - uses: actions/checkout@v6
83
121
  - uses: actions/setup-python@v6
84
122
  with:
85
123
  python-version: "3.13"
124
+ cache: 'pip'
125
+ cache-dependency-path: 'pyproject.toml'
86
126
  - name: Extract project metadata
87
127
  shell: python
88
128
  run: |
89
129
  import os
90
- import tomllib
91
130
  from pathlib import Path
92
131
 
132
+ try:
133
+ import tomllib
134
+ except ModuleNotFoundError:
135
+ import pip._vendor.tomli as tomllib
136
+
93
137
  data = tomllib.loads(Path('pyproject.toml').read_text('utf-8'))
94
138
  project = data['project']['name']
95
139
  module = project.replace('-', '_')
@@ -123,10 +167,12 @@ jobs:
123
167
  name: Execute notebooks (ubuntu, Python 3.13)
124
168
  runs-on: ubuntu-latest
125
169
  steps:
126
- - uses: actions/checkout@v5
170
+ - uses: actions/checkout@v6
127
171
  - uses: actions/setup-python@v6
128
172
  with:
129
173
  python-version: "3.13"
174
+ cache: 'pip'
175
+ cache-dependency-path: 'pyproject.toml'
130
176
  - name: Install notebook runner deps
131
177
  run: |
132
178
  python -m pip install --upgrade pip
@@ -23,7 +23,7 @@ jobs:
23
23
 
24
24
  steps:
25
25
  - name: Checkout repository
26
- uses: actions/checkout@v5
26
+ uses: actions/checkout@v6
27
27
 
28
28
  - name: Initialize CodeQL
29
29
  uses: github/codeql-action/init@v4
@@ -14,29 +14,37 @@ jobs:
14
14
  permissions:
15
15
  contents: read
16
16
  steps:
17
- - uses: actions/checkout@v5
17
+ - uses: actions/checkout@v6
18
18
  - name: Verify PyPI token is set
19
19
  run: |
20
20
  if [ -z "${{ secrets.PYPI_API_TOKEN }}" ]; then
21
- echo "::error title=Missing PyPI token::Set the PYPI_API_TOKEN secret in GitHub repository settings to enable PyPI publishing on releases."
22
- echo "See: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions"
21
+ echo "::error title=Missing PyPI token::Set the PYPI_API_TOKEN secret in GitHub repository settings to enable PyPI publishing on releases."
22
+ echo "See: https://docs.github.com/en/actions/security-guides/using-secrets-in-github-actions"
23
23
  exit 1
24
24
  fi
25
25
  - uses: actions/setup-python@v6
26
26
  with:
27
27
  python-version: '3.13'
28
+ cache: 'pip'
29
+ cache-dependency-path: 'pyproject.toml'
30
+ - name: Install uv
31
+ uses: astral-sh/setup-uv@v7
32
+ with:
33
+ enable-cache: true
28
34
  - name: Build artifacts
29
35
  run: |
30
- python -m pip install --upgrade pip build
36
+ python -m pip install --upgrade pip
37
+ uv pip install build --system
31
38
  python -m build
32
39
  - name: Publish to PyPI
33
40
  # Use the rolling major tag to get latest Twine/standards support (e.g., Core Metadata 2.4)
34
41
  uses: pypa/gh-action-pypi-publish@release/v1
35
42
  with:
36
43
  password: ${{ secrets.PYPI_API_TOKEN }}
44
+ attestations: false
37
45
  skip-existing: true
38
46
  - name: Upload artifacts
39
- uses: actions/upload-artifact@v4
47
+ uses: actions/upload-artifact@v5
40
48
  with:
41
49
  name: dist
42
50
  path: dist/*
@@ -178,3 +178,4 @@ result
178
178
  poetry.lock
179
179
  pdm.lock
180
180
  uv.lock
181
+ /.github_bak/
@@ -3,6 +3,30 @@
3
3
  All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
4
4
 
5
5
 
6
+ ## [2.2.0] - 2025-12-11
7
+
8
+ ### Changed
9
+ - Lowered minimum Python version from 3.13 to 3.10 for broader compatibility.
10
+ - Updated ruff target-version to py310 to match the new baseline.
11
+
12
+ ### Security
13
+ - Added setuptools vulnerability IDs (PYSEC-2022-43012, CVE-2024-6345, PYSEC-2025-49) to pip-audit ignore list. These are build-time dependencies managed by the CI environment, not runtime dependencies.
14
+
15
+ ## [2.1.1] - 2025-12-08
16
+
17
+ ### Changed
18
+ - Enforced strict data architecture by introducing TypedDict classes (`RichClickSnapshot`, `CliContextState`, `ConfigSnapshot`, `SessionOverrides`) to eliminate raw dictionary access patterns.
19
+ - Added `_is_posix_platform()` helper function to centralise platform detection and avoid string literal comparisons.
20
+ - Replaced assert-based type guards with explicit conditional checks to satisfy Bandit security scanning.
21
+
22
+ ### Refactored
23
+ - Comprehensive test suite refactoring following clean architecture principles:
24
+ - Each test now verifies exactly one behaviour with descriptive naming.
25
+ - Added OS-specific markers (`@pytest.mark.posix_only`, `@pytest.mark.windows_only`, `@pytest.mark.os_agnostic`) for platform-aware test execution.
26
+ - Centralised shared fixtures in `conftest.py` including `cli_runner`, `strip_ansi`, `reset_config`, and `sysexits_mode`.
27
+ - Prefer real behaviour tests over mocks where possible, particularly for signal handling.
28
+ - Organised tests into logical sections with clear header comments.
29
+
6
30
  ## [2.1.0] - 2025-10-13
7
31
 
8
32
  ### Changed
@@ -27,7 +27,7 @@ The sections below cover more specialised workflows, from editable installs to a
27
27
 
28
28
  ## Supported Python Versions
29
29
 
30
- `lib_cli_exit_tools` targets Python 3.13 and newer. Wheels are published for CPython on Linux, macOS, and Windows. For alternative interpreters (PyPy) install from source using `pip install lib_cli_exit_tools`.
30
+ `lib_cli_exit_tools` targets Python 3.10 and newer. Wheels are published for CPython on Linux, macOS, and Windows. For alternative interpreters (PyPy) install from source using `pip install lib_cli_exit_tools`.
31
31
 
32
32
  ## Installation Flows
33
33
 
@@ -3,7 +3,7 @@ SHELL := /bin/bash
3
3
  PYTHON ?= python3
4
4
  SCRIPTS ?= $(PYTHON) -m scripts
5
5
 
6
- .PHONY: help install dev test run clean build push release coverage version-current bump bump-patch bump-minor bump-major menu
6
+ .PHONY: help install dev test run clean build push release coverage version-current bump bump-patch bump-minor bump-major dependencies dependencies-update menu
7
7
 
8
8
  help:
9
9
  $(SCRIPTS) help
@@ -50,5 +50,11 @@ build:
50
50
  release:
51
51
  $(SCRIPTS) release
52
52
 
53
+ dependencies:
54
+ $(SCRIPTS) dependencies
55
+
56
+ dependencies-update:
57
+ $(SCRIPTS) dependencies-update
58
+
53
59
  menu:
54
60
  $(SCRIPTS) menu
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lib_cli_exit_tools
3
- Version: 2.1.0
3
+ Version: 2.2.0
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
@@ -15,22 +15,23 @@ Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python :: 3
16
16
  Classifier: Programming Language :: Python :: 3 :: Only
17
17
  Classifier: Typing :: Typed
18
- Requires-Python: >=3.13
19
- Requires-Dist: rich-click>=1.9.3
18
+ Requires-Python: >=3.10
19
+ Requires-Dist: rich-click>=1.9.4
20
20
  Provides-Extra: dev
21
- Requires-Dist: bandit>=1.8.6; extra == 'dev'
21
+ Requires-Dist: bandit>=1.9.2; extra == 'dev'
22
22
  Requires-Dist: build>=1.3.0; extra == 'dev'
23
- Requires-Dist: codecov-cli>=11.2.3; extra == 'dev'
24
- Requires-Dist: coverage[toml]>=7.10.7; extra == 'dev'
25
- Requires-Dist: hypothesis>=6.140.3; extra == 'dev'
26
- Requires-Dist: import-linter>=2.5.2; extra == 'dev'
27
- Requires-Dist: pip-audit>=2.9.0; extra == 'dev'
28
- Requires-Dist: pyright>=1.1.406; extra == 'dev'
29
- Requires-Dist: pytest-asyncio>=1.2.0; extra == 'dev'
23
+ Requires-Dist: codecov-cli>=11.2.6; extra == 'dev'
24
+ Requires-Dist: coverage[toml]>=7.13.0; extra == 'dev'
25
+ Requires-Dist: hypothesis>=6.148.7; extra == 'dev'
26
+ Requires-Dist: import-linter>=2.8; extra == 'dev'
27
+ Requires-Dist: pip-audit>=2.10.0; extra == 'dev'
28
+ Requires-Dist: pyright>=1.1.407; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=1.3.0; extra == 'dev'
30
30
  Requires-Dist: pytest-cov>=7.0.0; extra == 'dev'
31
- Requires-Dist: pytest>=8.4.2; extra == 'dev'
32
- Requires-Dist: ruff>=0.14.0; extra == 'dev'
33
- Requires-Dist: textual>=6.3.0; extra == 'dev'
31
+ Requires-Dist: pytest>=9.0.2; extra == 'dev'
32
+ Requires-Dist: ruff>=0.14.8; extra == 'dev'
33
+ Requires-Dist: textual>=6.8.0; extra == 'dev'
34
+ Requires-Dist: tomli>=2.3.0; (python_version < '3.11') and extra == 'dev'
34
35
  Requires-Dist: twine>=6.2.0; extra == 'dev'
35
36
  Description-Content-Type: text/markdown
36
37
 
@@ -47,6 +48,7 @@ Description-Content-Type: text/markdown
47
48
  [![codecov](https://codecov.io/gh/bitranox/lib_cli_exit_tools/graph/badge.svg?token=z1D8JSjWEH)](https://codecov.io/gh/bitranox/lib_cli_exit_tools)
48
49
  [![Maintainability](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools/maintainability.svg)](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools)
49
50
  [![Known Vulnerabilities](https://snyk.io/test/github/bitranox/lib_cli_exit_tools/badge.svg)](https://snyk.io/test/github/bitranox/lib_cli_exit_tools)
51
+ [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
50
52
 
51
53
  Small helpers for robust CLI exit handling:
52
54
  - Portable signal handling (SIGINT, SIGTERM/SIGBREAK)
@@ -55,7 +57,7 @@ Small helpers for robust CLI exit handling:
55
57
 
56
58
  ## Install
57
59
 
58
- Requires Python 3.13 or newer.
60
+ Requires Python 3.10 or newer.
59
61
 
60
62
  ```bash
61
63
  pip install lib_cli_exit_tools
@@ -581,7 +583,7 @@ When installed, the generated console scripts (`lib-cli-exit-tools`, `cli-exit-t
581
583
 
582
584
  ## Modern Python Toolchain
583
585
 
584
- - Targets Python 3.13+ exclusively—no runtime shims or compatibility branches remain.
586
+ - Targets Python 3.10+ for modern language features and broad compatibility.
585
587
  - Development extras track the latest stable releases published on PyPI so quality gates match local and CI environments.
586
588
  - GitHub Actions workflows rely on the current major releases of `actions/checkout`, `actions/setup-python`, and `astral-sh/setup-uv`, aligning the automation stack with the 2025 runner images.
587
589
 
@@ -11,6 +11,7 @@
11
11
  [![codecov](https://codecov.io/gh/bitranox/lib_cli_exit_tools/graph/badge.svg?token=z1D8JSjWEH)](https://codecov.io/gh/bitranox/lib_cli_exit_tools)
12
12
  [![Maintainability](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools/maintainability.svg)](https://qlty.sh/gh/bitranox/projects/lib_cli_exit_tools)
13
13
  [![Known Vulnerabilities](https://snyk.io/test/github/bitranox/lib_cli_exit_tools/badge.svg)](https://snyk.io/test/github/bitranox/lib_cli_exit_tools)
14
+ [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit)
14
15
 
15
16
  Small helpers for robust CLI exit handling:
16
17
  - Portable signal handling (SIGINT, SIGTERM/SIGBREAK)
@@ -19,7 +20,7 @@ Small helpers for robust CLI exit handling:
19
20
 
20
21
  ## Install
21
22
 
22
- Requires Python 3.13 or newer.
23
+ Requires Python 3.10 or newer.
23
24
 
24
25
  ```bash
25
26
  pip install lib_cli_exit_tools
@@ -545,7 +546,7 @@ When installed, the generated console scripts (`lib-cli-exit-tools`, `cli-exit-t
545
546
 
546
547
  ## Modern Python Toolchain
547
548
 
548
- - Targets Python 3.13+ exclusively—no runtime shims or compatibility branches remain.
549
+ - Targets Python 3.10+ for modern language features and broad compatibility.
549
550
  - Development extras track the latest stable releases published on PyPI so quality gates match local and CI environments.
550
551
  - GitHub Actions workflows rely on the current major releases of `actions/checkout`, `actions/setup-python`, and `astral-sh/setup-uv`, aligning the automation stack with the 2025 runner images.
551
552
 
@@ -1,10 +1,10 @@
1
1
  [project]
2
2
  name = "lib_cli_exit_tools"
3
- version = "2.1.0"
3
+ version = "2.2.0"
4
4
  description = "CLI exit handling helpers: clean signals, exit codes, and error printing"
5
5
  readme = "README.md"
6
- requires-python = ">=3.13"
7
- dependencies = ["rich-click>=1.9.3"]
6
+ requires-python = ">=3.10"
7
+ dependencies = ["rich-click>=1.9.4"]
8
8
  license = { text = "MIT" }
9
9
  authors = [{ name = "bitranox", email = "bitranox@gmail.com" }]
10
10
  keywords = ["cli", "exit", "signals", "errors", "click"]
@@ -25,18 +25,19 @@ Issues = "https://github.com/bitranox/lib_cli_exit_tools/issues"
25
25
  [project.optional-dependencies]
26
26
  dev = [
27
27
  "build>=1.3.0",
28
- "codecov-cli>=11.2.3",
29
- "coverage[toml]>=7.10.7",
30
- "hypothesis>=6.140.3",
31
- "import-linter>=2.5.2",
32
- "bandit>=1.8.6",
33
- "pip-audit>=2.9.0",
34
- "pyright>=1.1.406",
35
- "pytest>=8.4.2",
36
- "pytest-asyncio>=1.2.0",
28
+ "codecov-cli>=11.2.6",
29
+ "coverage[toml]>=7.13.0",
30
+ "hypothesis>=6.148.7",
31
+ "import-linter>=2.8",
32
+ "bandit>=1.9.2",
33
+ "pip-audit>=2.10.0",
34
+ "pyright>=1.1.407",
35
+ "pytest>=9.0.2",
36
+ "pytest-asyncio>=1.3.0",
37
37
  "pytest-cov>=7.0.0",
38
- "ruff>=0.14.0",
39
- "textual>=6.3.0",
38
+ "ruff>=0.14.8",
39
+ "textual>=6.8.0",
40
+ "tomli>=2.3.0;python_version<'3.11'",
40
41
  "twine>=6.2.0"
41
42
  ]
42
43
 
@@ -47,7 +48,7 @@ cli-exit-tools = "lib_cli_exit_tools.cli:main"
47
48
  lib-cli-exit-tools = "lib_cli_exit_tools.cli:main"
48
49
 
49
50
  [build-system]
50
- requires = ["hatchling>=1.27.0"]
51
+ requires = ["hatchling>=1.28.0"]
51
52
  build-backend = "hatchling.build"
52
53
 
53
54
  [tool.hatch.build.targets.wheel]
@@ -56,7 +57,7 @@ include = ["src/lib_cli_exit_tools/py.typed"]
56
57
 
57
58
  [tool.ruff]
58
59
  line-length = 160
59
- target-version = "py313"
60
+ target-version = "py310"
60
61
 
61
62
  [tool.ruff.lint.per-file-ignores]
62
63
  # ignore the "unused import sys" in the jupyter notebook - which we need (it is a linter hickup)
@@ -70,6 +71,7 @@ exclude = [
70
71
 
71
72
  [tool.pytest.ini_options]
72
73
  addopts = ["--doctest-modules"]
74
+ pythonpath = ["src"]
73
75
  doctest_optionflags = ["ELLIPSIS", "NORMALIZE_WHITESPACE"]
74
76
  markers = [
75
77
  "os_agnostic: test exercises behavior that is the same on every operating system",
@@ -91,6 +93,39 @@ omit = [
91
93
  fail_under = 85
92
94
  show_missing = true
93
95
 
96
+ [tool.clean]
97
+ # Patterns to remove when running `make clean` or `python -m scripts clean`
98
+ patterns = [
99
+ ".hypothesis",
100
+ ".import_linter_cache",
101
+ ".pytest_cache",
102
+ ".ruff_cache",
103
+ ".pyright",
104
+ ".mypy_cache",
105
+ ".tox",
106
+ ".nox",
107
+ ".eggs",
108
+ "*.egg-info",
109
+ "build",
110
+ "dist",
111
+ "htmlcov",
112
+ ".coverage",
113
+ "coverage.xml",
114
+ "codecov.sh",
115
+ ".cache",
116
+ "result",
117
+ ]
118
+
119
+ [tool.git]
120
+ # Default git remote for push/release commands
121
+ default-remote = "origin"
122
+
123
+
124
+ [tool.scripts.test]
125
+ # Configuration for scripts/test.py test runner
126
+ pytest-verbosity = "-vv"
127
+ coverage-report-file = "coverage.xml"
128
+ src-path = "src"
94
129
  [tool.importlinter]
95
130
  root_package = "lib_cli_exit_tools"
96
131
 
@@ -116,3 +151,18 @@ source_modules = [
116
151
  forbidden_modules = [
117
152
  "lib_cli_exit_tools.cli",
118
153
  ]
154
+
155
+ [tool.pip-audit]
156
+ # Known vulnerabilities to ignore (unfixable or accepted risk)
157
+ # GHSA-4xh5-x5gv-qwph: py library ReDoS (no fix available, low risk)
158
+ # PYSEC-2022-42969: same as above (alias)
159
+ # PYSEC-2022-43012, CVE-2024-6345, PYSEC-2025-49: setuptools vulnerabilities
160
+ # These are build-time dependencies only, not runtime. The virtual environment
161
+ # setuptools version is managed by the CI environment/pip itself.
162
+ ignore-vulns = [
163
+ "GHSA-4xh5-x5gv-qwph",
164
+ "PYSEC-2022-42969",
165
+ "PYSEC-2022-43012",
166
+ "CVE-2024-6345",
167
+ "PYSEC-2025-49",
168
+ ]