viztracer 1.0.4__tar.gz → 1.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.

Potentially problematic release.


This version of viztracer might be problematic. Click here for more details.

Files changed (146) hide show
  1. viztracer-1.1.0/PKG-INFO +316 -0
  2. {viztracer-1.0.4 → viztracer-1.1.0}/pyproject.toml +5 -4
  3. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/__init__.py +1 -1
  4. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/code_monkey.py +10 -13
  5. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/decorator.py +9 -12
  6. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/event_base.py +2 -2
  7. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/functree.py +7 -7
  8. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/main.py +9 -13
  9. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/snaptrace.c +14 -12
  10. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/util.c +1 -5
  11. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/vcompressor/vc_dump.c +4 -24
  12. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/vcompressor/vcompressor.c +13 -13
  13. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/patch.py +10 -6
  14. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/report_builder.py +8 -8
  15. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/snaptrace.pyi +8 -8
  16. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/util.py +1 -2
  17. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/viewer.py +5 -5
  18. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/vizlogging.py +1 -2
  19. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/vizplugin.py +3 -3
  20. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/viztracer.py +16 -16
  21. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/web_dist/index.html +1 -1
  22. viztracer-1.1.0/src/viztracer/web_dist/service_worker.js +279 -0
  23. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/web_dist/trace_processor +32 -31
  24. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/assets/MaterialSymbolsOutlined.woff2 +0 -0
  25. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/engine_bundle.js +3 -0
  26. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/frontend_bundle.js +5495 -0
  27. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/manifest.json +10 -8
  28. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/perfetto.css +5737 -0
  29. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/stdlib_docs.json +1 -0
  30. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/trace_config_utils.wasm +0 -0
  31. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/traceconv.wasm → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/trace_processor.wasm +0 -0
  32. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/trace_processor_memory64.wasm +0 -0
  33. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/trace_processor.wasm → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/traceconv.wasm +0 -0
  34. viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def/traceconv_bundle.js +2 -0
  35. viztracer-1.1.0/src/viztracer.egg-info/PKG-INFO +316 -0
  36. viztracer-1.1.0/src/viztracer.egg-info/SOURCES.txt +134 -0
  37. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_cmdline.py +3 -1
  38. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_multiprocess.py +29 -0
  39. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_patch.py +4 -0
  40. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_regression.py +25 -23
  41. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_torch.py +4 -3
  42. viztracer-1.0.4/PKG-INFO +0 -537
  43. viztracer-1.0.4/src/viztracer/web_dist/service_worker.js +0 -177
  44. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/assets/._MaterialSymbolsOutlined.woff2 +0 -0
  45. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/assets/MaterialSymbolsOutlined.woff2 +0 -0
  46. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/engine_bundle.js +0 -3
  47. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/frontend_bundle.js +0 -4994
  48. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/perfetto.css +0 -5133
  49. viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5/traceconv_bundle.js +0 -2
  50. viztracer-1.0.4/src/viztracer.egg-info/PKG-INFO +0 -537
  51. viztracer-1.0.4/src/viztracer.egg-info/SOURCES.txt +0 -132
  52. {viztracer-1.0.4 → viztracer-1.1.0}/LICENSE +0 -0
  53. {viztracer-1.0.4 → viztracer-1.1.0}/MANIFEST.in +0 -0
  54. {viztracer-1.0.4 → viztracer-1.1.0}/NOTICE.txt +0 -0
  55. {viztracer-1.0.4 → viztracer-1.1.0}/README.md +0 -0
  56. {viztracer-1.0.4 → viztracer-1.1.0}/setup.cfg +0 -0
  57. {viztracer-1.0.4 → viztracer-1.1.0}/setup.py +0 -0
  58. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/__main__.py +0 -0
  59. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/attach.py +0 -0
  60. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/attach_process/LICENSE +0 -0
  61. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/attach_process/__init__.py +0 -0
  62. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/attach_process/add_code_to_python_process.py +0 -0
  63. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/attach_process/attach_linux_amd64.so +0 -0
  64. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/attach_process/linux_and_mac/lldb_prepare.py +0 -0
  65. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/cellmagic.py +0 -0
  66. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/html/flamegraph.html +0 -0
  67. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/html/trace_viewer_embedder.html +0 -0
  68. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/html/trace_viewer_full.html +0 -0
  69. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/eventnode.c +0 -0
  70. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/eventnode.h +0 -0
  71. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/pythoncapi_compat.h +0 -0
  72. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/quicktime.c +0 -0
  73. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/quicktime.h +0 -0
  74. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/snaptrace.h +0 -0
  75. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/snaptrace_member.c +0 -0
  76. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/util.h +0 -0
  77. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/vcompressor/vc_dump.h +0 -0
  78. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/modules/vcompressor/vcompressor.h +0 -0
  79. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/vcompressor.pyi +0 -0
  80. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/vizcounter.py +0 -0
  81. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/vizevent.py +0 -0
  82. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/vizobject.py +0 -0
  83. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer/web_dist/LICENSE +0 -0
  84. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/Roboto-100.woff2 +0 -0
  85. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/Roboto-300.woff2 +0 -0
  86. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/Roboto-400.woff2 +0 -0
  87. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/Roboto-500.woff2 +0 -0
  88. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/RobotoCondensed-Light.woff2 +0 -0
  89. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/RobotoCondensed-Regular.woff2 +0 -0
  90. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/RobotoMono-Regular.woff2 +0 -0
  91. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/brand.png +0 -0
  92. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/catapult_trace_viewer.html +0 -0
  93. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/catapult_trace_viewer.js +0 -0
  94. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/favicon.png +0 -0
  95. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/logo-128.png +0 -0
  96. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/logo-3d.png +0 -0
  97. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_atrace.png +0 -0
  98. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_battery_counters.png +0 -0
  99. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_board_voltage.png +0 -0
  100. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_cpu_coarse.png +0 -0
  101. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_cpu_fine.png +0 -0
  102. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_cpu_freq.png +0 -0
  103. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_cpu_voltage.png +0 -0
  104. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_frame_timeline.png +0 -0
  105. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_ftrace.png +0 -0
  106. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_gpu_mem_total.png +0 -0
  107. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_java_heap_dump.png +0 -0
  108. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_lmk.png +0 -0
  109. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_logcat.png +0 -0
  110. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_long_trace.png +0 -0
  111. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_mem_hifreq.png +0 -0
  112. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_meminfo.png +0 -0
  113. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_native_heap_profiler.png +0 -0
  114. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_one_shot.png +0 -0
  115. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_profiling.png +0 -0
  116. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_ps_stats.png +0 -0
  117. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_ring_buf.png +0 -0
  118. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_syscalls.png +0 -0
  119. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/rec_vmstat.png +0 -0
  120. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/scheduling_latency.png +0 -0
  121. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/assets/vscode-icon.png +0 -0
  122. {viztracer-1.0.4/src/viztracer/web_dist/v47.0-02b2414d5 → viztracer-1.1.0/src/viztracer/web_dist/v52.0-6b9586def}/index.html +0 -0
  123. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer.egg-info/dependency_links.txt +0 -0
  124. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer.egg-info/entry_points.txt +0 -0
  125. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer.egg-info/requires.txt +0 -0
  126. {viztracer-1.0.4 → viztracer-1.1.0}/src/viztracer.egg-info/top_level.txt +0 -0
  127. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_basic.py +0 -0
  128. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_codemonkey.py +0 -0
  129. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_fastlog.py +0 -0
  130. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_functree.py +0 -0
  131. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_invalid.py +0 -0
  132. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_jupyter.py +0 -0
  133. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_logging.py +0 -0
  134. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_logsparse.py +0 -0
  135. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_multithread.py +0 -0
  136. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_performance.py +0 -0
  137. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_remote.py +0 -0
  138. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_report_builder.py +0 -0
  139. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_tracer.py +0 -0
  140. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_util.py +0 -0
  141. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_vcompressor.py +0 -0
  142. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_viewer.py +0 -0
  143. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_vizcounter.py +0 -0
  144. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_vizevent.py +0 -0
  145. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_vizobject.py +0 -0
  146. {viztracer-1.0.4 → viztracer-1.1.0}/tests/test_vizplugin.py +0 -0
