lib-cli-exit-tools 2.2.1__tar.gz → 2.2.2__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 (76) hide show
  1. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.github/workflows/ci.yml +10 -10
  2. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/CHANGELOG.md +5 -0
  3. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/PKG-INFO +3 -3
  4. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/pyproject.toml +3 -3
  5. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/_utils.py +4 -38
  6. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/toml_config.py +3 -25
  7. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/__init__conf__.py +1 -1
  8. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_metadata.py +3 -9
  9. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.codacy/cli-config.yaml +0 -0
  10. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.codacy/cli.sh +0 -0
  11. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.codacy/codacy.yaml +0 -0
  12. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.codacy/tools-configs/lizard.yaml +0 -0
  13. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.codacy/tools-configs/trivy.yaml +0 -0
  14. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.devcontainer/devcontainer.json +0 -0
  15. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.devcontainer/settings.json +0 -0
  16. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.env.example +0 -0
  17. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.github/dependabot.yml +0 -0
  18. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.github/workflows/codeql.yml +0 -0
  19. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.github/workflows/release.yml +0 -0
  20. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.gitignore +0 -0
  21. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.qlty/qlty.toml +0 -0
  22. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/.snyk +0 -0
  23. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/AGENTS.md +0 -0
  24. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/AGENTS_README.md +0 -0
  25. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/CONTRIBUTING.md +0 -0
  26. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/DEVELOPMENT.md +0 -0
  27. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/INSTALL.md +0 -0
  28. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/LICENSE +0 -0
  29. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/Makefile +0 -0
  30. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/README.md +0 -0
  31. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/codecov.yml +0 -0
  32. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/docs/system-design/module_reference.md +0 -0
  33. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/notebooks/Quickstart.ipynb +0 -0
  34. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/__init__.py +0 -0
  35. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/__main__.py +0 -0
  36. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/build.py +0 -0
  37. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/bump.py +0 -0
  38. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/bump_major.py +0 -0
  39. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/bump_minor.py +0 -0
  40. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/bump_patch.py +0 -0
  41. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/bump_version.py +0 -0
  42. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/clean.py +0 -0
  43. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/cli.py +0 -0
  44. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/dependencies.py +0 -0
  45. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/dev.py +0 -0
  46. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/help.py +0 -0
  47. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/install.py +0 -0
  48. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/menu.py +0 -0
  49. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/push.py +0 -0
  50. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/release.py +0 -0
  51. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/run_cli.py +0 -0
  52. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/target_metadata.py +0 -0
  53. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/test.py +0 -0
  54. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/scripts/version_current.py +0 -0
  55. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/__init__.py +0 -0
  56. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/__main__.py +0 -0
  57. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/adapters/__init__.py +0 -0
  58. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/adapters/signals.py +0 -0
  59. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/application/__init__.py +0 -0
  60. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/application/runner.py +0 -0
  61. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/cli.py +0 -0
  62. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/core/__init__.py +0 -0
  63. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/core/configuration.py +0 -0
  64. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/core/exit_codes.py +0 -0
  65. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/lib_cli_exit_tools.py +0 -0
  66. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/src/lib_cli_exit_tools/py.typed +0 -0
  67. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/conftest.py +0 -0
  68. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_adapters_signals.py +0 -0
  69. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_application_runner.py +0 -0
  70. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_behaviors.py +0 -0
  71. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_cli.py +0 -0
  72. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_core_configuration.py +0 -0
  73. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_core_exit_codes.py +0 -0
  74. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_module_entry.py +0 -0
  75. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_scripts.py +0 -0
  76. {lib_cli_exit_tools-2.2.1 → lib_cli_exit_tools-2.2.2}/tests/test_signals_integration.py +0 -0
@@ -33,18 +33,18 @@ jobs:
33
33
  uses: astral-sh/setup-uv@v7
34
34
  with:
35
35
  enable-cache: true
36
+ - name: Install rtoml
37
+ shell: bash
38
+ run: python -m pip install rtoml
36
39
  - name: Extract project metadata
37
40
  shell: python
38
41
  run: |
39
42
  import os
40
43
  from pathlib import Path
41
44
 
42
- try:
43
- import tomllib
44
- except ModuleNotFoundError:
45
- import pip._vendor.tomli as tomllib
45
+ import rtoml
46
46
 
47
- data = tomllib.loads(Path('pyproject.toml').read_text('utf-8'))
47
+ data = rtoml.loads(Path('pyproject.toml').read_text('utf-8'))
48
48
  project = data['project']['name']
49
49
  module = project.replace('-', '_')
