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