Skip to content

Commit 2f83905

Browse files
committed
Properly parse pdbcls from the configuration.
1 parent 8335503 commit 2f83905

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

docs/source/reference_guides/configuration.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,34 @@ paths = ["folder_1", "folder_2/task_2.py"]
191191
```
192192
````
193193

194+
````{confval} pdbcls
195+
196+
If you want to use a custom debugger instead of the standard Python debugger, you can
197+
specify it with the `pdbcls` option. The value must be in the format
198+
`module_name:class_name`.
199+
200+
```console
201+
$ pytask build --pdbcls=IPython.terminal.debugger:TerminalPdb
202+
```
203+
204+
Or, use the configuration file:
205+
206+
```toml
207+
pdbcls = "IPython.terminal.debugger:TerminalPdb"
208+
```
209+
210+
This is particularly useful when working with enhanced debuggers like `pdbpp` or `pdbp`
211+
that provide additional features such as syntax highlighting and tab completion:
212+
213+
```toml
214+
pdbcls = "pdbp:Pdb"
215+
```
216+
217+
The custom debugger will be used when you invoke the `--pdb` flag for post-mortem
218+
debugging or when using `breakpoint()` in your task code.
219+
220+
````
221+
194222
````{confval} show_errors_immediately
195223
196224
If you want to print the exception and tracebacks of errors as soon as they occur,

src/_pytask/debugging.py

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,42 @@ def pytask_extend_command_line_interface(cli: click.Group) -> None:
6060
cli.commands["build"].params.extend(additional_parameters)
6161

6262

63+
def _parse_pdbcls(value: str) -> tuple[str, str]:
64+
"""Parse and validate pdbcls string format."""
65+
split = value.split(":")
66+
if len(split) != 2: # noqa: PLR2004
67+
msg = (
68+
f"Invalid 'pdbcls' format: {value!r}. "
69+
"Must be like 'IPython.terminal.debugger:TerminalPdb'"
70+
)
71+
raise ValueError(msg)
72+
return tuple(split) # type: ignore[return-value]
73+
74+
6375
def _pdbcls_callback(
6476
ctx: click.Context, # noqa: ARG001
6577
name: str, # noqa: ARG001
6678
value: str | None,
6779
) -> tuple[str, str] | None:
6880
"""Validate the debugger class string passed to pdbcls."""
69-
message = "'pdbcls' must be like IPython.terminal.debugger:TerminalPdb"
70-
7181
if value is None:
7282
return None
73-
if isinstance(value, str):
74-
split = value.split(":")
75-
if len(split) != 2: # noqa: PLR2004
76-
raise click.BadParameter(message)
77-
return tuple(split) # type: ignore[return-value]
78-
raise click.BadParameter(message)
83+
try:
84+
return _parse_pdbcls(value)
85+
except ValueError as exc:
86+
raise click.BadParameter(str(exc)) from exc
87+
88+
89+
@hookimpl
90+
def pytask_parse_config(config: dict[str, Any]) -> None:
91+
"""Parse the debugger configuration.
92+
93+
Convert pdbcls from string format to tuple if it comes from config file.
94+
When pdbcls comes from CLI, it's already converted by _pdbcls_callback.
95+
"""
96+
pdbcls = config.get("pdbcls")
97+
if pdbcls and isinstance(pdbcls, str):
98+
config["pdbcls"] = _parse_pdbcls(pdbcls)
7999

80100

81101
@hookimpl(trylast=True)

0 commit comments

Comments
 (0)