50
50
  dash = project.replace('_', '-')
@@ -123,18 +123,18 @@ jobs:
123
123
  python-version: "3.13"
124
124
  cache: 'pip'
125
125
  cache-dependency-path: 'pyproject.toml'
126
+ - name: Install rtoml
127
+ shell: bash
128
+ run: python -m pip install rtoml
126
129
  - name: Extract project metadata
127
130
  shell: python
128
131
  run: |
129
132
  import os
130
133
  from pathlib import Path
131
134
 
132
- try:
133
- import tomllib
134
- except ModuleNotFoundError:
135
- import pip._vendor.tomli as tomllib
135
+ import rtoml
136
136
 
137
- data = tomllib.loads(Path('pyproject.toml').read_text('utf-8'))
137
+ data = rtoml.loads(Path('pyproject.toml').read_text('utf-8'))
138
138
  project = data['project']['name']
139
139
  module = project.replace('-', '_')
140
140
  dash = project.replace('_', '-')
@@ -3,6 +3,11 @@
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.2] - 2025-12-12
7
+
8
+ ### Changed
9
+ - Replaced `tomllib`/`tomli` with `rtoml` for TOML parsing across the entire codebase and CI/CD pipelines. This provides a single, fast Rust-based implementation without version-conditional imports.
10
+
6
11
  ## [2.2.1] - 2025-12-11
7
12
 
8
13
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lib_cli_exit_tools
3
- Version: 2.2.1
3
+ Version: 2.2.2
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
@@ -29,9 +29,9 @@ Requires-Dist: pyright>=1.1.407; 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
- Requires-Dist: ruff>=0.14.8; extra == 'dev'
32
+ Requires-Dist: rtoml>=0.13.0; extra == 'dev'
33
+ Requires-Dist: ruff>=0.14.9; extra == 'dev'
33
34
  Requires-Dist: textual>=6.8.0; extra == 'dev'
34
- Requires-Dist: tomli>=2.3.0; (python_version < '3.11') and extra == 'dev'
35
35
  Requires-Dist: twine>=6.2.0; extra == 'dev'
36
36
  Description-Content-Type: text/markdown
37
37
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "lib_cli_exit_tools"
3
- version = "2.2.1"
3
+ version = "2.2.2"
4
4
  description = "CLI exit handling helpers: clean signals, exit codes, and error printing"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -35,9 +35,9 @@ dev = [
35
35
  "pytest>=9.0.2",
36
36
  "pytest-asyncio>=1.3.0",
37
37
  "pytest-cov>=7.0.0",
38
- "ruff>=0.14.8",
38
+ "ruff>=0.14.9",
39
39
  "textual>=6.8.0",
40
- "tomli>=2.3.0;python_version<'3.11'",
40
+ "rtoml>=0.13.0",
41
41
  "twine>=6.2.0"
42
42
  ]
43
43
 
@@ -35,6 +35,8 @@ from subprocess import CompletedProcess
35
35
  from typing import Any, Mapping, Sequence, cast
36
36
  from urllib.parse import urlparse
37
37
 
38
+ import rtoml
39
+
38
40
 
39
41
  @dataclass
40
42
  class RunResult:
@@ -118,41 +120,6 @@ class ProjectMetadata:
118
120
 
119
121
  _PYPROJECT_DATA_CACHE: dict[Path, dict[str, object]] = {}
120
122
  _METADATA_CACHE: dict[Path, ProjectMetadata] = {}
121
- _toml_module: Any = None
122
-
123
-
124
- def _get_toml_module() -> Any:
125
- """Return tomllib (Python 3.11+) or tomli backport (Python 3.9-3.10).
126
-
127
- Purpose
128
- -------
129
- Ensure TOML parsing works across Python 3.9+ by using the standard
130
- library tomllib on 3.11+ and falling back to the tomli package
131
- on earlier versions.
132
-
133
- Returns
134
- -------
135
- module
136
- Either tomllib or tomli with identical interfaces.
137
-
138
- Raises
139
- ------
140
- ModuleNotFoundError
141
- If neither tomllib nor tomli can be imported.
142
- """
143
- global _toml_module
144
- if _toml_module is not None:
145
- return _toml_module
146
-
147
- # Use tomllib (Python 3.11+) or tomli backport (Python 3.9-3.10)
148
- # Both have the same interface, so we can treat them interchangeably
149
- try:
150
- import tomllib as module # type: ignore[import-not-found]
151
- except ModuleNotFoundError:
152
- import tomli as module # type: ignore[import-not-found,no-redef]
153
-
154
- _toml_module = module
155
- return module
156
123
 
