mirror of
https://github.com/cool-RR/PySnooper.git
synced 2026-07-18 17:03:47 +00:00
variable changes are diffed and printed on the next trace event. the last line of a with block has no next event before __exit__, so its new/modified variables were dropped on python < 3.10 (3.10+ emits an extra block-exit line event that flushes them). flush the pending changes in __exit__, but only when a later event hasn't already captured the final state. track a per-frame 'pending' flag: a body line leaves changes pending, while the block-exit line event and non-line events (exception/return) clear it. so: - 3.10+ normal exit: the block-exit line event clears pending -> no double eval of repr/watch/custom_repr. - exceptional exit: skipped entirely (the exception events already captured, and this avoids replacing the user's exception from a callback). - one-line 'with snoop(): x=1': no trace event at all, so we still flush. - same with statement reused in a loop: the with line is resolved from f_lasti (reliable) instead of f_lineno at __enter__ (which can be a stale body line on 3.8/3.9), so every iteration's final value is reported. cleanup runs in finally so a failing callback can't strand frame references. tests: final line that modifies an existing var and creates a new one, the one-line body, no double repr eval, exceptional exit (exception survives, no extra snapshot, state cleaned), and a with block reused in a loop. ran the full suite on 3.9, 3.11 and 3.14. |
||
|---|---|---|
| .. | ||
| mini_toolbox | ||
| samples | ||
| test_multiple_files | ||
| test_utils | ||
| __init__.py | ||
| test_chinese.py | ||
| test_ended_by_exception.py | ||
| test_mini_toolbox.py | ||
| test_not_implemented.py | ||
| test_pysnooper.py | ||
| utils.py | ||