debug-dojo 0.3.2__tar.gz → 0.4.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.
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/.gitignore +1 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/HISTORY.md +12 -13
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/PKG-INFO +41 -27
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/README.md +29 -13
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/pyproject.toml +9 -14
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/_cli.py +47 -25
- debug_dojo-0.4.0/src/debug_dojo/_config.py +136 -0
- debug_dojo-0.4.0/src/debug_dojo/_config_models.py +138 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/_installers.py +27 -12
- debug_dojo-0.3.2/src/debug_dojo/_config.py +0 -117
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/LICENSE +0 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/__init__.py +0 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/__main__.py +0 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/_compareres.py +0 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/install.py +0 -0
- {debug_dojo-0.3.2 → debug_dojo-0.4.0}/src/debug_dojo/py.typed +0 -0
|
@@ -1,38 +1,37 @@
|
|
|
1
|
-
## v0.
|
|
1
|
+
## v0.4.0 (2025-08-10)
|
|
2
2
|
|
|
3
|
-
*release tag*: [v0.
|
|
3
|
+
*release tag*: [v0.4.0]
|
|
4
|
+
|
|
5
|
+
- New configuration model `DebugDojoConfig` for better structure.
|
|
6
|
+
- Added support for `debugger` configuration in `dojo.toml`.
|
|
7
|
+
- Updated `dojo` command to include debugger type in command call.
|
|
8
|
+
- Configuration versioning allows for in-flight migration of old configurations.
|
|
9
|
+
- Improved error handling in configuration loading.
|
|
10
|
+
- Improved catching errors from target execution.
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
## v0.3.2 (2025-07-28)
|
|
13
|
+
|
|
14
|
+
*release tag*: [v0.3.2]
|
|
6
15
|
|
|
7
16
|
- New logo for the project.
|
|
8
17
|
- Typer used for CLI implementation.
|
|
9
18
|
- Dojo is configured via `dojo.toml` or `pyproject.toml`.
|
|
10
19
|
- Support for `debugpy` and `ipdb` for debugging.
|
|
11
|
-
|
|
12
|
-
#### Fixes
|
|
13
|
-
|
|
14
20
|
- Fixed documentation and history.
|
|
15
21
|
|
|
16
22
|
## v0.2.0 (2025-07-20)
|
|
17
23
|
|
|
18
24
|
*release tag*: [v0.2.0]
|
|
19
25
|
|
|
20
|
-
### What's Changed
|
|
21
|
-
|
|
22
26
|
- Added `dojo` command for easy debugging setup.
|
|
23
27
|
- Added `p()` function for rich printing.
|
|
24
28
|
- Added history file for tracking changes.
|
|
25
29
|
- Moved to `hatch` for building and packaging.
|
|
26
|
-
|
|
27
|
-
#### Fixes
|
|
28
|
-
|
|
29
30
|
- Fixed `pyproject.toml` to point to GitHub repository as the homepage.
|
|
30
31
|
|
|
31
32
|
## v0.1.0 (2025-07-19)
|
|
32
33
|
|
|
33
34
|
*release tag*: [v0.1.0]
|
|
34
35
|
|
|
35
|
-
### What's Changed
|
|
36
|
-
|
|
37
36
|
- Initial module to install debugging tools.
|
|
38
37
|
- Debug mode utilities for PuDB, rich tracebacks, and object inspection.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: debug-dojo
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: Debbugging dojo for Python developers
|
|
5
5
|
Project-URL: Homepage, https://github.com/bwrob/debug-dojo
|
|
6
6
|
Project-URL: Documentation, https://github.com/bwrob/debug-dojo/blob/main/README.md
|
|
@@ -48,7 +48,7 @@ It leverages [`rich`](https://github.com/Textualize/rich) for beautiful output a
|
|
|
48
48
|
|
|
49
49
|
- **Convenient CLI** Quickly run your code with debugging tools enabled.
|
|
50
50
|
- **Simple API:** Install all tools or only what you need.
|
|
51
|
-
- **Debugger integration:** Quickly enable Debugpy, PuDB, PDB, or IPDB as your default debugger.
|
|
51
|
+
- **Debugger integration:** Quickly enable Debugpy, PuDB, PDB, or IPDB as your default pre-configured debugger.
|
|
52
52
|
- **Rich tracebacks:** Get readable, colorized tracebacks for easier debugging.
|
|
53
53
|
- **Side-by-side object inspection:** Visually compare Python objects, their attributes, and methods in the terminal.
|
|
54
54
|
- **Configuration:** Easily configure the debugging tools using `dojo.toml` or `pyproject.toml`.
|
|
@@ -63,10 +63,10 @@ Run your Python script with debugging tools enabled using the `debug-dojo` comma
|
|
|
63
63
|
dojo my_script.py
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
You can optionally set configuration
|
|
66
|
+
You can optionally set configuration, verbose mode, and specify the debugger type. Both script files and modules are supported:
|
|
67
67
|
|
|
68
68
|
```console
|
|
69
|
-
dojo --config dojo.toml --verbose
|
|
69
|
+
dojo --debugger ipdb --config dojo.toml --verbose --module my_module
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
### From the code
|
|
@@ -74,19 +74,18 @@ dojo --config dojo.toml --verbose my_script.py
|
|
|
74
74
|
In the `PuDB` style, you can install all debugging tools and enter the debugging mode with a single command:
|
|
75
75
|
|
|
76
76
|
```python
|
|
77
|
-
import debug_dojo.install; b()
|
|
78
|
-
|
|
79
77
|
object_1 = {"foo": 1, "bar": 2}
|
|
80
78
|
object_2 = [1, 2, 3]
|
|
81
79
|
|
|
80
|
+
import debug_dojo.install; b()
|
|
82
81
|
p(object_1) # Pretty print an object with Rich
|
|
83
|
-
i(object_1) # Inspect an object
|
|
84
|
-
c(object_1, object_2) # Compare two objects side-by-side
|
|
85
82
|
```
|
|
86
83
|
|
|
87
|
-
|
|
84
|
+
### Features in debugging mode
|
|
88
85
|
|
|
89
|
-
|
|
86
|
+
The following functions are available in the debugging mode, injected into builtins:
|
|
87
|
+
|
|
88
|
+
- `b()` is a hook that sets a breakpoint using the configured debugger.
|
|
90
89
|
- `p(object_1)` is pretty printing of an object using Rich.
|
|
91
90
|
- `i(object_1)` to inspect an object using Rich.
|
|
92
91
|
- `c(object_1, object_2)` to compare two objects side-by-side.
|
|
@@ -98,12 +97,23 @@ You can configure the debugging tools using a `dojo.toml` or `pyproject.toml` fi
|
|
|
98
97
|
**Example `dojo.toml`:**
|
|
99
98
|
|
|
100
99
|
```toml
|
|
101
|
-
|
|
100
|
+
[debuggers]
|
|
101
|
+
default = "ipdb"
|
|
102
|
+
|
|
103
|
+
debugpy = { port = 1992 }
|
|
104
|
+
ipdb = { context_lines = 20 }
|
|
105
|
+
|
|
106
|
+
[exceptions]
|
|
107
|
+
locals_in_traceback = false
|
|
108
|
+
post_mortem = true
|
|
109
|
+
rich_traceback = true
|
|
102
110
|
|
|
103
111
|
[features]
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
breakpoint = "b"
|
|
113
|
+
# Empty string means disable the feature
|
|
114
|
+
comparer = ""
|
|
115
|
+
rich_inspect = "i"
|
|
116
|
+
rich_print = "p"
|
|
107
117
|
```
|
|
108
118
|
|
|
109
119
|
## Installation
|
|
@@ -133,46 +143,50 @@ Note that dojo most likely will not work when installed via `pipx` or `uvx`, as
|
|
|
133
143
|
```console
|
|
134
144
|
ruff check src/debug_dojo --fix
|
|
135
145
|
basedpyright src/debug_dojo
|
|
146
|
+
|
|
147
|
+
poe code-quality
|
|
136
148
|
```
|
|
137
149
|
|
|
150
|
+
### Tests
|
|
151
|
+
|
|
152
|
+
TBA
|
|
138
153
|
|
|
139
154
|
## Changelog
|
|
140
155
|
|
|
141
|
-
## v0.
|
|
156
|
+
## v0.4.0 (2025-08-10)
|
|
142
157
|
|
|
143
|
-
*release tag*: [v0.
|
|
158
|
+
*release tag*: [v0.4.0]
|
|
144
159
|
|
|
145
|
-
|
|
160
|
+
- New configuration model `DebugDojoConfig` for better structure.
|
|
161
|
+
- Added support for `debugger` configuration in `dojo.toml`.
|
|
162
|
+
- Updated `dojo` command to include debugger type in command call.
|
|
163
|
+
- Configuration versioning allows for in-flight migration of old configurations.
|
|
164
|
+
- Improved error handling in configuration loading.
|
|
165
|
+
- Improved catching errors from target execution.
|
|
166
|
+
|
|
167
|
+
## v0.3.2 (2025-07-28)
|
|
168
|
+
|
|
169
|
+
*release tag*: [v0.3.2]
|
|
146
170
|
|
|
147
171
|
- New logo for the project.
|
|
148
172
|
- Typer used for CLI implementation.
|
|
149
173
|
- Dojo is configured via `dojo.toml` or `pyproject.toml`.
|
|
150
174
|
- Support for `debugpy` and `ipdb` for debugging.
|
|
151
|
-
|
|
152
|
-
#### Fixes
|
|
153
|
-
|
|
154
175
|
- Fixed documentation and history.
|
|
155
176
|
|
|
156
177
|
## v0.2.0 (2025-07-20)
|
|
157
178
|
|
|
158
179
|
*release tag*: [v0.2.0]
|
|
159
180
|
|
|
160
|
-
### What's Changed
|
|
161
|
-
|
|
162
181
|
- Added `dojo` command for easy debugging setup.
|
|
163
182
|
- Added `p()` function for rich printing.
|
|
164
183
|
- Added history file for tracking changes.
|
|
165
184
|
- Moved to `hatch` for building and packaging.
|
|
166
|
-
|
|
167
|
-
#### Fixes
|
|
168
|
-
|
|
169
185
|
- Fixed `pyproject.toml` to point to GitHub repository as the homepage.
|
|
170
186
|
|
|
171
187
|
## v0.1.0 (2025-07-19)
|
|
172
188
|
|
|
173
189
|
*release tag*: [v0.1.0]
|
|
174
190
|
|
|
175
|
-
### What's Changed
|
|
176
|
-
|
|
177
191
|
- Initial module to install debugging tools.
|
|
178
192
|
- Debug mode utilities for PuDB, rich tracebacks, and object inspection.
|
|
@@ -16,7 +16,7 @@ It leverages [`rich`](https://github.com/Textualize/rich) for beautiful output a
|
|
|
16
16
|
|
|
17
17
|
- **Convenient CLI** Quickly run your code with debugging tools enabled.
|
|
18
18
|
- **Simple API:** Install all tools or only what you need.
|
|
19
|
-
- **Debugger integration:** Quickly enable Debugpy, PuDB, PDB, or IPDB as your default debugger.
|
|
19
|
+
- **Debugger integration:** Quickly enable Debugpy, PuDB, PDB, or IPDB as your default pre-configured debugger.
|
|
20
20
|
- **Rich tracebacks:** Get readable, colorized tracebacks for easier debugging.
|
|
21
21
|
- **Side-by-side object inspection:** Visually compare Python objects, their attributes, and methods in the terminal.
|
|
22
22
|
- **Configuration:** Easily configure the debugging tools using `dojo.toml` or `pyproject.toml`.
|
|
@@ -31,10 +31,10 @@ Run your Python script with debugging tools enabled using the `debug-dojo` comma
|
|
|
31
31
|
dojo my_script.py
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
You can optionally set configuration
|
|
34
|
+
You can optionally set configuration, verbose mode, and specify the debugger type. Both script files and modules are supported:
|
|
35
35
|
|
|
36
36
|
```console
|
|
37
|
-
dojo --config dojo.toml --verbose
|
|
37
|
+
dojo --debugger ipdb --config dojo.toml --verbose --module my_module
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
### From the code
|
|
@@ -42,19 +42,18 @@ dojo --config dojo.toml --verbose my_script.py
|
|
|
42
42
|
In the `PuDB` style, you can install all debugging tools and enter the debugging mode with a single command:
|
|
43
43
|
|
|
44
44
|
```python
|
|
45
|
-
import debug_dojo.install; b()
|
|
46
|
-
|
|
47
45
|
object_1 = {"foo": 1, "bar": 2}
|
|
48
46
|
object_2 = [1, 2, 3]
|
|
49
47
|
|
|
48
|
+
import debug_dojo.install; b()
|
|
50
49
|
p(object_1) # Pretty print an object with Rich
|
|
51
|
-
i(object_1) # Inspect an object
|
|
52
|
-
c(object_1, object_2) # Compare two objects side-by-side
|
|
53
50
|
```
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
### Features in debugging mode
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
The following functions are available in the debugging mode, injected into builtins:
|
|
55
|
+
|
|
56
|
+
- `b()` is a hook that sets a breakpoint using the configured debugger.
|
|
58
57
|
- `p(object_1)` is pretty printing of an object using Rich.
|
|
59
58
|
- `i(object_1)` to inspect an object using Rich.
|
|
60
59
|
- `c(object_1, object_2)` to compare two objects side-by-side.
|
|
@@ -66,12 +65,23 @@ You can configure the debugging tools using a `dojo.toml` or `pyproject.toml` fi
|
|
|
66
65
|
**Example `dojo.toml`:**
|
|
67
66
|
|
|
68
67
|
```toml
|
|
69
|
-
|
|
68
|
+
[debuggers]
|
|
69
|
+
default = "ipdb"
|
|
70
|
+
|
|
71
|
+
debugpy = { port = 1992 }
|
|
72
|
+
ipdb = { context_lines = 20 }
|
|
73
|
+
|
|
74
|
+
[exceptions]
|
|
75
|
+
locals_in_traceback = false
|
|
76
|
+
post_mortem = true
|
|
77
|
+
rich_traceback = true
|
|
70
78
|
|
|
71
79
|
[features]
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
80
|
+
breakpoint = "b"
|
|
81
|
+
# Empty string means disable the feature
|
|
82
|
+
comparer = ""
|
|
83
|
+
rich_inspect = "i"
|
|
84
|
+
rich_print = "p"
|
|
75
85
|
```
|
|
76
86
|
|
|
77
87
|
## Installation
|
|
@@ -101,4 +111,10 @@ Note that dojo most likely will not work when installed via `pipx` or `uvx`, as
|
|
|
101
111
|
```console
|
|
102
112
|
ruff check src/debug_dojo --fix
|
|
103
113
|
basedpyright src/debug_dojo
|
|
114
|
+
|
|
115
|
+
poe code-quality
|
|
104
116
|
```
|
|
117
|
+
|
|
118
|
+
### Tests
|
|
119
|
+
|
|
120
|
+
TBA
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"rich>=12.0.0",
|
|
14
14
|
"tomlkit>=0.13.3",
|
|
15
15
|
"typer>=0.15.0",
|
|
16
|
-
]
|
|
16
|
+
]
|
|
17
17
|
license = 'MIT'
|
|
18
18
|
license-files = ['LICENSE']
|
|
19
19
|
keywords = [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"Topic :: Software Development :: Debuggers",
|
|
37
37
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
38
38
|
]
|
|
39
|
-
version = "0.
|
|
39
|
+
version = "0.4.0"
|
|
40
40
|
dynamic = ['readme']
|
|
41
41
|
|
|
42
42
|
[project.urls]
|
|
@@ -46,8 +46,6 @@ version = "0.3.2"
|
|
|
46
46
|
Changelog = "https://github.com/bwrob/debug-dojo/blob/main/HISTORY.md"
|
|
47
47
|
|
|
48
48
|
[project.scripts]
|
|
49
|
-
# This defines your command-line script!
|
|
50
|
-
# It points to the 'main' function in your 'cli' module.
|
|
51
49
|
"dojo" = "debug_dojo._cli:main"
|
|
52
50
|
|
|
53
51
|
[dependency-groups]
|
|
@@ -56,7 +54,7 @@ version = "0.3.2"
|
|
|
56
54
|
"jupyter>=1.1.1",
|
|
57
55
|
"poethepoet>=0.36.0",
|
|
58
56
|
"ruff>=0.12.4",
|
|
59
|
-
]
|
|
57
|
+
]
|
|
60
58
|
|
|
61
59
|
[build-system]
|
|
62
60
|
requires = [
|
|
@@ -86,22 +84,19 @@ version = "0.3.2"
|
|
|
86
84
|
]
|
|
87
85
|
|
|
88
86
|
[tool.basedpyright]
|
|
89
|
-
typeCheckingMode = "
|
|
87
|
+
typeCheckingMode = "basic"
|
|
90
88
|
pythonVersion = "3.10"
|
|
91
89
|
strict = ["src/debug_dojo/*"]
|
|
92
90
|
ignore = ["examples"]
|
|
93
91
|
|
|
94
92
|
[tool.poe.tasks]
|
|
95
|
-
# Define your tasks here
|
|
96
93
|
lint = "ruff check --fix src"
|
|
97
94
|
format = "ruff format src"
|
|
98
|
-
type-check = "basedpyright"
|
|
95
|
+
type-check = "basedpyright --project pyproject.toml src/debug_dojo"
|
|
99
96
|
code-quality = ["format", "lint", "type-check"]
|
|
100
97
|
publish = [
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
{cmd="
|
|
105
|
-
{cmd="uv build"},
|
|
106
|
-
{cmd="uv publish"},
|
|
98
|
+
"code-quality",
|
|
99
|
+
{ cmd = "rm -rf dist" },
|
|
100
|
+
{ cmd = "uv build" },
|
|
101
|
+
{ cmd = "uv publish" },
|
|
107
102
|
]
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
import os
|
|
6
5
|
import runpy
|
|
7
6
|
import sys
|
|
8
7
|
from bdb import BdbQuit
|
|
@@ -10,10 +9,9 @@ from pathlib import Path
|
|
|
10
9
|
from typing import Annotated
|
|
11
10
|
|
|
12
11
|
import typer
|
|
13
|
-
from pydantic import ValidationError
|
|
14
12
|
from rich import print as rich_print
|
|
15
13
|
|
|
16
|
-
from ._config import DebugDojoConfig, load_config
|
|
14
|
+
from ._config import DebugDojoConfig, DebuggerType, load_config
|
|
17
15
|
from ._installers import install_by_config
|
|
18
16
|
|
|
19
17
|
cli = typer.Typer(
|
|
@@ -23,11 +21,13 @@ cli = typer.Typer(
|
|
|
23
21
|
)
|
|
24
22
|
|
|
25
23
|
|
|
26
|
-
def execute_with_debug(
|
|
24
|
+
def execute_with_debug( # noqa: C901
|
|
27
25
|
target_name: str,
|
|
28
26
|
target_args: list[str],
|
|
29
27
|
*,
|
|
28
|
+
target_is_module: bool,
|
|
30
29
|
verbose: bool,
|
|
30
|
+
config: DebugDojoConfig,
|
|
31
31
|
) -> None:
|
|
32
32
|
"""Execute a target script or module with installation of debugging tools."""
|
|
33
33
|
sys.argv = [target_name, *target_args]
|
|
@@ -36,21 +36,37 @@ def execute_with_debug(
|
|
|
36
36
|
rich_print(f"[blue]Installing debugging tools for {target_name}.[/blue]")
|
|
37
37
|
rich_print(f"[blue]Arguments for target: {target_args}[/blue]")
|
|
38
38
|
|
|
39
|
-
config = load_config()
|
|
40
39
|
install_by_config(config)
|
|
41
40
|
|
|
42
|
-
if
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
or os.sep in target_name
|
|
46
|
-
):
|
|
41
|
+
if target_is_module:
|
|
42
|
+
runner = runpy.run_module
|
|
43
|
+
else:
|
|
47
44
|
if not Path(target_name).exists():
|
|
48
45
|
sys.exit(1)
|
|
49
46
|
runner = runpy.run_path
|
|
50
|
-
else:
|
|
51
|
-
runner = runpy.run_module
|
|
52
47
|
|
|
53
|
-
|
|
48
|
+
try:
|
|
49
|
+
_ = runner(target_name, run_name="__main__")
|
|
50
|
+
except ImportError as e:
|
|
51
|
+
rich_print(f"[red]Error importing {target_name}:[/red]\n{e}")
|
|
52
|
+
sys.exit(1)
|
|
53
|
+
except BdbQuit:
|
|
54
|
+
rich_print("[red]Debugging session terminated by user.[/red]")
|
|
55
|
+
sys.exit(0)
|
|
56
|
+
except KeyboardInterrupt:
|
|
57
|
+
rich_print("[red]Execution interrupted by user.[/red]")
|
|
58
|
+
sys.exit(0)
|
|
59
|
+
except SystemExit as e:
|
|
60
|
+
if e.code:
|
|
61
|
+
rich_print(f"[red]Script exited with code {e.code}.[/red]")
|
|
62
|
+
except Exception as e: # noqa: BLE001
|
|
63
|
+
rich_print(f"[red]Error while running {target_name}:[/red]\n{e}")
|
|
64
|
+
if config.exceptions.post_mortem:
|
|
65
|
+
import pdb # noqa: PLC0415, T100
|
|
66
|
+
|
|
67
|
+
rich_print("[blue]Entering post-mortem debugging session...[/blue]")
|
|
68
|
+
pdb.post_mortem(e.__traceback__)
|
|
69
|
+
sys.exit(1)
|
|
54
70
|
|
|
55
71
|
|
|
56
72
|
def display_config(config: DebugDojoConfig) -> None:
|
|
@@ -64,36 +80,42 @@ def display_config(config: DebugDojoConfig) -> None:
|
|
|
64
80
|
no_args_is_help=True,
|
|
65
81
|
context_settings={"allow_extra_args": True, "ignore_unknown_options": True},
|
|
66
82
|
)
|
|
67
|
-
def run_debug(
|
|
83
|
+
def run_debug( # noqa: PLR0913
|
|
68
84
|
ctx: typer.Context,
|
|
69
85
|
target_name: Annotated[
|
|
70
86
|
str | None, typer.Argument(help="The target script or module to debug.")
|
|
71
87
|
] = None,
|
|
88
|
+
*,
|
|
72
89
|
config_path: Annotated[
|
|
73
90
|
Path | None, typer.Option("--config", "-c", help="Show configuration")
|
|
74
91
|
] = None,
|
|
75
|
-
|
|
92
|
+
debugger: Annotated[
|
|
93
|
+
DebuggerType | None,
|
|
94
|
+
typer.Option("--debugger", "-d", help="Specify the debugger to use"),
|
|
95
|
+
] = None,
|
|
76
96
|
verbose: Annotated[
|
|
77
97
|
bool,
|
|
78
98
|
typer.Option("--verbose", "-v", is_flag=True, help="Enable verbose output"),
|
|
79
99
|
] = False,
|
|
100
|
+
module: Annotated[
|
|
101
|
+
bool,
|
|
102
|
+
typer.Option("--module", "-m", is_flag=True, help="Run as a module"),
|
|
103
|
+
] = False,
|
|
80
104
|
) -> None:
|
|
81
105
|
"""Run the command-line interface."""
|
|
82
|
-
|
|
83
|
-
config = load_config(config_path, verbose=verbose)
|
|
84
|
-
except ValidationError as e:
|
|
85
|
-
rich_print(f"[red]Configuration error:\n{e}[/red]")
|
|
86
|
-
sys.exit(1)
|
|
106
|
+
config = load_config(config_path, verbose=verbose, debugger=debugger)
|
|
87
107
|
|
|
88
108
|
if verbose:
|
|
89
109
|
display_config(config)
|
|
90
110
|
|
|
91
111
|
if target_name:
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
112
|
+
execute_with_debug(
|
|
113
|
+
target_name=target_name,
|
|
114
|
+
target_is_module=module,
|
|
115
|
+
target_args=ctx.args,
|
|
116
|
+
verbose=verbose,
|
|
117
|
+
config=config,
|
|
118
|
+
)
|
|
97
119
|
|
|
98
120
|
|
|
99
121
|
def main() -> None:
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"""Debug Dojo configuration module.
|
|
2
|
+
|
|
3
|
+
It includes configurations for different debuggers, exception handling,
|
|
4
|
+
and features that can be enabled or disabled.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
from pathlib import Path
|
|
11
|
+
from typing import Any, cast
|
|
12
|
+
|
|
13
|
+
from pydantic import ValidationError
|
|
14
|
+
from rich import print as rich_print
|
|
15
|
+
from tomlkit import parse
|
|
16
|
+
from tomlkit.exceptions import TOMLKitError
|
|
17
|
+
|
|
18
|
+
from ._config_models import (
|
|
19
|
+
DebugDojoConfig,
|
|
20
|
+
DebugDojoConfigV1,
|
|
21
|
+
DebugDojoConfigV2,
|
|
22
|
+
DebuggerType,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def __filter_pydantic_error_msg(error: ValidationError) -> str:
|
|
27
|
+
"""Filter out specific lines from a Pydantic validation error."""
|
|
28
|
+
return "\n".join(
|
|
29
|
+
line
|
|
30
|
+
for line in str(error).splitlines()
|
|
31
|
+
if not line.startswith("For further information visit")
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def resolve_config_path(config_path: Path | None) -> Path | None:
|
|
36
|
+
"""Resolve the configuration path, returning a default if none is provided."""
|
|
37
|
+
if config_path:
|
|
38
|
+
if not config_path.exists():
|
|
39
|
+
msg = f"Configuration file not found:\n{config_path.resolve()}"
|
|
40
|
+
raise FileNotFoundError(msg)
|
|
41
|
+
return config_path.resolve()
|
|
42
|
+
|
|
43
|
+
# Default configuration path
|
|
44
|
+
for path in (Path("dojo.toml"), Path("pyproject.toml")):
|
|
45
|
+
if path.exists():
|
|
46
|
+
return path.resolve()
|
|
47
|
+
return None
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def load_raw_config(
|
|
51
|
+
config_path: Path,
|
|
52
|
+
) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
53
|
+
"""Load the Debug Dojo configuration from a file.
|
|
54
|
+
|
|
55
|
+
Currently supports 'dojo.toml' or 'pyproject.toml'.
|
|
56
|
+
If no path is provided, it checks the current directory for these files.
|
|
57
|
+
"""
|
|
58
|
+
config_str = config_path.read_text(encoding="utf-8")
|
|
59
|
+
|
|
60
|
+
try:
|
|
61
|
+
config_data = parse(config_str).unwrap()
|
|
62
|
+
except TOMLKitError as e:
|
|
63
|
+
msg = f"Error parsing configuration file {config_path.resolve()}."
|
|
64
|
+
raise ValueError(msg) from e
|
|
65
|
+
|
|
66
|
+
# If config is in [tool.debug_dojo] (pyproject.toml), extract it.
|
|
67
|
+
if config_path.name == "pyproject.toml":
|
|
68
|
+
try:
|
|
69
|
+
dojo_config = cast("dict[str, Any]", config_data["tool"]["debug_dojo"])
|
|
70
|
+
except KeyError:
|
|
71
|
+
return {}
|
|
72
|
+
else:
|
|
73
|
+
return dojo_config
|
|
74
|
+
|
|
75
|
+
return config_data
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def load_config( # noqa: C901
|
|
79
|
+
config_path: Path | None = None,
|
|
80
|
+
*,
|
|
81
|
+
verbose: bool = False,
|
|
82
|
+
debugger: DebuggerType | None = None,
|
|
83
|
+
) -> DebugDojoConfig:
|
|
84
|
+
"""Load the Debug Dojo configuration and return a DebugDojoConfig instance."""
|
|
85
|
+
resolved_path = resolve_config_path(config_path)
|
|
86
|
+
|
|
87
|
+
if verbose:
|
|
88
|
+
if resolved_path:
|
|
89
|
+
msg = f"Using configuration file: {resolved_path}."
|
|
90
|
+
else:
|
|
91
|
+
msg = "No configuration file found, using default settings."
|
|
92
|
+
rich_print(f"[blue]{msg}[/blue]")
|
|
93
|
+
|
|
94
|
+
if not resolved_path:
|
|
95
|
+
return DebugDojoConfig()
|
|
96
|
+
|
|
97
|
+
raw_config = load_raw_config(resolved_path)
|
|
98
|
+
|
|
99
|
+
config = None
|
|
100
|
+
for model in (DebugDojoConfigV2, DebugDojoConfigV1):
|
|
101
|
+
model_name = model.__name__
|
|
102
|
+
try:
|
|
103
|
+
config = model.model_validate(raw_config)
|
|
104
|
+
except ValidationError as e:
|
|
105
|
+
if verbose:
|
|
106
|
+
msg = (
|
|
107
|
+
f"[yellow]Configuration validation error for {model_name}:\n"
|
|
108
|
+
f"{__filter_pydantic_error_msg(e)}\n\n"
|
|
109
|
+
f"Please check your configuration file {resolved_path}.[/yellow]"
|
|
110
|
+
)
|
|
111
|
+
rich_print(msg)
|
|
112
|
+
else:
|
|
113
|
+
if verbose or model_name != DebugDojoConfig.__name__:
|
|
114
|
+
msg = (
|
|
115
|
+
f"[blue]Using configuration model: {model_name}.\n"
|
|
116
|
+
f"Current configuration model {DebugDojoConfig.__name__}. [/blue]"
|
|
117
|
+
)
|
|
118
|
+
rich_print(msg)
|
|
119
|
+
break
|
|
120
|
+
|
|
121
|
+
if not config:
|
|
122
|
+
msg = (
|
|
123
|
+
f"[red]Unsupported configuration version in {resolved_path.resolve()}.\n"
|
|
124
|
+
"Please update your configuration file.[/red]"
|
|
125
|
+
)
|
|
126
|
+
rich_print(msg)
|
|
127
|
+
sys.exit(1)
|
|
128
|
+
|
|
129
|
+
while not isinstance(config, DebugDojoConfig):
|
|
130
|
+
config = config.update()
|
|
131
|
+
|
|
132
|
+
# If a debugger is specified, update the config.
|
|
133
|
+
if debugger:
|
|
134
|
+
config.debuggers.default = debugger
|
|
135
|
+
|
|
136
|
+
return config
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, ConfigDict
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class BaseConfig(BaseModel):
|
|
9
|
+
"""Base configuration class with extra fields forbidden."""
|
|
10
|
+
|
|
11
|
+
model_config = ConfigDict(extra="forbid", validate_assignment=True)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class DebuggerType(Enum):
|
|
15
|
+
"""Enum for different types of debuggers."""
|
|
16
|
+
|
|
17
|
+
PDB = "pdb"
|
|
18
|
+
PUDB = "pudb"
|
|
19
|
+
IPDB = "ipdb"
|
|
20
|
+
DEBUGPY = "debugpy"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Features(BaseModel):
|
|
24
|
+
"""Configuration for installing debug features."""
|
|
25
|
+
|
|
26
|
+
model_config = ConfigDict(extra="forbid") # pyright: ignore[reportUnannotatedClassAttribute]
|
|
27
|
+
|
|
28
|
+
rich_inspect: bool = True
|
|
29
|
+
"""Install rich inspect as 'i' for enhanced object inspection."""
|
|
30
|
+
rich_print: bool = True
|
|
31
|
+
"""Install rich print as 'p' for enhanced printing."""
|
|
32
|
+
rich_traceback: bool = True
|
|
33
|
+
"""Install rich traceback for better error reporting."""
|
|
34
|
+
comparer: bool = True
|
|
35
|
+
"""Install comparer as 'c' for side-by-side object comparison."""
|
|
36
|
+
breakpoint: bool = True
|
|
37
|
+
"""Install breakpoint as 'b' for setting breakpoints in code."""
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class DebugpyConfig(BaseConfig):
|
|
41
|
+
"""Configuration for debugpy debugger."""
|
|
42
|
+
|
|
43
|
+
port: int = 1992
|
|
44
|
+
"""Port for debugpy debugger."""
|
|
45
|
+
host: str = "localhost"
|
|
46
|
+
"""Host for debugpy debugger."""
|
|
47
|
+
wait_for_client: bool = True
|
|
48
|
+
"""Whether to wait for the client to connect before starting debugging."""
|
|
49
|
+
log_to_file: bool = False
|
|
50
|
+
"""Whether to log debugpy output to a file."""
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class IpdbConfig(BaseConfig):
|
|
54
|
+
"""Configuration for ipdb debugger."""
|
|
55
|
+
|
|
56
|
+
context_lines: int = 20
|
|
57
|
+
"""Number of context lines to show in ipdb."""
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
class DebuggersConfig(BaseConfig):
|
|
61
|
+
"""Configuration for debuggers."""
|
|
62
|
+
|
|
63
|
+
default: DebuggerType = DebuggerType.IPDB
|
|
64
|
+
"""Default debugger to use."""
|
|
65
|
+
prompt_name: str = "debug-dojo> "
|
|
66
|
+
"""Prompt name for the debugger, used in the REPL."""
|
|
67
|
+
debugpy: DebugpyConfig = DebugpyConfig()
|
|
68
|
+
"""Configuration for debugpy debugger."""
|
|
69
|
+
ipdb: IpdbConfig = IpdbConfig()
|
|
70
|
+
"""Configuration for ipdb debugger."""
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class ExceptionsConfig(BaseConfig):
|
|
74
|
+
"""Configuration for exceptions handling."""
|
|
75
|
+
|
|
76
|
+
rich_traceback: bool = True
|
|
77
|
+
"""Enable rich traceback for better error reporting."""
|
|
78
|
+
locals_in_traceback: bool = False
|
|
79
|
+
"""Include local variables in traceback."""
|
|
80
|
+
post_mortem: bool = True
|
|
81
|
+
"""Enable post-mortem debugging after an exception."""
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class FeaturesConfig(BaseConfig):
|
|
85
|
+
"""Configuration for installing debug features."""
|
|
86
|
+
|
|
87
|
+
rich_inspect: str = "i"
|
|
88
|
+
"""Install rich inspect as 'i' for enhanced object inspection."""
|
|
89
|
+
rich_print: str = "p"
|
|
90
|
+
"""Install rich print as 'p' for enhanced printing."""
|
|
91
|
+
comparer: str = "c"
|
|
92
|
+
"""Install comparer as 'c' for side-by-side object comparison."""
|
|
93
|
+
breakpoint: str = "b"
|
|
94
|
+
"""Install breakpoint as 'b' for setting breakpoints in code."""
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class DebugDojoConfigV1(BaseModel):
|
|
98
|
+
"""Configuration for Debug Dojo."""
|
|
99
|
+
|
|
100
|
+
model_config = ConfigDict(extra="forbid") # pyright: ignore[reportUnannotatedClassAttribute]
|
|
101
|
+
|
|
102
|
+
debugger: DebuggerType = DebuggerType.PUDB
|
|
103
|
+
"""The type of debugger to use."""
|
|
104
|
+
features: Features = Features()
|
|
105
|
+
"""Features to install for debugging."""
|
|
106
|
+
|
|
107
|
+
def update(self) -> DebugDojoConfigV2:
|
|
108
|
+
"""Update the configuration to the latest version."""
|
|
109
|
+
v2_exceptions = ExceptionsConfig(
|
|
110
|
+
rich_traceback=self.features.rich_traceback,
|
|
111
|
+
)
|
|
112
|
+
v2_debuggers = DebuggersConfig(default=self.debugger)
|
|
113
|
+
v2_features = FeaturesConfig(
|
|
114
|
+
rich_inspect="i" if self.features.rich_inspect else "",
|
|
115
|
+
rich_print="p" if self.features.rich_print else "",
|
|
116
|
+
comparer="c" if self.features.comparer else "",
|
|
117
|
+
breakpoint="b" if self.features.breakpoint else "",
|
|
118
|
+
)
|
|
119
|
+
return DebugDojoConfigV2(
|
|
120
|
+
exceptions=v2_exceptions,
|
|
121
|
+
debuggers=v2_debuggers,
|
|
122
|
+
features=v2_features,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class DebugDojoConfigV2(BaseModel):
|
|
127
|
+
"""Configuration for Debug Dojo."""
|
|
128
|
+
|
|
129
|
+
model_config = ConfigDict(extra="forbid") # pyright: ignore[reportUnannotatedClassAttribute]
|
|
130
|
+
|
|
131
|
+
exceptions: ExceptionsConfig = ExceptionsConfig()
|
|
132
|
+
debuggers: DebuggersConfig = DebuggersConfig()
|
|
133
|
+
"""Default debugger and configs."""
|
|
134
|
+
features: FeaturesConfig = FeaturesConfig()
|
|
135
|
+
"""Features mnemonics ."""
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
DebugDojoConfig = DebugDojoConfigV2
|
|
@@ -14,7 +14,13 @@ import sys
|
|
|
14
14
|
from rich import print as rich_print
|
|
15
15
|
|
|
16
16
|
from ._compareres import inspect_objects_side_by_side
|
|
17
|
-
from .
|
|
17
|
+
from ._config_models import (
|
|
18
|
+
DebugDojoConfig,
|
|
19
|
+
DebuggersConfig,
|
|
20
|
+
DebuggerType,
|
|
21
|
+
ExceptionsConfig,
|
|
22
|
+
FeaturesConfig,
|
|
23
|
+
)
|
|
18
24
|
|
|
19
25
|
BREAKPOINT_ENV_VAR = "PYTHONBREAKPOINT"
|
|
20
26
|
|
|
@@ -69,11 +75,11 @@ def _use_debugpy() -> None:
|
|
|
69
75
|
debugpy.wait_for_client()
|
|
70
76
|
|
|
71
77
|
|
|
72
|
-
def _rich_traceback() -> None:
|
|
78
|
+
def _rich_traceback(*, locals_in_traceback: bool) -> None:
|
|
73
79
|
"""Check if Rich Traceback is available and set it as the default."""
|
|
74
80
|
from rich import traceback
|
|
75
81
|
|
|
76
|
-
_ = traceback.install(show_locals=
|
|
82
|
+
_ = traceback.install(show_locals=locals_in_traceback)
|
|
77
83
|
|
|
78
84
|
|
|
79
85
|
def _inspect() -> None:
|
|
@@ -106,33 +112,42 @@ def _rich_print() -> None:
|
|
|
106
112
|
builtins.p = rich_print # pyright: ignore[reportAttributeAccessIssue]
|
|
107
113
|
|
|
108
114
|
|
|
109
|
-
def _install_features(features:
|
|
115
|
+
def _install_features(features: FeaturesConfig) -> None:
|
|
110
116
|
"""Install the specified debugging features."""
|
|
111
117
|
if features.rich_inspect:
|
|
112
118
|
_inspect()
|
|
113
119
|
if features.rich_print:
|
|
114
120
|
_rich_print()
|
|
115
|
-
if features.rich_traceback:
|
|
116
|
-
_rich_traceback()
|
|
117
121
|
if features.comparer:
|
|
118
122
|
_compare()
|
|
119
123
|
if features.breakpoint:
|
|
120
124
|
_breakpoint()
|
|
121
125
|
|
|
122
126
|
|
|
123
|
-
def _set_debugger(
|
|
127
|
+
def _set_debugger(debugger_config: DebuggersConfig) -> None:
|
|
124
128
|
"""Set the debugger based on the configuration."""
|
|
129
|
+
debugger = debugger_config.default
|
|
130
|
+
|
|
125
131
|
if debugger == DebuggerType.PDB:
|
|
126
|
-
|
|
132
|
+
_use_pdb()
|
|
127
133
|
if debugger == DebuggerType.PUDB:
|
|
128
|
-
|
|
134
|
+
_use_pudb()
|
|
129
135
|
if debugger == DebuggerType.IPDB:
|
|
130
|
-
|
|
136
|
+
_use_ipdb()
|
|
131
137
|
if debugger == DebuggerType.DEBUGPY:
|
|
132
|
-
|
|
138
|
+
_use_debugpy()
|
|
139
|
+
|
|
140
|
+
sys.ps1 = debugger_config.prompt_name
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def _set_exceptions(exceptions: ExceptionsConfig) -> None:
|
|
144
|
+
"""Set the exception handling based on the configuration."""
|
|
145
|
+
if exceptions.rich_traceback:
|
|
146
|
+
_rich_traceback(locals_in_traceback=exceptions.locals_in_traceback)
|
|
133
147
|
|
|
134
148
|
|
|
135
149
|
def install_by_config(config: DebugDojoConfig) -> None:
|
|
136
150
|
"""Install debugging tools."""
|
|
137
|
-
_set_debugger(config.
|
|
151
|
+
_set_debugger(config.debuggers)
|
|
152
|
+
_set_exceptions(config.exceptions)
|
|
138
153
|
_install_features(config.features)
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
|
|
3
|
-
from enum import Enum
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Any, cast
|
|
6
|
-
|
|
7
|
-
import tomlkit
|
|
8
|
-
from pydantic import BaseModel, ConfigDict
|
|
9
|
-
from rich import print as rich_print
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class DebuggerType(Enum):
|
|
13
|
-
"""Enum for different types of debuggers."""
|
|
14
|
-
|
|
15
|
-
PDB = "pdb"
|
|
16
|
-
PUDB = "pudb"
|
|
17
|
-
IPDB = "ipdb"
|
|
18
|
-
DEBUGPY = "debugpy"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
class Features(BaseModel):
|
|
22
|
-
"""Configuration for installing debug features."""
|
|
23
|
-
|
|
24
|
-
model_config = ConfigDict(extra="forbid") # pyright: ignore[reportUnannotatedClassAttribute]
|
|
25
|
-
|
|
26
|
-
rich_inspect: bool = True
|
|
27
|
-
"""Install rich inspect as 'i' for enhanced object inspection."""
|
|
28
|
-
rich_print: bool = True
|
|
29
|
-
"""Install rich print as 'p' for enhanced printing."""
|
|
30
|
-
rich_traceback: bool = True
|
|
31
|
-
"""Install rich traceback for better error reporting."""
|
|
32
|
-
comparer: bool = True
|
|
33
|
-
"""Install comparer as 'c' for side-by-side object comparison."""
|
|
34
|
-
breakpoint: bool = True
|
|
35
|
-
"""Install breakpoint as 'b' for setting breakpoints in code."""
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class DebugDojoConfig(BaseModel):
|
|
39
|
-
"""Configuration for Debug Dojo."""
|
|
40
|
-
|
|
41
|
-
model_config = ConfigDict(extra="forbid") # pyright: ignore[reportUnannotatedClassAttribute]
|
|
42
|
-
|
|
43
|
-
debugger: DebuggerType = DebuggerType.PUDB
|
|
44
|
-
"""The type of debugger to use."""
|
|
45
|
-
features: Features = Features()
|
|
46
|
-
"""Features to install for debugging."""
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
def resolve_config_path(config_path: Path | None) -> Path | None:
|
|
50
|
-
"""Resolve the configuration path, returning a default if none is provided."""
|
|
51
|
-
if config_path:
|
|
52
|
-
if not config_path.exists():
|
|
53
|
-
msg = f"Configuration file not found:\n{config_path.resolve()}"
|
|
54
|
-
raise FileNotFoundError(msg)
|
|
55
|
-
return config_path
|
|
56
|
-
|
|
57
|
-
# Default configuration path
|
|
58
|
-
for path in (Path("dojo.toml"), Path("pyproject.toml")):
|
|
59
|
-
if path.exists():
|
|
60
|
-
return path
|
|
61
|
-
return None
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
def load_raw_config(
|
|
65
|
-
config_path: Path,
|
|
66
|
-
) -> dict[str, Any]: # pyright: ignore[reportExplicitAny]
|
|
67
|
-
"""Load the Debug Dojo configuration from a file.
|
|
68
|
-
|
|
69
|
-
Currently supports 'dojo.toml' or 'pyproject.toml'.
|
|
70
|
-
If no path is provided, it checks the current directory for these files.
|
|
71
|
-
"""
|
|
72
|
-
with config_path.open("rb") as f:
|
|
73
|
-
config_data = tomlkit.load(f).unwrap()
|
|
74
|
-
|
|
75
|
-
# If config is in [tool.debug_dojo] (pyproject.toml), extract it.
|
|
76
|
-
if config_path.name == "dojo.toml":
|
|
77
|
-
return config_data
|
|
78
|
-
|
|
79
|
-
if config_path.name == "pyproject.toml":
|
|
80
|
-
try:
|
|
81
|
-
dojo_config = cast(
|
|
82
|
-
"dict[str, Any]", # pyright: ignore[reportExplicitAny]
|
|
83
|
-
config_data["tool"]["debug_dojo"],
|
|
84
|
-
)
|
|
85
|
-
except KeyError:
|
|
86
|
-
return {}
|
|
87
|
-
else:
|
|
88
|
-
return dojo_config
|
|
89
|
-
|
|
90
|
-
# If the file is not recognized, raise an error.
|
|
91
|
-
msg = (
|
|
92
|
-
f"Unsupported configuration file: \n{config_path.resolve()}\n"
|
|
93
|
-
"Expected 'dojo.toml' or 'pyproject.toml'."
|
|
94
|
-
)
|
|
95
|
-
raise ValueError(msg)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
def load_config(
|
|
99
|
-
config_path: Path | None = None,
|
|
100
|
-
*,
|
|
101
|
-
verbose: bool = False,
|
|
102
|
-
) -> DebugDojoConfig:
|
|
103
|
-
"""Load the Debug Dojo configuration and return a DebugDojoConfig instance."""
|
|
104
|
-
resolved_path = resolve_config_path(config_path)
|
|
105
|
-
|
|
106
|
-
if verbose:
|
|
107
|
-
if resolved_path:
|
|
108
|
-
msg = f"Using configuration file: {resolved_path.resolve()}."
|
|
109
|
-
else:
|
|
110
|
-
msg = "No configuration file found, using default settings."
|
|
111
|
-
rich_print(f"[blue]{msg}[/blue]")
|
|
112
|
-
|
|
113
|
-
if not resolved_path:
|
|
114
|
-
return DebugDojoConfig()
|
|
115
|
-
|
|
116
|
-
raw_config = load_raw_config(resolved_path)
|
|
117
|
-
return DebugDojoConfig.model_validate(raw_config)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|