@@ -0,0 +1,316 @@
1
+ Metadata-Version: 2.4
2
+ Name: viztracer
3
+ Version: 1.1.0
4
+ Summary: A debugging and profiling tool that can trace and visualize python code execution
5
+ Author-email: Tian Gao <gaogaotiantian@hotmail.com>
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/gaogaotiantian/viztracer
8
+ Project-URL: Documentation, https://viztracer.readthedocs.io
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Programming Language :: Python :: 3.10
11
+ Classifier: Programming Language :: Python :: 3.11
12
+ Classifier: Programming Language :: Python :: 3.12
13
+ Classifier: Programming Language :: Python :: 3.13
14
+ Classifier: Programming Language :: Python :: 3.14
15
+ Classifier: Programming Language :: Python :: Free Threading
16
+ Classifier: Programming Language :: Python :: Free Threading :: 3 - Stable
17
+ Classifier: Intended Audience :: Developers
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Operating System :: POSIX :: Linux
20
+ Classifier: Operating System :: Microsoft :: Windows
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Classifier: Topic :: Software Development :: Bug Tracking
23
+ Classifier: Topic :: System :: Logging
24
+ Requires-Python: >=3.10
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ License-File: NOTICE.txt
28
+ Requires-Dist: objprint>=0.3.0
29
+ Provides-Extra: full
30
+ Requires-Dist: orjson; extra == "full"
31
+ Dynamic: license-file
32
+
33
+ # VizTracer
34
+
35
+ [![build](https://github.com/gaogaotiantian/viztracer/workflows/build/badge.svg)](https://github.com/gaogaotiantian/viztracer/actions?query=workflow%3Abuild) [![flake8](https://github.com/gaogaotiantian/viztracer/workflows/lint/badge.svg)](https://github.com/gaogaotiantian/viztracer/actions?query=workflow%3ALint) [![readthedocs](https://img.shields.io/readthedocs/viztracer)](https://viztracer.readthedocs.io/en/stable/) [![coverage](https://img.shields.io/codecov/c/github/gaogaotiantian/viztracer)](https://codecov.io/gh/gaogaotiantian/viztracer) [![pypi](https://img.shields.io/pypi/v/viztracer.svg)](https://pypi.org/project/viztracer/) [![Visual Studio Marketplace Version](https://img.shields.io/visual-studio-marketplace/v/gaogaotiantian.viztracer-vscode?logo=visual-studio)](https://marketplace.visualstudio.com/items?itemName=gaogaotiantian.viztracer-vscode) [![support-version](https://img.shields.io/pypi/pyversions/viztracer)](https://img.shields.io/pypi/pyversions/viztracer) [![license](https://img.shields.io/github/license/gaogaotiantian/viztracer)](https://github.com/gaogaotiantian/viztracer/blob/master/LICENSE) [![commit](https://img.shields.io/github/last-commit/gaogaotiantian/viztracer)](https://github.com/gaogaotiantian/viztracer/commits/master) [![sponsor](https://img.shields.io/badge/%E2%9D%A4-Sponsor%20me-%23c96198?style=flat&logo=GitHub)](https://github.com/sponsors/gaogaotiantian)
36
+
37
+ VizTracer is a low-overhead logging/debugging/profiling tool that can trace and visualize your python code execution.
38
+
39
+ The front-end UI is powered by [Perfetto](https://perfetto.dev/). **Use "AWSD" to zoom/navigate**.
40
+ More help can be found in "Support - Controls".
41
+
42
+ [![example_img](https://github.com/gaogaotiantian/viztracer/blob/master/img/example.png)](https://github.com/gaogaotiantian/viztracer/blob/master/img/example.png)
43
+
44
+
45
+ ## Highlights
46
+
47
+ * Detailed function entry/exit information on timeline with source code
48
+ * Super easy to use, no source code change for most features, no package dependency
49
+ * Low overhead, probably the fastest tracer in the market
50
+ * Supports threading, multiprocessing, subprocess, async and PyTorch
51
+ * Powerful front-end, able to render GB-level trace smoothly
52
+ * Works on Linux/MacOS/Windows
53
+
54
+ ## Install
55
+
56
+ The preferred way to install VizTracer is via pip
57
+
58
+ ```sh
59
+ pip install viztracer
60
+ ```
61
+
62
+ ## Basic Usage
63
+
64
+ ### Command Line
65
+
66
+ ```sh
67
+ # Instead of "python3 my_script.py arg1 arg2"
68
+ viztracer my_script.py arg1 arg2
69
+ ```
70
+
71
+ <details>
72
+
73
+ <summary>
74
+ A <code>result.json</code> file will be generated, which you can open with <code>vizviewer</code>
75
+ </summary>
76
+
77
+ ```sh
78
+ # You can display all the files in a directory and open them in browser too
79
+ vizviewer ./
80
+ # For very large trace files, try external trace processor
81
+ vizviewer --use_external_processor result.json
82
+ ```
83
+
84
+ vizviewer will host an HTTP server on ``http://localhost:9001``. You can also open your browser and use that address.
85
+
86
+ If you do not want vizviewer to open the webbrowser automatically, you can use
87
+
88
+ ```sh
89
+ vizviewer --server_only result.json
90
+ ```
91
+
92
+ If you just need to bring up the trace report once, and do not want the persistent server, use
93
+
94
+ ```sh
95
+ vizviewer --once result.json
96
+ ```
97
+
98
+ </details>
99
+
100
+ ```sh
101
+ vizviewer result.json
102
+ ```
103
+
104
+ A [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=gaogaotiantian.viztracer-vscode)
105
+ is available to make your life even easier.
106
+
107
+ <p align="center">
108
+ <img src="https://github.com/gaogaotiantian/viztracer-vscode/raw/master/assets/demo.gif" />
109
+ </p>
110
+
111
+ <details>
112
+
113
+ <summary>
114
+ Add <code>--open</code> to open the reports right after tracing
115
+ </summary>
116
+
117
+ ```sh
118
+ viztracer --open my_script.py arg1 arg2
119
+ viztracer -o result.html --open my_script.py arg1 arg2
120
+ ```
121
+
122
+ </details>
123
+
124
+ <details>
125
+
126
+ <summary>
127
+ modules and console scripts(like <code>flask</code>) are supported as well
128
+ </summary>
129
+
130
+ ```sh
131
+ viztracer -m your_module
132
+ ```
133
+
134
+ ```sh
135
+ viztracer flask run
136
+ ```
137
+
138
+ </details>
139
+
140
+ ### Inline
141
+
142
+ You can also manually start/stop VizTracer in your script as well.
143
+
144
+ ```python
145
+ from viztracer import VizTracer
146
+
147
+ tracer = VizTracer()
148
+ tracer.start()
149
+ # Something happens here
150
+ tracer.stop()
151
+ tracer.save() # also takes output_file as an optional argument
152
+ ```
153
+
154
+ Or, you can do it with ```with``` statement
155
+
156
+ ```python
157
+ with VizTracer(output_file="optional.json") as tracer:
158
+ # Something happens here
159
+ ```
160
+
161
+ ### Jupyter
162
+
163
+ If you are using Jupyter, you can use viztracer cell magics.
164
+
165
+ ```python
166
+ # You need to load the extension first
167
+ %load_ext viztracer
168
+ ```
169
+
170
+ ```python
171
+ %%viztracer
172
+ # Your code after
173
+ ```
174
+
175
+ A ``VizTracer Report`` button will appear after the cell and you can click it to view the results
176
+
177
+ ### PyTorch
178
+
179
+ VizTracer can log native calls and GPU events of PyTorch (based on `torch.profiler`) with
180
+ ``--log_torch``.
181
+
182
+ ```python
183
+ with VizTracer(log_torch=True) as tracer:
184
+ # Your torch code
185
+ ```
186
+
187
+ ```sh
188
+ viztracer --log_torch your_model.py
189
+ ```
190
+
191
+ ## Advanced Usage
192
+
193
+ ### Trace Filter
194
+
195
+ VizTracer can filter out the data you don't want to reduce overhead and keep info of a longer time period before you dump the log.
196
+
197
+ * [Min Duration](https://viztracer.readthedocs.io/en/stable/filter.html#min-duration)
198
+ * [Max Stack Depth](https://viztracer.readthedocs.io/en/stable/filter.html#max-stack-depth)
199
+ * [Include Files](https://viztracer.readthedocs.io/en/stable/filter.html#include-files)
200
+ * [Exclude Files](https://viztracer.readthedocs.io/en/stable/filter.html#exclude-files)
201
+ * [Ignore C Function](https://viztracer.readthedocs.io/en/stable/filter.html#ignore-c-function)
202
+ * [Sparse Log](https://viztracer.readthedocs.io/en/stable/filter.html#log-sparse)
203
+
204
+ ### Extra Logs without Code Change
205
+
206
+ VizTracer can log extra information without changing your source code
207
+
208
+ * [Any Variable/Attribute with RegEx](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-variable)
209
+ * [Function Entry](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-function-entry)
210
+ * [Variables in Specified Function](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-function-execution)
211
+ * [Garbage Collector Operation](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-garbage-collector)
212
+ * [Function Input Arguments](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-function-arguments)
213
+ * [Function Return Value](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-function-return-value)
214
+ * [Audit Events](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-audit)
215
+ * [Raised Exceptions](https://viztracer.readthedocs.io/en/stable/extra_log.html#log-exception)
216
+
217
+ ### Add Custom Event
218
+
219
+ VizTracer supports inserting custom events while the program is running. This works like a print debug, but you can know when this print happens while looking at trace data.
220
+
221
+ * [Instant Event](https://viztracer.readthedocs.io/en/stable/custom_event_intro.html#instant-event)
222
+ * [Variable Event](https://viztracer.readthedocs.io/en/stable/custom_event_intro.html#variable-event)
223
+ * [Duration Event](https://viztracer.readthedocs.io/en/stable/custom_event_intro.html#duration-event)
224
+
225
+ ## Misc
226
+
227
+ ### Multi Thread Support
228
+
229
+ For Python3.12+, VizTracer supports Python-level multi-thread tracing without the need to do any modification to your code.
230
+
231
+ For versions before 3.12, VizTracer supports python native ```threading``` module. Just start ```VizTracer``` before you create threads and it will just work.
232
+
233
+ For other multi-thread scenarios, you can use ``enable_thread_tracing()`` to notice VizTracer about the thread to trace it.
234
+
235
+ [![example_img](https://github.com/gaogaotiantian/viztracer/blob/master/img/multithread_example.png)](https://github.com/gaogaotiantian/viztracer/blob/master/img/multithread_example.png)
236
+
237
+ Refer to [multi thread docs](https://viztracer.readthedocs.io/en/stable/concurrency.html) for details
238
+
239
+
240
+ ### Multi Process Support
241
+
242
+ VizTracer supports ```subprocess```, ```multiprocessing```, ```os.fork()```, ```concurrent.futures```, and ```loky``` out of the box.
243
+
244
+ For more general multi-process cases, VizTracer can support with some extra steps.
245
+
246
+ [![example_img](https://github.com/gaogaotiantian/viztracer/blob/master/img/multiprocess_example.png)](https://github.com/gaogaotiantian/viztracer/blob/master/img/multiprocess_example.png)
247
+
248
+ Refer to [multi process docs](https://viztracer.readthedocs.io/en/stable/concurrency.html) for details
249
+
250
+ ### Async Support
251
+
252
+ VizTracer supports ```asyncio``` natively, but could enhance the report by using ```--log_async```.
253
+
254
+ [![example_img](https://github.com/gaogaotiantian/viztracer/blob/master/img/async_example.png)](https://github.com/gaogaotiantian/viztracer/blob/master/img/async_example.png)
255
+
256
+ Refer to [async docs](https://viztracer.readthedocs.io/en/stable/concurrency.html) for details
257
+
258
+ ### Flamegraph
259
+
260
+ Perfetto supports native flamegraph, just select slices on the UI and choose "Slice Flamegraph".
261
+
262
+ [![example_img](https://github.com/gaogaotiantian/viztracer/blob/master/img/flamegraph.png)](https://github.com/gaogaotiantian/viztracer/blob/master/img/flamegraph.png)
263
+
264
+ ### Remote attach
265
+
266
+ VizTracer supports remote attach to an arbitrary Python process to trace it, as long as viztracer is importable
267
+
268
+ Refer to [remote attach docs](https://viztracer.readthedocs.io/en/stable/remote_attach.html)
269
+
270
+ ### JSON alternative
271
+
272
+ VizTracer needs to dump the internal data to json format. It is recommended for the users to install ```orjson```, which is much faster than the builtin ```json``` library. VizTracer will try to import ```orjson``` and fall back to the builtin ```json``` library if ```orjson``` does not exist.
273
+
274
+ ## Performance
275
+
276
+ VizTracer puts in a lot of effort to achieve low overhead. The actual performance impact largely depends on your application.
277
+ For typical codebases, the overhead is expected to be below 1x. If your code has infrequent function calls,
278
+ the overhead could be minimal.
279
+
280
+ <details>
281
+
282
+ <summary>
283
+ Detailed explanation
284
+ </summary>
285
+
286
+ The overhead introduced by VizTracer is basically a fixed amount of time during function entry and exit, so the more time spent on
287
+ function entries and exits, the more overhead will be observed. A pure recursive ```fib``` function could suffer 3x-4x overhead
288
+ on Python3.11+ (when the Python call is optimized, before that Python call was slower so the overhead ratio would be less).
289
+
290
+ In the real life scenario, your code should not spend too much time on function calls (they don't really do anything useful), so
291
+ the overhead would be much smaller.
292
+
293
+ Many techniques are applied to minimize the overall overhead during code execution to reduce the inevitable skew introduced by
294
+ VizTracer (the report saving part is not as critical). For example, VizTracer tries to use the CPU timestamp counter instead of
295
+ a syscall to get the time when available. On Python 3.12+, VizTracer uses ```sys.monitoring``` which has less overhead than
296
+ ```sys.setprofile```. All of the efforts made it observably faster than ```cProfile```, the Python stdlib profiler.
297
+
298
+ However, VizTracer is a tracer, which means it has to record every single function entry and exit, so it can't be as fast as
299
+ the sampling profilers - they are not the same thing. With the extra overhead, VizTracer provides a lot more information than
300
+ normal sampling profilers.
301
+
302
+ </details>
303
+
304
+ ## Documentation
305
+
306
+ For full documentation, please see [https://viztracer.readthedocs.io/en/stable](https://viztracer.readthedocs.io/en/stable)
307
+
308
+ ## Bugs/Requests
309
+
310
+ Please send bug reports and feature requests through [github issue tracker](https://github.com/gaogaotiantian/viztracer/issues). VizTracer is currently under development now and it's open to any constructive suggestions.
311
+
312
+ ## License
313
+
314
+ Copyright 2020-2025 Tian Gao.
315
+
316
+ Distributed under the terms of the [Apache 2.0 license](https://github.com/gaogaotiantian/viztracer/blob/master/LICENSE).
@@ -8,18 +8,19 @@ authors = [{name = "Tian Gao", email = "gaogaotiantian@hotmail.com"}]
8
8
  description = "A debugging and profiling tool that can trace and visualize python code execution"
9
9
  dependencies = ["objprint>=0.3.0"]
10
10
  readme = "README.md"
11
- requires-python = ">=3.9"
12
- license = {file = "LICENSE"}
11
+ requires-python = ">=3.10"
12
+ license = "Apache-2.0"
13
13
  dynamic = ["version"]
14
14
  classifiers = [
15
15
  "Development Status :: 5 - Production/Stable",
16
- "Programming Language :: Python :: 3.9",
17
16
  "Programming Language :: Python :: 3.10",
18
17
  "Programming Language :: Python :: 3.11",
19
18
  "Programming Language :: Python :: 3.12",
20
19
  "Programming Language :: Python :: 3.13",
20
+ "Programming Language :: Python :: 3.14",
21
+ "Programming Language :: Python :: Free Threading",
22
+ "Programming Language :: Python :: Free Threading :: 3 - Stable",
21
23
  "Intended Audience :: Developers",
22
- "License :: OSI Approved :: Apache Software License",
23
24
  "Operating System :: MacOS",
24
25
  "Operating System :: POSIX :: Linux",
25
26
  "Operating System :: Microsoft :: Windows",
@@ -1,7 +1,7 @@
1
1
  # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0
2
2
  # For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
3
3
 
4
- __version__ = "1.0.4"
4
+ __version__ = "1.1.0"
5
5
 
6
6
 
7
7
  from .cellmagic import load_ipython_extension
@@ -5,7 +5,7 @@ import ast
5
5
  import copy
6
6
  import re
7
7
  from functools import reduce
8
- from typing import Any, Callable, Optional, Union
8
+ from typing import Any, Callable
9
9
 
10
10
  from .util import color_print
11
11
 
@@ -18,13 +18,13 @@ class AstTransformer(ast.NodeTransformer):
18
18
  self.curr_lineno: int = 0
19
19
  self.log_func_exec_enable: bool = False
20
20
 
21
- def visit_Assign(self, node: ast.Assign) -> Union[ast.stmt, list[ast.stmt]]:
21
+ def visit_Assign(self, node: ast.Assign) -> ast.stmt | list[ast.stmt]:
22
22
  return self._visit_generic_assign(node)
23
23
 
24
- def visit_AugAssign(self, node: ast.AugAssign) -> Union[ast.stmt, list[ast.stmt]]:
24
+ def visit_AugAssign(self, node: ast.AugAssign) -> ast.stmt | list[ast.stmt]:
25
25
  return self._visit_generic_assign(node)
26
26
 
27
- def visit_AnnAssign(self, node: ast.AnnAssign) -> Union[ast.stmt, list[ast.stmt]]:
27
+ def visit_AnnAssign(self, node: ast.AnnAssign) -> ast.stmt | list[ast.stmt]:
28
28
  return self._visit_generic_assign(node)
29
29
 
30
30
  def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
@@ -69,13 +69,13 @@ class AstTransformer(ast.NodeTransformer):
69
69
  node.body = instrumented_nodes + node.body
70
70
  return node
71
71
 
72
- def visit_Raise(self, node: ast.Raise) -> Union[ast.AST, list[ast.AST]]:
72
+ def visit_Raise(self, node: ast.Raise) -> ast.AST | list[ast.AST]:
73
73
  if self.inst_type == "log_exception":
74
74
  instrument_node = self.get_instrument_node_by_node("Exception", node.exc)
75
75
  return [instrument_node, node]
76
76
  return node
77
77
 
78
- def _visit_generic_assign(self, node: Union[ast.Assign, ast.AugAssign, ast.AnnAssign]) -> list[ast.stmt]:
78
+ def _visit_generic_assign(self, node: ast.Assign | ast.AugAssign | ast.AnnAssign) -> list[ast.stmt]:
79
79
  self.generic_visit(node)
80
80
  ret: list[ast.stmt] = [node]
81
81
  self.curr_lineno = node.lineno
@@ -174,7 +174,7 @@ class AstTransformer(ast.NodeTransformer):
174
174
  else:
175
175
  raise ValueError(f"{name} is not supported")
176
176
 
177
- def get_instrument_node_by_node(self, trigger: str, node: Optional[ast.expr]) -> ast.Expr:
177
+ def get_instrument_node_by_node(self, trigger: str, node: ast.expr | None) -> ast.Expr:
178
178
  var_node: ast.expr
179
179
  if node is None:
180
180
  name = f"{trigger}"
@@ -235,17 +235,14 @@ class AstTransformer(ast.NodeTransformer):
235
235
  n.ctx = ast.Load() # type: ignore
236
236
  return new_node
237
237
 
238
- def get_string_of_expr(self, node: Union[ast.expr, ast.slice]) -> str:
238
+ def get_string_of_expr(self, node: ast.expr | ast.slice) -> str:
239
239
  """
240
240
  Try to do "unparse" of the node
241
241
  """
242
242
  if isinstance(node, ast.Name):
243
243
  return node.id
244
244
  elif isinstance(node, ast.Constant):
245
- if isinstance(node.value, str):
246
- return f"'{node.value}'"
247
- else:
248
- return f"{node.value}"
245
+ return repr(node.value)
249
246
  elif isinstance(node, ast.Attribute):
250
247
  return f"{self.get_string_of_expr(node.value)}.{node.attr}"
251
248
  elif isinstance(node, ast.Subscript):
@@ -333,7 +330,7 @@ class CodeMonkey:
333
330
  def __init__(self, file_name: str) -> None:
334
331
  self.file_name: str = file_name
335
332
  self._compile: Callable = compile
336
- self.source_processor: Optional[SourceProcessor] = None
333
+ self.source_processor: SourceProcessor | None = None
337
334
  self.ast_transformers: list[AstTransformer] = []
338
335
 
339
336
  def add_instrument(self, inst_type: str, inst_args: dict[str, dict]) -> None:
@@ -5,7 +5,7 @@ import functools
5
5
  import multiprocessing
6
6
  import os
7
7
  import time
8
- from typing import Any, Callable, Optional, TypeVar, Union, overload
8
+ from typing import Any, Callable, TypeVar, overload
9
9
 
10
10
  from .viztracer import VizTracer, get_tracer
11
11
 
@@ -15,19 +15,18 @@ R = TypeVar("R")
15
15
 
16
16
  @overload
17
17
  def ignore_function(method: None,
18
- tracer: Optional[VizTracer] = None) -> Callable[[Callable[..., R]], Callable[..., R]]:
18
+ tracer: VizTracer | None = None) -> Callable[[Callable[..., R]], Callable[..., R]]:
19
19
  pass # pragma: no cover
20
20
 
21
21
 
22
22
  @overload
23
23
  def ignore_function(method: Callable[..., R],
24
- tracer: Optional[VizTracer] = None) -> Callable[..., R]:
24
+ tracer: VizTracer | None = None) -> Callable[..., R]:
25
25
  pass # pragma: no cover
26
26
 
27
27
 
28
- def ignore_function(method: Optional[Callable[..., R]] = None,
29
- tracer: Optional[VizTracer] = None) -> Union[Callable[..., R],
30
- Callable[[Callable[..., R]], Callable[..., R]]]:
28
+ def ignore_function(method: Callable[..., R] | None = None,
29
+ tracer: VizTracer | None = None) -> Callable[..., R] | Callable[[Callable[..., R]], Callable[..., R]]:
31
30
 
32
31
  def inner(func: Callable[..., R]) -> Callable[..., R]:
33
32
 
@@ -65,10 +64,9 @@ def trace_and_save(method: Callable[..., R],
65
64
  pass # pragma: no cover
66
65
 
67
66
 
68
- def trace_and_save(method: Optional[Callable[..., R]] = None,
67
+ def trace_and_save(method: Callable[..., R] | None = None,
69
68
  output_dir: str = "./",
70
- **viztracer_kwargs) -> Union[Callable[..., R],
71
- Callable[[Callable[..., R]], Callable[..., R]]]:
69
+ **viztracer_kwargs) -> Callable[..., R] | Callable[[Callable[..., R]], Callable[..., R]]:
72
70
 
73
71
  def inner(func: Callable[..., R]) -> Callable[..., R]:
74
72
 
@@ -158,10 +156,9 @@ def log_sparse(func: Callable[..., R],
158
156
  pass # pragma: no cover
159
157
 
160
158
 
161
- def log_sparse(func: Optional[Callable[..., R]] = None,
159
+ def log_sparse(func: Callable[..., R] | None = None,
162
160
  stack_depth: int = 0,
163
- dynamic_tracer_check: bool = False) -> Union[Callable[..., R],
164
- Callable[[Callable[..., R]], Callable[..., R]]]:
161
+ dynamic_tracer_check: bool = False) -> Callable[..., R] | Callable[[Callable[..., R]], Callable[..., R]]:
165
162
  if func is None:
166
163
  return functools.partial(_log_sparse_wrapper, stack_depth=stack_depth, dynamic_tracer_check=dynamic_tracer_check)
167
164
  return _log_sparse_wrapper(func=func, stack_depth=stack_depth, dynamic_tracer_check=dynamic_tracer_check)
@@ -2,7 +2,7 @@
2
2
  # For details: https://github.com/gaogaotiantian/viztracer/blob/master/NOTICE.txt
3
3
 
4
4
  import functools
5
- from typing import Any, Callable, Literal, Optional
5
+ from typing import Any, Callable, Literal
6
6
 
7
7
  from .viztracer import VizTracer
8
8
 
@@ -59,7 +59,7 @@ class _EventBase:
59
59
  self._viztracer_log()
60
60
 
61
61
  @staticmethod
62
- def triggerlog(method: Optional[Callable] = None,
62
+ def triggerlog(method: Callable | None = None,
63
63
  when: Literal["after", "before", "both"] = "after") -> Callable:
64
64
  if when not in ["after", "before", "both"]:
65
65
  raise ValueError(f"when has to be one of 'after', 'before' or 'both', not {when}")
@@ -4,18 +4,18 @@
4
4
  import bisect
5
5
  import copy
6
6
  import re
7
- from typing import Any, Generator, Optional
7
+ from typing import Any, Generator
8
8
 
9
9
 
10
10
  class FuncTreeNode:
11
11
  name_regex = r"(.*) \((.*?):([0-9]+)\)"
12
12
 
13
- def __init__(self, event: Optional[dict[str, Any]] = None) -> None:
14
- self.filename: Optional[str] = None
15
- self.lineno: Optional[int] = None
16
- self.is_python: Optional[bool] = False
17
- self.funcname: Optional[str] = None
18
- self.parent: Optional[FuncTreeNode] = None
13
+ def __init__(self, event: dict[str, Any] | None = None) -> None:
14
+ self.filename: str | None = None
15
+ self.lineno: int | None = None
16
+ self.is_python: bool | None = False
17
+ self.funcname: str | None = None
18
+ self.parent: FuncTreeNode | None = None
19
19
  self.children: list[FuncTreeNode] = []
20
20
  self.start: float = - (2 ** 64)
21
21
  self.end: float = 2 ** 64
@@ -19,7 +19,7 @@ import time
19
19
  import types
20
20
  import re
21
21
  from types import CodeType
22
- from typing import Any, Optional, Union
22
+ from typing import Any
23
23
 
24
24
  from . import __version__
25
25
  from .code_monkey import CodeMonkey
@@ -31,12 +31,12 @@ from .viztracer import VizTracer
31
31
  # For all the procedures in VizUI, return a tuple as the result
32
32
  # The first element bool indicates whether the procedure succeeds
33
33
  # The second element is the error message if it fails.
34
- VizProcedureResult = tuple[bool, Optional[str]]
34
+ VizProcedureResult = tuple[bool, str | None]
35
35
 
36
36
 
37
37
  class VizUI:
38
38
  def __init__(self) -> None:
39
- self.tracer: Optional[VizTracer] = None
39
+ self.tracer: VizTracer | None = None
40
40
  self.parser: argparse.ArgumentParser = self.create_parser()
41
41
  self.verbose: int = 1
42
42
  self.ofile: str = "result.json"
@@ -199,7 +199,7 @@ class VizUI:
199
199
  def parse(self, argv: list[str]) -> VizProcedureResult:
200
200
  # If -- or --run exists, all the commands after --/--run are the commands we need to run
201
201
  # We need to filter those out, they might conflict with our arguments
202
- idx: Optional[int] = None
202
+ idx: int | None = None
203
203
  if "--" in argv[1:]:
204
204
  idx = argv.index("--")
205
205
  elif "--run" in argv[1:]:
@@ -295,7 +295,7 @@ class VizUI:
295
295
 
296
296
  return True, None
297
297
 
298
- def search_file(self, file_name: str) -> Optional[str]:
298
+ def search_file(self, file_name: str) -> str | None:
299
299
  if os.path.isfile(file_name):
300
300
  return file_name
301
301
 
@@ -326,7 +326,7 @@ class VizUI:
326
326
  return self.uninstall()
327
327
  elif self.options.cmd_string is not None:
328
328
  return self.run_string()
329
- elif self.options.module:
329
+ elif self.options.module is not None:
330
330
  return self.run_module()
331
331
  elif self.command:
332
332
  return self.run_command()
@@ -342,7 +342,7 @@ class VizUI:
342
342
  self.parser.print_help()
343
343
  return True, None
344
344
 
345
- def run_code(self, code: Union[CodeType, str], global_dict: dict[str, Any]) -> VizProcedureResult:
345
+ def run_code(self, code: CodeType | str, global_dict: dict[str, Any]) -> VizProcedureResult:
346
346
  options = self.options
347
347
  self.parent_pid = os.getpid()
348
348
 
@@ -386,16 +386,12 @@ class VizUI:
386
386
  if not options.log_exit:
387
387
  tracer.stop(stop_option="flush_as_finish")
388
388
 
389
- # Clear to global_dict to release all references.
390
- # This is helpful for some deadlock issues.
391
- global_dict.clear()
392
-
393
389
  # issue141 - concurrent.future requires a proper release by executing
394
390
  # threading._threading_atexits or it will deadlock if not explicitly
395
391
  # release the resource in the code
396
392
  # Python 3.9+ has this issue
397
393
  if threading._threading_atexits: # type: ignore
398
- for atexit_call in threading._threading_atexits: # type: ignore
394
+ for atexit_call in reversed(threading._threading_atexits): # type: ignore
399
395
  atexit_call()
400
396
  threading._threading_atexits = [] # type: ignore
401
397
 
@@ -526,7 +522,7 @@ class VizUI:
526
522
  print(__version__)
527
523
  return True, None
528
524
 
529
- def _check_attach_availability(self) -> tuple[bool, Optional[str]]:
525
+ def _check_attach_availability(self) -> tuple[bool, str | None]:
530
526
  if sys.platform == "win32":
531
527
  return False, "VizTracer does not support this feature on Windows"
532
528