imgui_debugger 0.1.0__py3-none-any.whl

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.
@@ -0,0 +1,225 @@
1
+ Metadata-Version: 2.4
2
+ Name: imgui_debugger
3
+ Version: 0.1.0
4
+ Summary: A live variable inspector you can drop into any imgui-bundle widget.
5
+ Author-email: Flynn OConnell <flynnoconnell@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/FlynnOConnell/imgui_debugger
8
+ Project-URL: Source, https://github.com/FlynnOConnell/imgui_debugger
9
+ Project-URL: Issues, https://github.com/FlynnOConnell/imgui_debugger/issues
10
+ Keywords: imgui,imgui-bundle,hello-imgui,debugger,inspector,gui,widget
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Topic :: Software Development :: Debuggers
16
+ Classifier: Topic :: Software Development :: User Interfaces
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: imgui-bundle<2,>=1.92
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=7; extra == "dev"
23
+ Provides-Extra: docs
24
+ Requires-Dist: pillow>=9; extra == "docs"
25
+ Requires-Dist: numpy>=1.21; extra == "docs"
26
+ Dynamic: license-file
27
+
28
+ <h1 align="center">imgui_debugger</h1>
29
+
30
+ <p align="center">
31
+ <a href="https://pypi.org/project/imgui_debugger/"><img src="https://img.shields.io/pypi/v/imgui_debugger.svg" alt="PyPI version"></a>
32
+ <a href="https://pypi.org/project/imgui_debugger/"><img src="https://img.shields.io/badge/python-3.10%2B-blue.svg" alt="Python 3.10+"></a>
33
+ <a href="LICENSE"><img src="https://img.shields.io/pypi/l/imgui_debugger.svg" alt="License: MIT"></a>
34
+ </p>
35
+
36
+ <samp>
37
+ <p align="center">
38
+ A live <b>variable inspector</b> for any imgui-bundle widget
39
+ <br>
40
+ <br>
41
+ <a href="#install">install</a> ·
42
+ <a href="#quick-start">quick start</a> ·
43
+ <a href="#scopes">scopes</a> ·
44
+ <a href="#examples">examples</a> ·
45
+ <a href="#configuration-reference">configuration</a> ·
46
+ <a href="https://github.com/FlynnOConnell/imgui_debugger/issues">issues</a>
47
+ </p>
48
+ </samp>
49
+
50
+ ## About
51
+
52
+ Point it at a widget and it draws every variable that widget can see, grouped by
53
+ scope, in a collapsible tree that re-reads its values every frame:
54
+
55
+ - **instance** — the object's own `__dict__` and `__slots__`
56
+ - **properties** — `property` descriptors, evaluated live; one that raises shows
57
+ the exception instead of blanking the panel
58
+ - **class** — class attributes from the whole MRO
59
+ - **locals / globals** — the call frame you captured, so you can follow a draw
60
+ method's own variables
61
+ - **imgui** — io, mouse, keyboard, the window rect and the style metrics that
62
+ explain most layout bugs
63
+ - **watches** — anything else you promote to a top-level scope
64
+
65
+ Leaves that are a bool, number, string or color tuple get an inline editor that
66
+ writes straight back onto the object, so you can find the value that fixes the
67
+ layout without restarting the app.
68
+
69
+ It is built for widgets like the ones in
70
+ [mbo_utilities](https://github.com/MillerBrainObservatory/mbo_utilities) and
71
+ [masknmf-toolbox](https://github.com/apasarkar/masknmf-toolbox), but it knows
72
+ nothing about them — it works on any Python object.
73
+
74
+ ## Install
75
+
76
+ ```bash
77
+ pip install imgui_debugger
78
+ ```
79
+
80
+ The only dependency is `imgui-bundle` (which provides imgui, hello_imgui,
81
+ immapp and the FontAwesome icon font).
82
+
83
+ ## Quick start
84
+
85
+ Inspect one object in its own window, no host app needed:
86
+
87
+ ```python
88
+ from imgui_debugger import run_debugger
89
+
90
+ run_debugger({"fs": 9.6, "dz": 5.0, "planes": [1, 2, 3]})
91
+ ```
92
+
93
+ Add a debug window to a widget you already have:
94
+
95
+ ```python
96
+ from imgui_debugger import attach
97
+
98
+ class RoiWidget:
99
+ def __init__(self):
100
+ self.threshold = 0.4
101
+ self.debugger = attach(self, title="ROIs widget")
102
+
103
+ def update(self): # your per-frame draw
104
+ ...
105
+ self.debugger.capture() # follow this method's locals
106
+ self.debugger.render_window() # draw the debug window
107
+ ```
108
+
109
+ Or draw the tree inline, in a panel you already own:
110
+
111
+ ```python
112
+ self.debugger.render() # toolbar + tree at the current cursor
113
+ self.debugger.draw_tree() # tree only, no toolbar
114
+ ```
115
+
116
+ ## Scopes
117
+
118
+ `Debugger.scopes()` returns them in display order: the target's
119
+ `instance` / `properties` / `class`, then your watches, then `locals` /
120
+ `globals`, then `imgui`.
121
+
122
+ | scope | source | writable |
123
+ |-------|--------|----------|
124
+ | `instance` | `vars(obj)` + `__slots__` | yes |
125
+ | `properties` | `property` / `cached_property` on the MRO | only with an `fset` |
126
+ | `class` | class attributes, no methods or descriptors | yes |
127
+ | `locals` | the captured frame's `f_locals` | no (writes do not stick) |
128
+ | `globals` | the captured frame's `f_globals` | yes |
129
+ | `imgui` | `io`, `mouse`, `keyboard`, `window`, `style` | no |
130
+ | watches | `watch(name, value_or_callable)` | depends on the value |
131
+
132
+ A watch takes a value or a zero-argument callable; the callable is re-read every
133
+ frame, so `watch("metadata", lambda: self.metadata)` survives the attribute
134
+ being reassigned:
135
+
136
+ ```python
137
+ dbg.watch("metadata", lambda: self.metadata, role="prop")
138
+ dbg.watch("fps", lambda: {"now": imgui.get_io().framerate}, role="runtime")
139
+ ```
140
+
141
+ `watch_all(obj, ["metadata", "indices"])` does the same for several attributes
142
+ in one call.
143
+
144
+ ## Toolbar
145
+
146
+ | control | what it does |
147
+ |---------|--------------|
148
+ | filter | case-insensitive match over names and leaf values, recursing into children (bounded to 6 levels and 64 items per container, memoized per filter string) |
149
+ | expand / collapse | force every node open or shut for one frame |
150
+ | private | include `_name` attributes |
151
+ | edit | turn the inline editors off and read only |
152
+
153
+ ## Examples
154
+
155
+ See all examples in [`examples/`](examples/).
156
+
157
+ | name | file | what it shows |
158
+ |------|------|---------------|
159
+ | debug_minimal | [`debug_minimal.py`](examples/debug_minimal.py) | one-shot window over a settings dataclass |
160
+ | debug_widget | [`debug_widget.py`](examples/debug_widget.py) | a widget that owns its debugger, captures its own locals, and toggles it with F12 |
161
+ | debug_edge_window | [`debug_edge_window.py`](examples/debug_edge_window.py) | a fastplotlib `EdgeWindow`, the widget shape pml_utilities and masknmf-toolbox use |
162
+
163
+ ## Configuration reference
164
+
165
+ `DebuggerConfig` fields:
166
+
167
+ | field | default | purpose |
168
+ |-------|---------|---------|
169
+ | `target` | `None` | the object whose scopes come first |
170
+ | `title` | `"Debugger"` | header text and default window title |
171
+ | `theme` | `Theme.dark()` | colors |
172
+ | `private` | `False` | show `_name` attributes |
173
+ | `properties` | `True` | show the `properties` scope and expand nested properties |
174
+ | `class_attrs` | `True` | show the `class` scope |
175
+ | `editable` | `True` | inline editors for writable leaves |
176
+ | `show_frame` | `True` | show `locals` / `globals` |
177
+ | `show_runtime` | `True` | show the live `imgui` scope |
178
+ | `max_depth` | `8` | deepest level the tree expands |
179
+ | `max_items` | `200` | rows per container before "+N more" |
180
+ | `value_col` | `0.0` | pixel column values align at; `0` packs them after the name |
181
+ | `show_toolbar` | `True` | draw the filter box and toggles |
182
+ | `window_title`, `window_size`, `resizable` | — | OS window (one-shot mode) |
183
+ | `ini_path` | `~/.imgui_debugger/debugger.ini` | where the layout `.ini` is saved |
184
+ | `assets_folder` | `None` | folder providing the icon font; unset never overrides a host app's |
185
+
186
+ `attach(target, **kwargs)` and `run_debugger(target, **kwargs)` take any of
187
+ these as keyword arguments.
188
+
189
+ ## Files on disk
190
+
191
+ Everything the library writes lives under `~/.imgui_debugger/` (override with
192
+ the `IMGUI_DEBUGGER_HOME` env var):
193
+
194
+ | path | written by | purpose |
195
+ |------|-----------|---------|
196
+ | `~/.imgui_debugger/debugger.ini` | `run_debugger` | hello_imgui window layout. Override with `config.ini_path`; an embedding app's own `ini_filename` always wins. |
197
+ | `~/.imgui_debugger/assets/` | you (optional) | user assets folder. Never created automatically; added to hello_imgui's search path when the icon font cannot be resolved. |
198
+
199
+ Embedded use writes nothing: `render()` and `render_window()` only draw.
200
+
201
+ ## Notes
202
+
203
+ - Reads are guarded. A property that raises, a `__repr__` that raises, and a
204
+ container that changes size mid-frame all render as a row rather than
205
+ crashing the frame.
206
+ - Values are read fresh every frame, so the tree shows the state of the frame
207
+ you are looking at.
208
+ - Big containers are capped, not truncated silently: a "+N more" line says how
209
+ many rows were left out.
210
+ - Editing writes through the same setter the row was built from — `setattr` for
211
+ an attribute, `__setitem__` for a dict or list entry, the property's `fset`
212
+ for a property.
213
+
214
+ ## Acknowledgements
215
+
216
+ The tree rendering, the bounded memoized filter and the value formatting come
217
+ from the metadata inspector in
218
+ [mbo_utilities](https://github.com/MillerBrainObservatory/mbo_utilities) at the
219
+ [Miller Brain Observatory](https://github.com/MillerBrainObservatory). The
220
+ packaging, theming and one-shot harness follow
221
+ [imgui_data_loader](https://github.com/FlynnOConnell/imgui_data_loader).
222
+
223
+ ## License
224
+
225
+ MIT
@@ -0,0 +1,16 @@
1
+ imgui_debugger/__init__.py,sha256=WbZawVJSZiLGDoswiX4oZsLekxGCtbDUOLlgWeB8YaA,2057
2
+ imgui_debugger/_assets.py,sha256=5zYn5n-9K9tCrb6nRHpd9B7cMzCe05zG_97XjDsICHA,3435
3
+ imgui_debugger/debugger.py,sha256=lIKUYOV855DEn_2TbE1hnq6kTFAIY59YzrsFvWbaYQY,17254
4
+ imgui_debugger/edit.py,sha256=aA04je8-zL1rMavbtPMKcSbVUW9Vnh0jWofVGK3CMbY,3637
5
+ imgui_debugger/format.py,sha256=-fKzXTxv135G02CjyaYYdYiCZicx-qTxUr3n3eoavDE,3864
6
+ imgui_debugger/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
+ imgui_debugger/runner.py,sha256=0AF4eRxLsNg7yXn0_-PxklzCtsj9zEJ4Ce3pBCq1F_c,3180
8
+ imgui_debugger/scopes.py,sha256=xRrga7K5tRQtP5h-CgxVnQoyV4a4uaHujFqydiGLOeg,21437
9
+ imgui_debugger/search.py,sha256=dvtYtPl3jUtYZHfK5Q5n444FEb6mCIWvR4qhLO_rqeI,4379
10
+ imgui_debugger/theme.py,sha256=8kqMg06qFJg58ook1HwpD7Gewt5jlWAV_cqh7SLyg6g,3744
11
+ imgui_debugger/tree.py,sha256=-VapSyHjadDRPNIC8ocKgYZ4pX4uuY5zvUN5TO7CjME,8600
12
+ imgui_debugger-0.1.0.dist-info/licenses/LICENSE,sha256=_rnO3wYmX-Bj_IT2wH7723wGbissPGOu6-sDbmj6Jwg,1092
13
+ imgui_debugger-0.1.0.dist-info/METADATA,sha256=ABKbaJLYMn04PapmATG3UTB7tpkkFPgrVle5dc_uyac,9199
14
+ imgui_debugger-0.1.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
15
+ imgui_debugger-0.1.0.dist-info/top_level.txt,sha256=pXTVGXaXClxB7_eS61MN5hBrcczgQmzP25FBZMSAolc,15
16
+ imgui_debugger-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Flynn OConnell
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1 @@
1
+ imgui_debugger