textual-debugger 0.0.3__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.
Files changed (55) hide show
  1. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/PKG-INFO +98 -51
  2. {textual_debugger-0.0.3/src/tdb → textual_debugger-0.1.0}/README.md +96 -50
  3. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/pyproject.toml +24 -2
  4. {textual_debugger-0.0.3 → textual_debugger-0.1.0/src/tdb}/README.md +96 -50
  5. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/__init__.py +1 -1
  6. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/app.py +15 -1
  7. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/cli.py +53 -15
  8. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/keybindings/__init__.py +8 -8
  9. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/session/controller.py +123 -76
  10. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/code_view.py +13 -7
  11. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/textual_debugger.egg-info/PKG-INFO +98 -51
  12. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/textual_debugger.egg-info/requires.txt +1 -0
  13. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/LICENSE +0 -0
  14. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/setup.cfg +0 -0
  15. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/__main__.py +0 -0
  16. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/app_handlers/__init__.py +0 -0
  17. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/app_handlers/dap_events.py +0 -0
  18. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/app_handlers/inspection.py +0 -0
  19. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/app_helpers.py +0 -0
  20. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/breakpoint_hook.py +0 -0
  21. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/dap/__init__.py +0 -0
  22. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/dap/client.py +0 -0
  23. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/dap/messages.py +0 -0
  24. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/dap/protocol.py +0 -0
  25. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/dap/types.py +0 -0
  26. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/inspection.py +0 -0
  27. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/persist.py +0 -0
  28. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/post_mortem.py +0 -0
  29. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/server/__init__.py +0 -0
  30. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/server/app.py +0 -0
  31. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/server/event_handler.py +0 -0
  32. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/server/handlers.py +0 -0
  33. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/server/rpc_types.py +0 -0
  34. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/server/runner.py +0 -0
  35. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/session/__init__.py +0 -0
  36. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/session/event_bus.py +0 -0
  37. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/session/messages.py +0 -0
  38. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/session/state.py +0 -0
  39. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/session/textual_handler.py +0 -0
  40. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/__init__.py +0 -0
  41. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/async_tasks_modal.py +0 -0
  42. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/breakpoint_view.py +0 -0
  43. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/console_view.py +0 -0
  44. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/evaluate_console.py +0 -0
  45. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/menu_bar.py +0 -0
  46. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/modals.py +0 -0
  47. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/processes_modal.py +0 -0
  48. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/stack_view.py +0 -0
  49. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/status_bar.py +0 -0
  50. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/threads_modal.py +0 -0
  51. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/tdb/widgets/variable_view.py +0 -0
  52. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/textual_debugger.egg-info/SOURCES.txt +0 -0
  53. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/textual_debugger.egg-info/dependency_links.txt +0 -0
  54. {textual_debugger-0.0.3 → textual_debugger-0.1.0}/src/textual_debugger.egg-info/entry_points.txt +0 -0
  55. {textual_debugger-0.0.3 → 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
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:
@@ -53,6 +53,7 @@ Requires-Dist: fastapi>=0.115.0
53
53
  Requires-Dist: uvicorn>=0.30.0
54
54
  Provides-Extra: dev
55
55
  Requires-Dist: pytest; extra == "dev"
56
+ Requires-Dist: pytest-cov; extra == "dev"
56
57
  Requires-Dist: pytest-asyncio; extra == "dev"
57
58
  Requires-Dist: httpx; extra == "dev"
58
59
  Requires-Dist: matplotlib; extra == "dev"
@@ -83,7 +84,7 @@ MIT License. Copyright 2026 by Al Danial.
83
84
 
84
85
  - supports debugging of synchronous, asynchronous, multi-threaded, and multi-process Python code.
85
86
  It specifically supports modules
86
- - `asyncio` (with a built-in async task inspector)
87
+ - `asyncio` (with a built-in async task inspector and task wait graph)
87
88
  - `threading` (with a thread inspector)
88
89
  - `multiprocessing` / `concurrent.futures` (with automatic child process attachment and a process inspector)
89
90
 
@@ -96,7 +97,7 @@ automated, headless debugging workflows and AI-assisted debugging
96
97
  built with `textual`, `prompt-toolkit`, `urwid`, `curses`, `rich`, and so on
97
98
 
98
99
  - comes with a post-mortem exception hook that can be installed in Python programs
99
- to have the debugger pop open automatically at the first uncaught exception
100
+ to have `tdb` pop open automatically at the first uncaught exception
100
101
 
101
102
  - can be entirely keyboard-driven
102
103
  making it suitable for operation in non-graphical environments (mouse support is
@@ -118,6 +119,18 @@ as open source.
118
119
  [Claude for Open Source](https://claude.com/contact-sales/claude-for-oss) program.
119
120
  `tdb` was made almost entirely with Claude Code.
120
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
+
121
134
  ## Installation
122
135
 
123
136
  ```bash
@@ -130,33 +143,52 @@ or (better):
130
143
  uv pip install textual-debugger
131
144
  ```
132
145
 
146
+ or run it without installing:
147
+
148
+ ```
149
+ uvx --from textual-debugger tdb my_program.py
150
+ ```
151
+
133
152
 
134
153
  ## Quick Start
135
154
 
136
155
  ```bash
137
- # Debug a script (stops at first line by default)
138
- tdb my_script.py
156
+ # show comprehensive documentation in a terminal-based Markdown viewer
157
+ tdb --doc
139
158
 
140
- # Debug with arguments
141
- tdb my_script.py arg1 arg2
159
+ # debug a script (stops at first line by default)
160
+ tdb my_program.py
142
161
 
143
- # Use a specific virtualenv
144
- tdb --python /path/to/venv/bin/python my_script.py
162
+ # debug with arguments
163
+ tdb my_program.py arg1 arg2
145
164
 
146
- # Don't stop on entry; run until first breakpoint or exit
147
- tdb --no-stop-on-entry my_script.py
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
148
167
 
149
- > **Note:** Avoid `argparse` confusion by separating `tdb` switches from
150
- > the debuggee's switches by prefixing the debuggee with `--`.
168
+ # use a specific virtualenv
169
+ tdb --python /path/to/venv/bin/python my_program.py
151
170
 
152
- # `--` separates tdb's switches from the debuggee's switches
153
- tdb --python /path/to/venv/bin/python -- my_script.py -f 17 --max 23.3
171
+ # step into, or stop at tracebacks in library code
172
+ tdb --no-just-my-code /path/to/venv/bin/python my_program.py
173
+
174
+ # run until first breakpoint or exit
175
+ tdb --no-stop-on-entry my_program.py
176
+
177
+ # run the debuggee in an external terminal
178
+ tdb --terminal xterm my_program.py
179
+
180
+ # attach to a remote Python program that has a debugpy server on port 5678
181
+ tdb -r remotehost:5678 my_program.py
182
+
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
154
186
  ```
155
187
 
156
- Or use the module entry point:
188
+ Alternatively, use the module entry point:
157
189
 
158
190
  ```bash
159
- python -m tdb my_script.py
191
+ python -m tdb my_program.py
160
192
  ```
161
193
 
162
194
  ## Layout
@@ -178,29 +210,18 @@ python -m tdb my_script.py
178
210
  └───────────────────────────────────────────────────────┘
179
211
  ```
180
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
+
181
217
  ## Features
182
218
 
183
219
  ### Navigation and Keybindings
184
220
 
221
+
185
222
  The Code View shows syntax-highlighted Python source with line numbers.
186
223
  A cursor line (blue) tracks your position; the current execution line is highlighted in gold.
187
224
 
188
- **Navigation (vim-style by default):**
189
-
190
- | Key | Action |
191
- |-----|--------|
192
- | `j` / `k` | Move cursor down / up |
193
- | `5j`, `10k` | Move N lines with count prefix |
194
- | `g` | Go to line (with count: `42g` jumps to line 42) |
195
- | `G` | Go to end of file |
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 between Navigation and Debug modes with `Escape`.
203
-
204
225
  **View focus shortcuts (global):**
205
226
 
206
227
  | Key | View |
@@ -225,6 +246,24 @@ Switch between Navigation and Debug modes with `Escape`.
225
246
  | `Alt+A` | Async Tasks |
226
247
  | `Alt+H` | Help (Documentation, About) |
227
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
+
228
267
  > **Note:** Many terminals send the byte sequence `ESC+f` for `Alt+F`, which Textual's
229
268
  ANSI parser rewrites to `Ctrl+Right` (the readline "forward-word" convention).
230
269
  `tdb` binds both so `Alt+F` works as expected regardless.
@@ -273,8 +312,7 @@ Breakpoints persist across session restarts.
273
312
 
274
313
  The Variable View shows a tree of scopes (Locals, Globals) with all variables in the current
275
314
  frame. Expand nodes to drill into complex objects. Children are loaded lazily on demand.
276
-
277
- Format: `name (type) = value`
315
+ Variable values can be changed in the Evaluate Console.
278
316
 
279
317
  ### Call Stack
280
318
 
@@ -301,11 +339,17 @@ A REPL at the bottom-left evaluates expressions in the current scope:
301
339
  (a, *p) : Join two or more pathname components...
302
340
  ```
303
341
 
342
+ Variable values set here are reflected in the running code.
343
+
304
344
  ### Console Output
305
345
 
306
346
  The Console View captures stdout (normal text) and stderr (red text) from the debuggee
307
347
  in real time.
308
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
+
309
353
  ### Crash Detection
310
354
 
311
355
  When the debuggee raises an unhandled exception, `tdb`:
@@ -353,7 +397,9 @@ memoization.
353
397
 
354
398
  ### Live Breakpoint Hook
355
399
 
356
- For the `pdb.set_trace()` use case--pausing at a specific line to inspect, then
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=
357
403
  continuing--use `tdb.breakpoint()`:
358
404
 
359
405
  ```python
@@ -499,17 +545,17 @@ print("tdb is attached!")
499
545
 
500
546
  When the debuggee runs and hits the `debugpy.wait_for_client()` line, it starts a
501
547
  debugpy server listening on port 5678.
502
- Attach `tdb` to it with the `-r` / `--remote-attach` switch, specifying the host and port.
548
+ Attach `tdb` to it with the `-r` switch, specifying the host and port.
503
549
  If the debuggee is on the same machine, you can omit the host or use `localhost`.
504
550
  This example assumes the debuggee runs on 192.168.1.10 and listens on port 5678:
505
551
 
506
552
  ```bash
507
553
  # Attach from tdb:
508
- tdb -r 5678
554
+ tdb -r 5678 # to localhost
509
555
  tdb -r 192.168.1.10:5678
510
556
 
511
557
  # With breakpoints:
512
- tdb -r 5678 -k my_script.py:42
558
+ tdb -r 5678 -k my_program.py:42
513
559
  ```
514
560
 
515
561
  All debugging features (breakpoints, stepping, variable inspection, threads, processes,
@@ -518,7 +564,7 @@ source file when the program stops.
518
564
 
519
565
  ### External Terminal Support
520
566
 
521
- Some Python programs, notably text user interfaces, make heavy use of terminal control
567
+ Some Python programs, notably text user interfaces, use terminal control
522
568
  codes and require direct access to the terminal to function properly.
523
569
  Such programs can be debugged with `tdb` by having it launch the debuggee in
524
570
  a separate terminal:
@@ -537,9 +583,9 @@ This feature only works in graphical environments where external terminals are a
537
583
  ### Keybinding Schemes
538
584
 
539
585
  ```bash
540
- tdb --keybindings vim my_script.py # default
541
- tdb --keybindings emacs my_script.py
542
- tdb --keybindings default my_script.py
586
+ tdb --keybindings vim my_program.py # default
587
+ tdb --keybindings emacs my_program.py
588
+ tdb --keybindings default my_program.py
543
589
  ```
544
590
 
545
591
  The keybinding choice is saved to `~/.config/tdb/config.json` and remembered for subsequent
@@ -553,7 +599,7 @@ debugging, CI pipelines, or AI-assisted debugging workflows.
553
599
  ### Headless Mode (no TUI)
554
600
 
555
601
  ```bash
556
- python -m tdb --headless my_script.py &
602
+ python -m tdb --headless my_program.py &
557
603
  ```
558
604
 
559
605
  The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
@@ -561,7 +607,7 @@ The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
561
607
  ### Dual Mode (TUI + server)
562
608
 
563
609
  ```bash
564
- tdb --server my_script.py
610
+ tdb --server my_program.py
565
611
  ```
566
612
 
567
613
  Both the interactive TUI and the JSON-RPC server run simultaneously.
@@ -643,18 +689,19 @@ Each is JSON with `event`, `data`, and `timestamp` fields.
643
689
  ## CLI Reference
644
690
 
645
691
  ```
646
- usage: tdb [-h] [-r [HOST:]PORT] [-k FILE:LINE] [--cwd CWD]
647
- [--no-stop-on-entry] [--no-just-my-code] [--no-subprocess]
648
- [--python PYTHON] [--keybindings {default,vim,emacs}]
692
+ usage: tdb [-h] [-v/--version] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
693
+ [--no-just-my-code] [--no-subprocess] [--python PYTHON]
694
+ [-d/--doc] [--doc-text] [--keybindings {default,vim,emacs}]
649
695
  [--terminal {xterm,konsole,gnome-terminal,ghostty,kitty,iterm2,warp,wezterm,terminator}]
650
- [--server] [--headless] [--server-port PORT]
696
+ [--server] [--headless] [-k FILE:LINE|LINE] [--server-port SERVER_PORT]
651
697
  [program] [args ...]
698
+
652
699
  ```
653
700
 
654
701
  | Flag | Description |
655
702
  |------|-------------|
656
- | `-r`, `--remote-attach HOST:PORT` | Attach to a remote debugpy server |
657
- | `-k`, `--breakpoint FILE:LINE` | Set a breakpoint (may be repeated) |
703
+ | `-r HOST:PORT` | Attach to a remote debugpy server |
704
+ | `-k`, `--breakpoint FILE:LINE|LINE` | Set a breakpoint (may be repeated) |
658
705
  | `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry) |
659
706
  | `--cwd DIR` | Working directory for the debuggee |
660
707
  | `--python PATH` | Python interpreter for the debuggee |
@@ -19,7 +19,7 @@ MIT License. Copyright 2026 by Al Danial.
19
19
 
20
20
  - supports debugging of synchronous, asynchronous, multi-threaded, and multi-process Python code.
21
21
  It specifically supports modules
22
- - `asyncio` (with a built-in async task inspector)
22
+ - `asyncio` (with a built-in async task inspector and task wait graph)
23
23
  - `threading` (with a thread inspector)
24
24
  - `multiprocessing` / `concurrent.futures` (with automatic child process attachment and a process inspector)
25
25
 
@@ -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 the debugger pop open automatically at the first uncaught exception
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
@@ -66,33 +78,52 @@ or (better):
66
78
  uv pip install textual-debugger
67
79
  ```
68
80
 
81
+ or run it without installing:
82
+
83
+ ```
84
+ uvx --from textual-debugger tdb my_program.py
85
+ ```
86
+
69
87
 
70
88
  ## Quick Start
71
89
 
72
90
  ```bash
73
- # Debug a script (stops at first line by default)
74
- tdb my_script.py
91
+ # show comprehensive documentation in a terminal-based Markdown viewer
92
+ tdb --doc
75
93
 
76
- # Debug with arguments
77
- tdb my_script.py arg1 arg2
94
+ # debug a script (stops at first line by default)
95
+ tdb my_program.py
78
96
 
79
- # Use a specific virtualenv
80
- tdb --python /path/to/venv/bin/python my_script.py
97
+ # debug with arguments
98
+ tdb my_program.py arg1 arg2
81
99
 
82
- # Don't stop on entry; run until first breakpoint or exit
83
- tdb --no-stop-on-entry my_script.py
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
84
102
 
85
- > **Note:** Avoid `argparse` confusion by separating `tdb` switches from
86
- > the debuggee's switches by prefixing the debuggee with `--`.
103
+ # use a specific virtualenv
104
+ tdb --python /path/to/venv/bin/python my_program.py
87
105
 
88
- # `--` separates tdb's switches from the debuggee's switches
89
- tdb --python /path/to/venv/bin/python -- my_script.py -f 17 --max 23.3
106
+ # step into, or stop at tracebacks in library code
107
+ tdb --no-just-my-code /path/to/venv/bin/python my_program.py
108
+
109
+ # run until first breakpoint or exit
110
+ tdb --no-stop-on-entry my_program.py
111
+
112
+ # run the debuggee in an external terminal
113
+ tdb --terminal xterm my_program.py
114
+
115
+ # attach to a remote Python program that has a debugpy server on port 5678
116
+ tdb -r remotehost:5678 my_program.py
117
+
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
90
121
  ```
91
122
 
92
- Or use the module entry point:
123
+ Alternatively, use the module entry point:
93
124
 
94
125
  ```bash
95
- python -m tdb my_script.py
126
+ python -m tdb my_program.py
96
127
  ```
97
128
 
98
129
  ## Layout
@@ -114,29 +145,18 @@ python -m tdb my_script.py
114
145
  └───────────────────────────────────────────────────────┘
115
146
  ```
116
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
+
117
152
  ## Features
118
153
 
119
154
  ### Navigation and Keybindings
120
155
 
156
+
121
157
  The Code View shows syntax-highlighted Python source with line numbers.
122
158
  A cursor line (blue) tracks your position; the current execution line is highlighted in gold.
123
159
 
124
- **Navigation (vim-style by default):**
125
-
126
- | Key | Action |
127
- |-----|--------|
128
- | `j` / `k` | Move cursor down / up |
129
- | `5j`, `10k` | Move N lines with count prefix |
130
- | `g` | Go to line (with count: `42g` jumps to line 42) |
131
- | `G` | Go to end of file |
132
- | `[` / `]` | Jump to previous / next paragraph boundary |
133
- | `/` | Search forward |
134
- | `?` | Search backward |
135
- | `n` / `N` | Next / previous search result |
136
- | `PageUp` / `PageDown` | Scroll by page |
137
-
138
- Switch between Navigation and Debug modes with `Escape`.
139
-
140
160
  **View focus shortcuts (global):**
141
161
 
142
162
  | Key | View |
@@ -161,6 +181,24 @@ Switch between Navigation and Debug modes with `Escape`.
161
181
  | `Alt+A` | Async Tasks |
162
182
  | `Alt+H` | Help (Documentation, About) |
163
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
+
164
202
  > **Note:** Many terminals send the byte sequence `ESC+f` for `Alt+F`, which Textual's
165
203
  ANSI parser rewrites to `Ctrl+Right` (the readline "forward-word" convention).
166
204
  `tdb` binds both so `Alt+F` works as expected regardless.
@@ -209,8 +247,7 @@ Breakpoints persist across session restarts.
209
247
 
210
248
  The Variable View shows a tree of scopes (Locals, Globals) with all variables in the current
211
249
  frame. Expand nodes to drill into complex objects. Children are loaded lazily on demand.
212
-
213
- Format: `name (type) = value`
250
+ Variable values can be changed in the Evaluate Console.
214
251
 
215
252
  ### Call Stack
216
253
 
@@ -237,11 +274,17 @@ A REPL at the bottom-left evaluates expressions in the current scope:
237
274
  (a, *p) : Join two or more pathname components...
238
275
  ```
239
276
 
277
+ Variable values set here are reflected in the running code.
278
+
240
279
  ### Console Output
241
280
 
242
281
  The Console View captures stdout (normal text) and stderr (red text) from the debuggee
243
282
  in real time.
244
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
+
245
288
  ### Crash Detection
246
289
 
247
290
  When the debuggee raises an unhandled exception, `tdb`:
@@ -289,7 +332,9 @@ memoization.
289
332
 
290
333
  ### Live Breakpoint Hook
291
334
 
292
- For the `pdb.set_trace()` use case--pausing at a specific line to inspect, then
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=
293
338
  continuing--use `tdb.breakpoint()`:
294
339
 
295
340
  ```python
@@ -435,17 +480,17 @@ print("tdb is attached!")
435
480
 
436
481
  When the debuggee runs and hits the `debugpy.wait_for_client()` line, it starts a
437
482
  debugpy server listening on port 5678.
438
- Attach `tdb` to it with the `-r` / `--remote-attach` switch, specifying the host and port.
483
+ Attach `tdb` to it with the `-r` switch, specifying the host and port.
439
484
  If the debuggee is on the same machine, you can omit the host or use `localhost`.
440
485
  This example assumes the debuggee runs on 192.168.1.10 and listens on port 5678:
441
486
 
442
487
  ```bash
443
488
  # Attach from tdb:
444
- tdb -r 5678
489
+ tdb -r 5678 # to localhost
445
490
  tdb -r 192.168.1.10:5678
446
491
 
447
492
  # With breakpoints:
448
- tdb -r 5678 -k my_script.py:42
493
+ tdb -r 5678 -k my_program.py:42
449
494
  ```
450
495
 
451
496
  All debugging features (breakpoints, stepping, variable inspection, threads, processes,
@@ -454,7 +499,7 @@ source file when the program stops.
454
499
 
455
500
  ### External Terminal Support
456
501
 
457
- Some Python programs, notably text user interfaces, make heavy use of terminal control
502
+ Some Python programs, notably text user interfaces, use terminal control
458
503
  codes and require direct access to the terminal to function properly.
459
504
  Such programs can be debugged with `tdb` by having it launch the debuggee in
460
505
  a separate terminal:
@@ -473,9 +518,9 @@ This feature only works in graphical environments where external terminals are a
473
518
  ### Keybinding Schemes
474
519
 
475
520
  ```bash
476
- tdb --keybindings vim my_script.py # default
477
- tdb --keybindings emacs my_script.py
478
- tdb --keybindings default my_script.py
521
+ tdb --keybindings vim my_program.py # default
522
+ tdb --keybindings emacs my_program.py
523
+ tdb --keybindings default my_program.py
479
524
  ```
480
525
 
481
526
  The keybinding choice is saved to `~/.config/tdb/config.json` and remembered for subsequent
@@ -489,7 +534,7 @@ debugging, CI pipelines, or AI-assisted debugging workflows.
489
534
  ### Headless Mode (no TUI)
490
535
 
491
536
  ```bash
492
- python -m tdb --headless my_script.py &
537
+ python -m tdb --headless my_program.py &
493
538
  ```
494
539
 
495
540
  The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
@@ -497,7 +542,7 @@ The server listens on `http://127.0.0.1:8150/rpc` (change with `--server-port`).
497
542
  ### Dual Mode (TUI + server)
498
543
 
499
544
  ```bash
500
- tdb --server my_script.py
545
+ tdb --server my_program.py
501
546
  ```
502
547
 
503
548
  Both the interactive TUI and the JSON-RPC server run simultaneously.
@@ -579,18 +624,19 @@ Each is JSON with `event`, `data`, and `timestamp` fields.
579
624
  ## CLI Reference
580
625
 
581
626
  ```
582
- usage: tdb [-h] [-r [HOST:]PORT] [-k FILE:LINE] [--cwd CWD]
583
- [--no-stop-on-entry] [--no-just-my-code] [--no-subprocess]
584
- [--python PYTHON] [--keybindings {default,vim,emacs}]
627
+ usage: tdb [-h] [-v/--version] [-r [HOST:]PORT] [--cwd CWD] [--no-stop-on-entry]
628
+ [--no-just-my-code] [--no-subprocess] [--python PYTHON]
629
+ [-d/--doc] [--doc-text] [--keybindings {default,vim,emacs}]
585
630
  [--terminal {xterm,konsole,gnome-terminal,ghostty,kitty,iterm2,warp,wezterm,terminator}]
586
- [--server] [--headless] [--server-port PORT]
631
+ [--server] [--headless] [-k FILE:LINE|LINE] [--server-port SERVER_PORT]
587
632
  [program] [args ...]
633
+
588
634
  ```
589
635
 
590
636
  | Flag | Description |
591
637
  |------|-------------|
592
- | `-r`, `--remote-attach HOST:PORT` | Attach to a remote debugpy server |
593
- | `-k`, `--breakpoint FILE:LINE` | Set a breakpoint (may be repeated) |
638
+ | `-r HOST:PORT` | Attach to a remote debugpy server |
639
+ | `-k`, `--breakpoint FILE:LINE|LINE` | Set a breakpoint (may be repeated) |
594
640
  | `--no-stop-on-entry` | Do not pause at the first line (default: stop on entry) |
595
641
  | `--cwd DIR` | Working directory for the debuggee |
596
642
  | `--python PATH` | Python interpreter for the debuggee |
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "textual-debugger"
3
- version = "0.0.3"
3
+ dynamic = ["version"]
4
4
  description = "A TUI Python debugger based on textual and debugpy"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.10"
@@ -29,7 +29,7 @@
29
29
 
30
30
  # extras needed to run the examples and tests
31
31
  [project.optional-dependencies]
32
- dev = ["pytest", "pytest-asyncio", "httpx",
32
+ dev = ["pytest", "pytest-cov", "pytest-asyncio", "httpx",
33
33
  "matplotlib",
34
34
  "pyyaml",
35
35
  "toml",
@@ -48,6 +48,9 @@
48
48
  requires = ["setuptools>=68.0"]
49
49
  build-backend = "setuptools.build_meta"
50
50
 
51
+ [tool.setuptools.dynamic]
52
+ version = {attr = "tdb.__version__"}
53
+
51
54
  [tool.setuptools.packages.find]
52
55
  where = ["src"]
53
56
 
@@ -57,6 +60,25 @@
57
60
  [tool.pytest.ini_options]
58
61
  testpaths = ["tests"]
59
62
  asyncio_mode = "auto"
63
+ addopts = "--cov=tdb --cov-report=term-missing"
60
64
  filterwarnings = [
61
65
  "ignore::DeprecationWarning",
62
66
  ]
67
+
68
+ [tool.coverage.run]
69
+ source = ["src/tdb"]
70
+ branch = true
71
+ omit = [
72
+ "*/tests/*",
73
+ "src/tdb/__main__.py",
74
+ ]
75
+
76
+ [tool.coverage.report]
77
+ exclude_lines = [
78
+ "pragma: no cover",
79
+ "raise NotImplementedError",
80
+ "if TYPE_CHECKING:",
81
+ "if __name__ == .__main__.:",
82
+ ]
83
+ show_missing = true
84
+ skip_covered = false