textual-debugger 0.0.4__tar.gz → 0.1.1__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.
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/PKG-INFO +74 -46
- {textual_debugger-0.0.4/src/tdb → textual_debugger-0.1.1}/README.md +73 -45
- {textual_debugger-0.0.4 → textual_debugger-0.1.1/src/tdb}/README.md +73 -45
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/__init__.py +1 -1
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/app.py +15 -1
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/keybindings/__init__.py +8 -8
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/session/controller.py +123 -76
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/code_view.py +13 -7
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/textual_debugger.egg-info/PKG-INFO +74 -46
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/LICENSE +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/pyproject.toml +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/setup.cfg +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/__main__.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/app_handlers/__init__.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/app_handlers/dap_events.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/app_handlers/inspection.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/app_helpers.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/breakpoint_hook.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/cli.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/dap/__init__.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/dap/client.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/dap/messages.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/dap/protocol.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/dap/types.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/inspection.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/persist.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/post_mortem.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/server/__init__.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/server/app.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/server/event_handler.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/server/handlers.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/server/rpc_types.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/server/runner.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/session/__init__.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/session/event_bus.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/session/messages.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/session/state.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/session/textual_handler.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/__init__.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/async_tasks_modal.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/breakpoint_view.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/console_view.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/evaluate_console.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/menu_bar.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/modals.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/processes_modal.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/stack_view.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/status_bar.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/threads_modal.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/tdb/widgets/variable_view.py +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/textual_debugger.egg-info/SOURCES.txt +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/textual_debugger.egg-info/entry_points.txt +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/textual_debugger.egg-info/requires.txt +0 -0
- {textual_debugger-0.0.4 → textual_debugger-0.1.1}/src/textual_debugger.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: textual-debugger
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.1
|
|
4
4
|
Summary: A TUI Python debugger based on textual and debugpy
|
|
5
5
|
Author-email: Al Danial <al.danial@gmail.com>
|
|
6
6
|
License: textual-debugger is licensed to you under the MIT/X Consortium license:
|
|
@@ -63,7 +63,7 @@ Requires-Dist: ruff; extra == "dev"
|
|
|
63
63
|
Requires-Dist: ipython; extra == "dev"
|
|
64
64
|
Dynamic: license-file
|
|
65
65
|
|
|
66
|
-
# `textual-debugger`
|
|
66
|
+
# `textual-debugger`
|
|
67
67
|
|
|
68
68
|
`textual-debugger` (the package) provides `tdb` (the command-line tool and module),
|
|
69
69
|
a full-featured terminal-based Python debugger.
|
|
@@ -97,7 +97,7 @@ automated, headless debugging workflows and AI-assisted debugging
|
|
|
97
97
|
built with `textual`, `prompt-toolkit`, `urwid`, `curses`, `rich`, and so on
|
|
98
98
|
|
|
99
99
|
- comes with a post-mortem exception hook that can be installed in Python programs
|
|
100
|
-
to have
|
|
100
|
+
to have `tdb` pop open automatically at the first uncaught exception
|
|
101
101
|
|
|
102
102
|
- can be entirely keyboard-driven
|
|
103
103
|
making it suitable for operation in non-graphical environments (mouse support is
|
|
@@ -119,6 +119,20 @@ as open source.
|
|
|
119
119
|
[Claude for Open Source](https://claude.com/contact-sales/claude-for-oss) program.
|
|
120
120
|
`tdb` was made almost entirely with Claude Code.
|
|
121
121
|
|
|
122
|
+
## Gallery
|
|
123
|
+
<p align="center">
|
|
124
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/async_breakpoint.png" alt="at breakpoint" width="300">
|
|
125
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/async_task_graph.png" alt="task graph" width="300">
|
|
126
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/multiprocessing_process_3.png" alt="multiple processes" width="300">
|
|
127
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/threading_list.png" alt="thread list" width="300">
|
|
128
|
+
</p>
|
|
129
|
+
|
|
130
|
+
Videos:
|
|
131
|
+
- [tdb basics](https://youtu.be/2_qf2WZDHuA) views, keybindings, breakpoints, stepping, variable modification, call stack
|
|
132
|
+
- [asyncio tasks](https://youtu.be/vM4tODuqMGg) inspect asyncio tasks and their wait graph; code mod to allow pause
|
|
133
|
+
- [threads and processes](https://youtu.be/J8LOARLs2oQ) inspect variables and call stacks in multiple threads and processes
|
|
134
|
+
- [external terminal](https://youtu.be/121aihjAQ8g) run the debuggee in a separate terminal--ideal for debugging TUI applications
|
|
135
|
+
|
|
122
136
|
## Installation
|
|
123
137
|
|
|
124
138
|
```bash
|
|
@@ -134,7 +148,7 @@ uv pip install textual-debugger
|
|
|
134
148
|
or run it without installing:
|
|
135
149
|
|
|
136
150
|
```
|
|
137
|
-
uvx --from textual-debugger tdb
|
|
151
|
+
uvx --from textual-debugger tdb my_program.py
|
|
138
152
|
```
|
|
139
153
|
|
|
140
154
|
|
|
@@ -145,38 +159,38 @@ uvx --from textual-debugger tdb
|
|
|
145
159
|
tdb --doc
|
|
146
160
|
|
|
147
161
|
# debug a script (stops at first line by default)
|
|
148
|
-
tdb
|
|
162
|
+
tdb my_program.py
|
|
149
163
|
|
|
150
164
|
# debug with arguments
|
|
151
|
-
tdb
|
|
165
|
+
tdb my_program.py arg1 arg2
|
|
152
166
|
|
|
153
|
-
# add breakpoints at lines 20 and 35 of `
|
|
154
|
-
tdb -k 20 -k 35 -k module.py:14
|
|
167
|
+
# add breakpoints at lines 20 and 35 of `my_program.py` and line 14 of `module.py`
|
|
168
|
+
tdb -k 20 -k 35 -k module.py:14 my_program.py arg1 arg2
|
|
155
169
|
|
|
156
170
|
# use a specific virtualenv
|
|
157
|
-
tdb --python /path/to/venv/bin/python
|
|
171
|
+
tdb --python /path/to/venv/bin/python my_program.py
|
|
158
172
|
|
|
159
173
|
# step into, or stop at tracebacks in library code
|
|
160
|
-
tdb --no-just-my-code /path/to/venv/bin/python
|
|
174
|
+
tdb --no-just-my-code /path/to/venv/bin/python my_program.py
|
|
161
175
|
|
|
162
176
|
# run until first breakpoint or exit
|
|
163
|
-
tdb --no-stop-on-entry
|
|
177
|
+
tdb --no-stop-on-entry my_program.py
|
|
164
178
|
|
|
165
179
|
# run the debuggee in an external terminal
|
|
166
|
-
tdb --terminal xterm
|
|
180
|
+
tdb --terminal xterm my_program.py
|
|
167
181
|
|
|
168
182
|
# attach to a remote Python program that has a debugpy server on port 5678
|
|
169
|
-
tdb -r remotehost:5678
|
|
183
|
+
tdb -r remotehost:5678 my_program.py
|
|
170
184
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
tdb --python /path/to/venv/bin/python --
|
|
185
|
+
# prevent `argparse` confusion by separating `tdb` switches from
|
|
186
|
+
# the debuggee switches by prefixing the debuggee with `--`
|
|
187
|
+
tdb --python /path/to/venv/bin/python -- my_program.py -k 17 --max 23.3
|
|
174
188
|
```
|
|
175
189
|
|
|
176
|
-
|
|
190
|
+
Alternatively, use the module entry point:
|
|
177
191
|
|
|
178
192
|
```bash
|
|
179
|
-
python -m tdb
|
|
193
|
+
python -m tdb my_program.py
|
|
180
194
|
```
|
|
181
195
|
|
|
182
196
|
## Layout
|
|
@@ -198,29 +212,18 @@ python -m tdb my_script.py
|
|
|
198
212
|
└───────────────────────────────────────────────────────┘
|
|
199
213
|
```
|
|
200
214
|
|
|
215
|
+
The status bar shows the current execution state (running, paused,
|
|
216
|
+
breakpoint hit) and location.
|
|
217
|
+
The footer shows the most relevant keybindings for the current mode.
|
|
218
|
+
|
|
201
219
|
## Features
|
|
202
220
|
|
|
203
221
|
### Navigation and Keybindings
|
|
204
222
|
|
|
223
|
+
|
|
205
224
|
The Code View shows syntax-highlighted Python source with line numbers.
|
|
206
225
|
A cursor line (blue) tracks your position; the current execution line is highlighted in gold.
|
|
207
226
|
|
|
208
|
-
**Navigation (vim-style by default):**
|
|
209
|
-
|
|
210
|
-
| Key | Action |
|
|
211
|
-
|-----|--------|
|
|
212
|
-
| `j` / `k` | Move cursor down / up |
|
|
213
|
-
| `5j`, `10k` | Move N lines with count prefix |
|
|
214
|
-
| `g` | Go to line (with count: `42g` jumps to line 42) |
|
|
215
|
-
| `G` | Go to end of file |
|
|
216
|
-
| `[` / `]` | Jump to previous / next paragraph boundary |
|
|
217
|
-
| `/` | Search forward |
|
|
218
|
-
| `?` | Search backward |
|
|
219
|
-
| `n` / `N` | Next / previous search result |
|
|
220
|
-
| `PageUp` / `PageDown` | Scroll by page |
|
|
221
|
-
|
|
222
|
-
Switch between Navigation and Debug modes with `Escape`.
|
|
223
|
-
|
|
224
227
|
**View focus shortcuts (global):**
|
|
225
228
|
|
|
226
229
|
| Key | View |
|
|
@@ -245,6 +248,24 @@ Switch between Navigation and Debug modes with `Escape`.
|
|
|
245
248
|
| `Alt+A` | Async Tasks |
|
|
246
249
|
| `Alt+H` | Help (Documentation, About) |
|
|
247
250
|
|
|
251
|
+
**Navigation (vim-style by default):**
|
|
252
|
+
|
|
253
|
+
By default the Code View is in Debug mode. Hit `Escape` to switch to Navigate mode
|
|
254
|
+
In Navigate mode, you can move around the file with the following keys:
|
|
255
|
+
|
|
256
|
+
| Key | Action |
|
|
257
|
+
|-----|--------|
|
|
258
|
+
| `j` / `k` | Move cursor down / up |
|
|
259
|
+
| `5j`, `10k` | Move N lines down / up with count prefix |
|
|
260
|
+
| `G` | Go to end of file (with count: `42G` jumps to line 42)|
|
|
261
|
+
| `[` / `]` | Jump to previous / next paragraph boundary |
|
|
262
|
+
| `/` | Search forward |
|
|
263
|
+
| `?` | Search backward |
|
|
264
|
+
| `n` / `N` | Next / previous search result |
|
|
265
|
+
| `PageUp` / `PageDown` | Scroll by page |
|
|
266
|
+
|
|
267
|
+
Switch from Navigate back to Debug mode with `Escape`.
|
|
268
|
+
|
|
248
269
|
> **Note:** Many terminals send the byte sequence `ESC+f` for `Alt+F`, which Textual's
|
|
249
270
|
ANSI parser rewrites to `Ctrl+Right` (the readline "forward-word" convention).
|
|
250
271
|
`tdb` binds both so `Alt+F` works as expected regardless.
|
|
@@ -293,8 +314,7 @@ Breakpoints persist across session restarts.
|
|
|
293
314
|
|
|
294
315
|
The Variable View shows a tree of scopes (Locals, Globals) with all variables in the current
|
|
295
316
|
frame. Expand nodes to drill into complex objects. Children are loaded lazily on demand.
|
|
296
|
-
|
|
297
|
-
Format: `name (type) = value`
|
|
317
|
+
Variable values can be changed in the Evaluate Console.
|
|
298
318
|
|
|
299
319
|
### Call Stack
|
|
300
320
|
|
|
@@ -321,11 +341,17 @@ A REPL at the bottom-left evaluates expressions in the current scope:
|
|
|
321
341
|
(a, *p) : Join two or more pathname components...
|
|
322
342
|
```
|
|
323
343
|
|
|
344
|
+
Variable values set here are reflected in the running code.
|
|
345
|
+
|
|
324
346
|
### Console Output
|
|
325
347
|
|
|
326
348
|
The Console View captures stdout (normal text) and stderr (red text) from the debuggee
|
|
327
349
|
in real time.
|
|
328
350
|
|
|
351
|
+
If your program prints a lot, or prompts for input, or uses colors or
|
|
352
|
+
terminal control codes, consider running it in an external terminal
|
|
353
|
+
with `--terminal` for the best experience.
|
|
354
|
+
|
|
329
355
|
### Crash Detection
|
|
330
356
|
|
|
331
357
|
When the debuggee raises an unhandled exception, `tdb`:
|
|
@@ -373,7 +399,9 @@ memoization.
|
|
|
373
399
|
|
|
374
400
|
### Live Breakpoint Hook
|
|
375
401
|
|
|
376
|
-
|
|
402
|
+
`tdb` has an improved implemenation of the standard `breakpoint()` function (or equivalently,
|
|
403
|
+
`pdb.set_trace()`) used to pause at a specific line to inspect, then
|
|
404
|
+
here=
|
|
377
405
|
continuing--use `tdb.breakpoint()`:
|
|
378
406
|
|
|
379
407
|
```python
|
|
@@ -519,7 +547,7 @@ print("tdb is attached!")
|
|
|
519
547
|
|
|
520
548
|
When the debuggee runs and hits the `debugpy.wait_for_client()` line, it starts a
|
|
521
549
|
debugpy server listening on port 5678.
|
|
522
|
-
Attach `tdb` to it with the `-r`
|
|
550
|
+
Attach `tdb` to it with the `-r` switch, specifying the host and port.
|
|
523
551
|
If the debuggee is on the same machine, you can omit the host or use `localhost`.
|
|
524
552
|
This example assumes the debuggee runs on 192.168.1.10 and listens on port 5678:
|
|
525
553
|
|
|
@@ -529,7 +557,7 @@ tdb -r 5678 # to localhost
|
|
|
529
557
|
tdb -r 192.168.1.10:5678
|
|
530
558
|
|
|
531
559
|
# With breakpoints:
|
|
532
|
-
tdb -r 5678 -k
|
|
560
|
+
tdb -r 5678 -k my_program.py:42
|
|
533
561
|
```
|
|
534
562
|
|
|
535
563
|
All debugging features (breakpoints, stepping, variable inspection, threads, processes,
|
|
@@ -538,7 +566,7 @@ source file when the program stops.
|
|
|
538
566
|
|
|
539
567
|
### External Terminal Support
|
|
540
568
|
|
|
541
|
-
Some Python programs, notably text user interfaces,
|
|
569
|
+
Some Python programs, notably text user interfaces, use terminal control
|
|
542
570
|
codes and require direct access to the terminal to function properly.
|
|
543
571
|
Such programs can be debugged with `tdb` by having it launch the debuggee in
|
|
544
572
|
a separate terminal:
|
|
@@ -557,9 +585,9 @@ This feature only works in graphical environments where external terminals are a
|
|
|
557
585
|
### Keybinding Schemes
|
|
558
586
|
|
|
559
587
|
```bash
|
|
560
|
-
tdb --keybindings vim
|
|
561
|
-
tdb --keybindings emacs
|
|
562
|
-
tdb --keybindings default
|
|
588
|
+
tdb --keybindings vim my_program.py # default
|
|
589
|
+
tdb --keybindings emacs my_program.py
|
|
590
|
+
tdb --keybindings default my_program.py
|
|
563
591
|
```
|
|
564
592
|
|
|
565
593
|
The keybinding choice is saved to `~/.config/tdb/config.json` and remembered for subsequent
|
|
@@ -573,7 +601,7 @@ debugging, CI pipelines, or AI-assisted debugging workflows.
|
|
|
573
601
|
### Headless Mode (no TUI)
|
|
574
602
|
|
|
575
603
|
```bash
|
|
576
|
-
python -m tdb --headless
|
|
604
|
+
python -m tdb --headless my_program.py &
|
|
577
605
|
```
|
|
578
606
|
|
|
579
607
|
The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
|
|
@@ -581,7 +609,7 @@ The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
|
|
|
581
609
|
### Dual Mode (TUI + server)
|
|
582
610
|
|
|
583
611
|
```bash
|
|
584
|
-
tdb --server
|
|
612
|
+
tdb --server my_program.py
|
|
585
613
|
```
|
|
586
614
|
|
|
587
615
|
Both the interactive TUI and the JSON-RPC server run simultaneously.
|
|
@@ -674,7 +702,7 @@ usage: tdb [-h] [-v/--version] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
674
702
|
|
|
675
703
|
| Flag | Description |
|
|
676
704
|
|------|-------------|
|
|
677
|
-
| `-r
|
|
705
|
+
| `-r HOST:PORT` | Attach to a remote debugpy server |
|
|
678
706
|
| `-k`, `--breakpoint FILE:LINE|LINE` | Set a breakpoint (may be repeated) |
|
|
679
707
|
| `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry) |
|
|
680
708
|
| `--cwd DIR` | Working directory for the debuggee |
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# `textual-debugger`
|
|
1
|
+
# `textual-debugger`
|
|
2
2
|
|
|
3
3
|
`textual-debugger` (the package) provides `tdb` (the command-line tool and module),
|
|
4
4
|
a full-featured terminal-based Python debugger.
|
|
@@ -32,7 +32,7 @@ automated, headless debugging workflows and AI-assisted debugging
|
|
|
32
32
|
built with `textual`, `prompt-toolkit`, `urwid`, `curses`, `rich`, and so on
|
|
33
33
|
|
|
34
34
|
- comes with a post-mortem exception hook that can be installed in Python programs
|
|
35
|
-
to have
|
|
35
|
+
to have `tdb` pop open automatically at the first uncaught exception
|
|
36
36
|
|
|
37
37
|
- can be entirely keyboard-driven
|
|
38
38
|
making it suitable for operation in non-graphical environments (mouse support is
|
|
@@ -54,6 +54,20 @@ as open source.
|
|
|
54
54
|
[Claude for Open Source](https://claude.com/contact-sales/claude-for-oss) program.
|
|
55
55
|
`tdb` was made almost entirely with Claude Code.
|
|
56
56
|
|
|
57
|
+
## Gallery
|
|
58
|
+
<p align="center">
|
|
59
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/async_breakpoint.png" alt="at breakpoint" width="300">
|
|
60
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/async_task_graph.png" alt="task graph" width="300">
|
|
61
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/multiprocessing_process_3.png" alt="multiple processes" width="300">
|
|
62
|
+
<img src="https://github.com/AlDanial/tdb/blob/main/gallery/threading_list.png" alt="thread list" width="300">
|
|
63
|
+
</p>
|
|
64
|
+
|
|
65
|
+
Videos:
|
|
66
|
+
- [tdb basics](https://youtu.be/2_qf2WZDHuA) views, keybindings, breakpoints, stepping, variable modification, call stack
|
|
67
|
+
- [asyncio tasks](https://youtu.be/vM4tODuqMGg) inspect asyncio tasks and their wait graph; code mod to allow pause
|
|
68
|
+
- [threads and processes](https://youtu.be/J8LOARLs2oQ) inspect variables and call stacks in multiple threads and processes
|
|
69
|
+
- [external terminal](https://youtu.be/121aihjAQ8g) run the debuggee in a separate terminal--ideal for debugging TUI applications
|
|
70
|
+
|
|
57
71
|
## Installation
|
|
58
72
|
|
|
59
73
|
```bash
|
|
@@ -69,7 +83,7 @@ uv pip install textual-debugger
|
|
|
69
83
|
or run it without installing:
|
|
70
84
|
|
|
71
85
|
```
|
|
72
|
-
uvx --from textual-debugger tdb
|
|
86
|
+
uvx --from textual-debugger tdb my_program.py
|
|
73
87
|
```
|
|
74
88
|
|
|
75
89
|
|
|
@@ -80,38 +94,38 @@ uvx --from textual-debugger tdb
|
|
|
80
94
|
tdb --doc
|
|
81
95
|
|
|
82
96
|
# debug a script (stops at first line by default)
|
|
83
|
-
tdb
|
|
97
|
+
tdb my_program.py
|
|
84
98
|
|
|
85
99
|
# debug with arguments
|
|
86
|
-
tdb
|
|
100
|
+
tdb my_program.py arg1 arg2
|
|
87
101
|
|
|
88
|
-
# add breakpoints at lines 20 and 35 of `
|
|
89
|
-
tdb -k 20 -k 35 -k module.py:14
|
|
102
|
+
# add breakpoints at lines 20 and 35 of `my_program.py` and line 14 of `module.py`
|
|
103
|
+
tdb -k 20 -k 35 -k module.py:14 my_program.py arg1 arg2
|
|
90
104
|
|
|
91
105
|
# use a specific virtualenv
|
|
92
|
-
tdb --python /path/to/venv/bin/python
|
|
106
|
+
tdb --python /path/to/venv/bin/python my_program.py
|
|
93
107
|
|
|
94
108
|
# step into, or stop at tracebacks in library code
|
|
95
|
-
tdb --no-just-my-code /path/to/venv/bin/python
|
|
109
|
+
tdb --no-just-my-code /path/to/venv/bin/python my_program.py
|
|
96
110
|
|
|
97
111
|
# run until first breakpoint or exit
|
|
98
|
-
tdb --no-stop-on-entry
|
|
112
|
+
tdb --no-stop-on-entry my_program.py
|
|
99
113
|
|
|
100
114
|
# run the debuggee in an external terminal
|
|
101
|
-
tdb --terminal xterm
|
|
115
|
+
tdb --terminal xterm my_program.py
|
|
102
116
|
|
|
103
117
|
# attach to a remote Python program that has a debugpy server on port 5678
|
|
104
|
-
tdb -r remotehost:5678
|
|
118
|
+
tdb -r remotehost:5678 my_program.py
|
|
105
119
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
tdb --python /path/to/venv/bin/python --
|
|
120
|
+
# prevent `argparse` confusion by separating `tdb` switches from
|
|
121
|
+
# the debuggee switches by prefixing the debuggee with `--`
|
|
122
|
+
tdb --python /path/to/venv/bin/python -- my_program.py -k 17 --max 23.3
|
|
109
123
|
```
|
|
110
124
|
|
|
111
|
-
|
|
125
|
+
Alternatively, use the module entry point:
|
|
112
126
|
|
|
113
127
|
```bash
|
|
114
|
-
python -m tdb
|
|
128
|
+
python -m tdb my_program.py
|
|
115
129
|
```
|
|
116
130
|
|
|
117
131
|
## Layout
|
|
@@ -133,29 +147,18 @@ python -m tdb my_script.py
|
|
|
133
147
|
└───────────────────────────────────────────────────────┘
|
|
134
148
|
```
|
|
135
149
|
|
|
150
|
+
The status bar shows the current execution state (running, paused,
|
|
151
|
+
breakpoint hit) and location.
|
|
152
|
+
The footer shows the most relevant keybindings for the current mode.
|
|
153
|
+
|
|
136
154
|
## Features
|
|
137
155
|
|
|
138
156
|
### Navigation and Keybindings
|
|
139
157
|
|
|
158
|
+
|
|
140
159
|
The Code View shows syntax-highlighted Python source with line numbers.
|
|
141
160
|
A cursor line (blue) tracks your position; the current execution line is highlighted in gold.
|
|
142
161
|
|
|
143
|
-
**Navigation (vim-style by default):**
|
|
144
|
-
|
|
145
|
-
| Key | Action |
|
|
146
|
-
|-----|--------|
|
|
147
|
-
| `j` / `k` | Move cursor down / up |
|
|
148
|
-
| `5j`, `10k` | Move N lines with count prefix |
|
|
149
|
-
| `g` | Go to line (with count: `42g` jumps to line 42) |
|
|
150
|
-
| `G` | Go to end of file |
|
|
151
|
-
| `[` / `]` | Jump to previous / next paragraph boundary |
|
|
152
|
-
| `/` | Search forward |
|
|
153
|
-
| `?` | Search backward |
|
|
154
|
-
| `n` / `N` | Next / previous search result |
|
|
155
|
-
| `PageUp` / `PageDown` | Scroll by page |
|
|
156
|
-
|
|
157
|
-
Switch between Navigation and Debug modes with `Escape`.
|
|
158
|
-
|
|
159
162
|
**View focus shortcuts (global):**
|
|
160
163
|
|
|
161
164
|
| Key | View |
|
|
@@ -180,6 +183,24 @@ Switch between Navigation and Debug modes with `Escape`.
|
|
|
180
183
|
| `Alt+A` | Async Tasks |
|
|
181
184
|
| `Alt+H` | Help (Documentation, About) |
|
|
182
185
|
|
|
186
|
+
**Navigation (vim-style by default):**
|
|
187
|
+
|
|
188
|
+
By default the Code View is in Debug mode. Hit `Escape` to switch to Navigate mode
|
|
189
|
+
In Navigate mode, you can move around the file with the following keys:
|
|
190
|
+
|
|
191
|
+
| Key | Action |
|
|
192
|
+
|-----|--------|
|
|
193
|
+
| `j` / `k` | Move cursor down / up |
|
|
194
|
+
| `5j`, `10k` | Move N lines down / up with count prefix |
|
|
195
|
+
| `G` | Go to end of file (with count: `42G` jumps to line 42)|
|
|
196
|
+
| `[` / `]` | Jump to previous / next paragraph boundary |
|
|
197
|
+
| `/` | Search forward |
|
|
198
|
+
| `?` | Search backward |
|
|
199
|
+
| `n` / `N` | Next / previous search result |
|
|
200
|
+
| `PageUp` / `PageDown` | Scroll by page |
|
|
201
|
+
|
|
202
|
+
Switch from Navigate back to Debug mode with `Escape`.
|
|
203
|
+
|
|
183
204
|
> **Note:** Many terminals send the byte sequence `ESC+f` for `Alt+F`, which Textual's
|
|
184
205
|
ANSI parser rewrites to `Ctrl+Right` (the readline "forward-word" convention).
|
|
185
206
|
`tdb` binds both so `Alt+F` works as expected regardless.
|
|
@@ -228,8 +249,7 @@ Breakpoints persist across session restarts.
|
|
|
228
249
|
|
|
229
250
|
The Variable View shows a tree of scopes (Locals, Globals) with all variables in the current
|
|
230
251
|
frame. Expand nodes to drill into complex objects. Children are loaded lazily on demand.
|
|
231
|
-
|
|
232
|
-
Format: `name (type) = value`
|
|
252
|
+
Variable values can be changed in the Evaluate Console.
|
|
233
253
|
|
|
234
254
|
### Call Stack
|
|
235
255
|
|
|
@@ -256,11 +276,17 @@ A REPL at the bottom-left evaluates expressions in the current scope:
|
|
|
256
276
|
(a, *p) : Join two or more pathname components...
|
|
257
277
|
```
|
|
258
278
|
|
|
279
|
+
Variable values set here are reflected in the running code.
|
|
280
|
+
|
|
259
281
|
### Console Output
|
|
260
282
|
|
|
261
283
|
The Console View captures stdout (normal text) and stderr (red text) from the debuggee
|
|
262
284
|
in real time.
|
|
263
285
|
|
|
286
|
+
If your program prints a lot, or prompts for input, or uses colors or
|
|
287
|
+
terminal control codes, consider running it in an external terminal
|
|
288
|
+
with `--terminal` for the best experience.
|
|
289
|
+
|
|
264
290
|
### Crash Detection
|
|
265
291
|
|
|
266
292
|
When the debuggee raises an unhandled exception, `tdb`:
|
|
@@ -308,7 +334,9 @@ memoization.
|
|
|
308
334
|
|
|
309
335
|
### Live Breakpoint Hook
|
|
310
336
|
|
|
311
|
-
|
|
337
|
+
`tdb` has an improved implemenation of the standard `breakpoint()` function (or equivalently,
|
|
338
|
+
`pdb.set_trace()`) used to pause at a specific line to inspect, then
|
|
339
|
+
here=
|
|
312
340
|
continuing--use `tdb.breakpoint()`:
|
|
313
341
|
|
|
314
342
|
```python
|
|
@@ -454,7 +482,7 @@ print("tdb is attached!")
|
|
|
454
482
|
|
|
455
483
|
When the debuggee runs and hits the `debugpy.wait_for_client()` line, it starts a
|
|
456
484
|
debugpy server listening on port 5678.
|
|
457
|
-
Attach `tdb` to it with the `-r`
|
|
485
|
+
Attach `tdb` to it with the `-r` switch, specifying the host and port.
|
|
458
486
|
If the debuggee is on the same machine, you can omit the host or use `localhost`.
|
|
459
487
|
This example assumes the debuggee runs on 192.168.1.10 and listens on port 5678:
|
|
460
488
|
|
|
@@ -464,7 +492,7 @@ tdb -r 5678 # to localhost
|
|
|
464
492
|
tdb -r 192.168.1.10:5678
|
|
465
493
|
|
|
466
494
|
# With breakpoints:
|
|
467
|
-
tdb -r 5678 -k
|
|
495
|
+
tdb -r 5678 -k my_program.py:42
|
|
468
496
|
```
|
|
469
497
|
|
|
470
498
|
All debugging features (breakpoints, stepping, variable inspection, threads, processes,
|
|
@@ -473,7 +501,7 @@ source file when the program stops.
|
|
|
473
501
|
|
|
474
502
|
### External Terminal Support
|
|
475
503
|
|
|
476
|
-
Some Python programs, notably text user interfaces,
|
|
504
|
+
Some Python programs, notably text user interfaces, use terminal control
|
|
477
505
|
codes and require direct access to the terminal to function properly.
|
|
478
506
|
Such programs can be debugged with `tdb` by having it launch the debuggee in
|
|
479
507
|
a separate terminal:
|
|
@@ -492,9 +520,9 @@ This feature only works in graphical environments where external terminals are a
|
|
|
492
520
|
### Keybinding Schemes
|
|
493
521
|
|
|
494
522
|
```bash
|
|
495
|
-
tdb --keybindings vim
|
|
496
|
-
tdb --keybindings emacs
|
|
497
|
-
tdb --keybindings default
|
|
523
|
+
tdb --keybindings vim my_program.py # default
|
|
524
|
+
tdb --keybindings emacs my_program.py
|
|
525
|
+
tdb --keybindings default my_program.py
|
|
498
526
|
```
|
|
499
527
|
|
|
500
528
|
The keybinding choice is saved to `~/.config/tdb/config.json` and remembered for subsequent
|
|
@@ -508,7 +536,7 @@ debugging, CI pipelines, or AI-assisted debugging workflows.
|
|
|
508
536
|
### Headless Mode (no TUI)
|
|
509
537
|
|
|
510
538
|
```bash
|
|
511
|
-
python -m tdb --headless
|
|
539
|
+
python -m tdb --headless my_program.py &
|
|
512
540
|
```
|
|
513
541
|
|
|
514
542
|
The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
|
|
@@ -516,7 +544,7 @@ The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
|
|
|
516
544
|
### Dual Mode (TUI + server)
|
|
517
545
|
|
|
518
546
|
```bash
|
|
519
|
-
tdb --server
|
|
547
|
+
tdb --server my_program.py
|
|
520
548
|
```
|
|
521
549
|
|
|
522
550
|
Both the interactive TUI and the JSON-RPC server run simultaneously.
|
|
@@ -609,7 +637,7 @@ usage: tdb [-h] [-v/--version] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
|
|
|
609
637
|
|
|
610
638
|
| Flag | Description |
|
|
611
639
|
|------|-------------|
|
|
612
|
-
| `-r
|
|
640
|
+
| `-r HOST:PORT` | Attach to a remote debugpy server |
|
|
613
641
|
| `-k`, `--breakpoint FILE:LINE|LINE` | Set a breakpoint (may be repeated) |
|
|
614
642
|
| `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry) |
|
|
615
643
|
| `--cwd DIR` | Working directory for the debuggee |
|