157
124
 
158
125
  def run(
@@ -250,10 +217,9 @@ def _load_pyproject(pyproject: Path) -> dict[str, object]:
250
217
  if cached is not None:
251
218
  return cached
252
219
  raw_text = path.read_text(encoding="utf-8")
253
- toml_module = _get_toml_module()
254
220
  try:
255
- parsed_obj = toml_module.loads(raw_text)
256
- except toml_module.TOMLDecodeError as exc: # pragma: no cover - invalid pyproject fails fast
221
+ parsed_obj = rtoml.loads(raw_text)
222
+ except rtoml.TomlParsingError as exc: # pragma: no cover - invalid pyproject fails fast
257
223
  msg = f"Unable to parse {path}: {exc}"
258
224
  raise ValueError(msg) from exc
259
225
  data = {str(key): value for key, value in parsed_obj.items()}
@@ -8,9 +8,10 @@ from __future__ import annotations
8
8
 
9
9
  from dataclasses import dataclass, field
10
10
  from pathlib import Path
11
- from types import ModuleType
12
11
  from typing import Any, cast
13
12
 
13
+ import rtoml
14
+
14
15
  __all__ = [
15
16
  "CleanConfig",
16
17
  "CoverageReportConfig",
@@ -25,28 +26,6 @@ __all__ = [
25
26
  ]
26
27
 
27
28
 
28
- # ---------------------------------------------------------------------------
29
- # TOML Module Loading
30
- # ---------------------------------------------------------------------------
31
-
32
- _toml_module: ModuleType | None = None
33
-
34
-
35
- def _get_toml_module() -> ModuleType:
36
- """Return the TOML parsing module (tomllib or tomli fallback)."""
37
- global _toml_module
38
- if _toml_module is not None:
39
- return _toml_module
40
-
41
- try:
42
- import tomllib as module # type: ignore[import-not-found]
43
- except ImportError:
44
- import tomli as module # type: ignore[import-not-found,no-redef]
45
-
46
- _toml_module = module
47
- return module
48
-
49
-
50
29
  # ---------------------------------------------------------------------------
51
30
  # Helper Functions for Safe Value Extraction
52
31
  # ---------------------------------------------------------------------------
@@ -436,8 +415,7 @@ class PyprojectConfig:
436
415
  def from_path(cls, path: Path) -> PyprojectConfig:
437
416
  """Load configuration from a pyproject.toml file."""
438
417
  try:
439
- toml = _get_toml_module()
440
- data: dict[str, Any] = toml.loads(path.read_text(encoding="utf-8"))
418
+ data: dict[str, Any] = rtoml.loads(path.read_text(encoding="utf-8"))
441
419
  return cls.from_dict(data)
442
420
  except Exception:
443
421
  return cls()
@@ -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.1"
27
+ version = "2.2.2"
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.
@@ -8,16 +8,11 @@ Each test verifies exactly one metadata behavior:
8
8
  from __future__ import annotations
9
9
 
10
10
  import runpy
11
- import sys
12
11
  from pathlib import Path
13
12
  from typing import Any, cast
14
13
 
15
- if sys.version_info >= (3, 11):
16
- import tomllib
17
- else:
18
- import tomli as tomllib # type: ignore[import-not-found,no-redef]
19
-
20
14
  import pytest
15
+ import rtoml
21
16
 
22
17
  PROJECT_ROOT = Path(__file__).resolve().parent.parent
23
18
  PYPROJECT_PATH = PROJECT_ROOT / "pyproject.toml"
@@ -30,8 +25,7 @@ TARGET_FIELDS = ("name", "title", "version", "homepage", "author", "author_email
30
25
 
31
26
 
32
27
  def _load_pyproject() -> dict[str, Any]:
33
- with PYPROJECT_PATH.open("rb") as stream:
34
- return tomllib.load(stream)
28
+ return rtoml.load(PYPROJECT_PATH)
35
29
 
36
30
 
37
31
  def _resolve_init_conf_path(pyproject: dict[str, Any]) -> Path:
@@ -67,7 +61,7 @@ def _load_init_conf_metadata(init_conf_path: Path) -> dict[str, str]:
67
61
  if not fragments:
68
62
  raise AssertionError("No metadata assignments found in __init__conf__.py")
69
63
  metadata_text = "[metadata]\n" + "\n".join(fragments)
70
- parsed = tomllib.loads(metadata_text)
64
+ parsed = rtoml.loads(metadata_text)
71
65
  metadata_table = cast(dict[str, str], parsed["metadata"])
72
66
  return metadata_table
73
67