Skip to content

Commit 3d98726

Browse files
authored
Properly parse pdbcls from the configuration. (#718)
1 parent 8335503 commit 3d98726

File tree

3 files changed

+57
-9
lines changed

3 files changed

+57
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ releases are available on [PyPI](https://pypi.org/project/pytask) and
1414
- {pull}`708` updates mypy and fixes type issues.
1515
- {pull}`709` add uv pre-commit check.
1616
- {pull}`713` removes uv as a test dependency. Closes {issue}`712`. Thanks to {user}`erooke`!
17+
- {pull}`718` fixes {issue}`717` by properly parsing the `pdbcls` configuration option from config files. Thanks to {user}`MImmesberger` for the report!
1718

1819
## 0.5.5 - 2025-07-25
1920

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 & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,41 @@ 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 | None) -> tuple[str, str] | None:
64+
"""Parse and validate pdbcls string format."""
65+
if value is None:
66+
return None
67+
if isinstance(value, tuple) and len(value) == 2: # noqa: PLR2004
68+
return value
69+
if not isinstance(value, str):
70+
msg = "'pdbcls' must be a string in format 'module:classname', got {value!r}"
71+
raise TypeError(msg)
72+
split = value.split(":")
73+
if len(split) != 2: # noqa: PLR2004
74+
msg = (
75+
f"Invalid 'pdbcls' format: {value!r}. "
76+
"Must be like 'IPython.terminal.debugger:TerminalPdb'"
77+
)
78+
raise ValueError(msg)
79+
return tuple(split) # type: ignore[return-value]
80+
81+
6382
def _pdbcls_callback(
6483
ctx: click.Context, # noqa: ARG001
6584
name: str, # noqa: ARG001
6685
value: str | None,
6786
) -> tuple[str, str] | None:
6887
"""Validate the debugger class string passed to pdbcls."""
69-
message = "'pdbcls' must be like IPython.terminal.debugger:TerminalPdb"
88+
try:
89+
return _parse_pdbcls(value)
90+
except Exception as e:
91+
raise click.BadParameter(str(e)) from e
7092

71-
if value is None:
72-
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)
93+
94+
@hookimpl
95+
def pytask_parse_config(config: dict[str, Any]) -> None:
96+
"""Parse the debugger configuration."""
97+
config["pdbcls"] = _parse_pdbcls(config.get("pdbcls"))
7998

8099

81100
@hookimpl(trylast=True)

0 commit comments

Comments
 (0)