pyflow-analysis 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.
Files changed (757) hide show
  1. pyflow/__init__.py +22 -0
  2. pyflow/_pyflow.py +50 -0
  3. pyflow/analysis/__init__.py +14 -0
  4. pyflow/analysis/alias/__init__.py +3 -0
  5. pyflow/analysis/alias/flow_sensitive/__init__.py +148 -0
  6. pyflow/analysis/alias/flow_sensitive/_transfer_calls.py +3493 -0
  7. pyflow/analysis/alias/flow_sensitive/_transfer_ops.py +1969 -0
  8. pyflow/analysis/alias/flow_sensitive/abstraction.py +1632 -0
  9. pyflow/analysis/alias/flow_sensitive/heap_analysis.py +280 -0
  10. pyflow/analysis/alias/flow_sensitive/heap_effects.py +1209 -0
  11. pyflow/analysis/alias/flow_sensitive/heap_state.py +381 -0
  12. pyflow/analysis/alias/flow_sensitive/heap_summary.py +299 -0
  13. pyflow/analysis/alias/flow_sensitive/intrinsics.py +948 -0
  14. pyflow/analysis/alias/flow_sensitive/model.py +449 -0
  15. pyflow/analysis/alias/flow_sensitive/points_to_graph.py +722 -0
  16. pyflow/analysis/alias/flow_sensitive/transfer.py +1483 -0
  17. pyflow/analysis/alias/kcfa/__init__.py +33 -0
  18. pyflow/analysis/alias/kcfa/_pythonstan/__init__.py +2 -0
  19. pyflow/analysis/alias/kcfa/_pythonstan/analysis/__init__.py +1 -0
  20. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/__init__.py +53 -0
  21. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/logging.py +490 -0
  22. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/operation.py +1601 -0
  23. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/pointer_adapter.py +353 -0
  24. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/solver.py +559 -0
  25. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/state.py +701 -0
  26. pyflow/analysis/alias/kcfa/_pythonstan/analysis/ai/value.py +804 -0
  27. pyflow/analysis/alias/kcfa/_pythonstan/analysis/analysis.py +86 -0
  28. pyflow/analysis/alias/kcfa/_pythonstan/analysis/class_hierarchy.py +83 -0
  29. pyflow/analysis/alias/kcfa/_pythonstan/analysis/closure.py +69 -0
  30. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/__init__.py +4 -0
  31. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/analysis.py +58 -0
  32. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/driver.py +38 -0
  33. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/liveness.py +33 -0
  34. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/reaching_definition.py +52 -0
  35. pyflow/analysis/alias/kcfa/_pythonstan/analysis/dataflow/solver.py +178 -0
  36. pyflow/analysis/alias/kcfa/_pythonstan/analysis/defuse.py +46 -0
  37. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/__init__.py +18 -0
  38. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/__init__.py +110 -0
  39. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/analysis.py +382 -0
  40. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/builtin_api_handler.py +1872 -0
  41. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/call_graph_analyzer.py +289 -0
  42. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/class_hierarchy.py +304 -0
  43. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/config.py +139 -0
  44. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/constraints.py +576 -0
  45. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/context.py +496 -0
  46. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/context_selector.py +297 -0
  47. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/debug_monitor.py +34 -0
  48. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/heap_model.py +221 -0
  49. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/ir_translator.py +1181 -0
  50. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/libs/__init__.py +2 -0
  51. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/libs/math.py +244 -0
  52. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/module_analysis.py +269 -0
  53. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/module_summary.py +191 -0
  54. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/object.py +685 -0
  55. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/pointer_flow_graph.py +282 -0
  56. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/points_to_set.py +301 -0
  57. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/__init__.py +21 -0
  58. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/attribute_semantics.py +512 -0
  59. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/compose_processor.py +46 -0
  60. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/container.py +128 -0
  61. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/generator.py +353 -0
  62. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/normal_call.py +664 -0
  63. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/processor.py +36 -0
  64. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/processor/super_resolve.py +131 -0
  65. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/pta_query_adapter.py +329 -0
  66. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/solver.py +917 -0
  67. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/solver_interface.py +76 -0
  68. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/state.py +735 -0
  69. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/unknown_tracker.py +126 -0
  70. pyflow/analysis/alias/kcfa/_pythonstan/analysis/pointer/kcfa/variable.py +144 -0
  71. pyflow/analysis/alias/kcfa/_pythonstan/analysis/scope/__init__.py +2 -0
  72. pyflow/analysis/alias/kcfa/_pythonstan/analysis/scope/analysis.py +37 -0
  73. pyflow/analysis/alias/kcfa/_pythonstan/analysis/scope/closure.py +81 -0
  74. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/__init__.py +8 -0
  75. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/block_cfg.py +133 -0
  76. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/cfg.py +95 -0
  77. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/driver.py +26 -0
  78. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/__init__.py +0 -0
  79. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/base.py +112 -0
  80. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/baseprocess.py +524 -0
  81. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/icfg.py +0 -0
  82. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/icfg_pre_transform.py +69 -0
  83. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/icfg_transform.py +0 -0
  84. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/postprocessor.py +308 -0
  85. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/icfg/preprocessor.py +375 -0
  86. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/ir.py +361 -0
  87. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/three_address.py +1161 -0
  88. pyflow/analysis/alias/kcfa/_pythonstan/analysis/transform/transform.py +27 -0
  89. pyflow/analysis/alias/kcfa/_pythonstan/graph/__init__.py +0 -0
  90. pyflow/analysis/alias/kcfa/_pythonstan/graph/call_graph/__init__.py +2 -0
  91. pyflow/analysis/alias/kcfa/_pythonstan/graph/call_graph/call_edge.py +45 -0
  92. pyflow/analysis/alias/kcfa/_pythonstan/graph/call_graph/call_graph.py +77 -0
  93. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/__init__.py +3 -0
  94. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/base_block.py +83 -0
  95. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/cfg.py +200 -0
  96. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/dump.py +20 -0
  97. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/edges.py +162 -0
  98. pyflow/analysis/alias/kcfa/_pythonstan/graph/cfg/visualize.py +112 -0
  99. pyflow/analysis/alias/kcfa/_pythonstan/graph/dominator_tree.py +126 -0
  100. pyflow/analysis/alias/kcfa/_pythonstan/graph/graph.py +81 -0
  101. pyflow/analysis/alias/kcfa/_pythonstan/graph/icfg/__init__.py +0 -0
  102. pyflow/analysis/alias/kcfa/_pythonstan/graph/icfg/icfg.py +98 -0
  103. pyflow/analysis/alias/kcfa/_pythonstan/ir/__init__.py +2 -0
  104. pyflow/analysis/alias/kcfa/_pythonstan/ir/ir_statements.py +1579 -0
  105. pyflow/analysis/alias/kcfa/_pythonstan/ir/ir_visitor.py +21 -0
  106. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/LICENSE.pythonstan +28 -0
  107. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/README.md +99 -0
  108. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/abc.cpython-313.pyc +0 -0
  109. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/base64.cpython-313.pyc +0 -0
  110. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/bisect.cpython-313.pyc +0 -0
  111. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/collections.cpython-313.pyc +0 -0
  112. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/contextlib.cpython-313.pyc +0 -0
  113. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/copy.cpython-313.pyc +0 -0
  114. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/csv.cpython-313.pyc +0 -0
  115. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/dataclasses.cpython-313.pyc +0 -0
  116. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/datetime.cpython-313.pyc +0 -0
  117. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/email.cpython-313.pyc +0 -0
  118. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/enum.cpython-313.pyc +0 -0
  119. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/fnmatch.cpython-313.pyc +0 -0
  120. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/functools.cpython-313.pyc +0 -0
  121. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/glob.cpython-313.pyc +0 -0
  122. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/hashlib.cpython-313.pyc +0 -0
  123. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/heapq.cpython-313.pyc +0 -0
  124. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/hmac.cpython-313.pyc +0 -0
  125. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/http.cpython-313.pyc +0 -0
  126. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/importlib.cpython-313.pyc +0 -0
  127. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/inspect.cpython-313.pyc +0 -0
  128. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/io.cpython-313.pyc +0 -0
  129. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/itertools.cpython-313.pyc +0 -0
  130. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/json.cpython-313.pyc +0 -0
  131. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/logging.cpython-313.pyc +0 -0
  132. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/math.cpython-313.pyc +0 -0
  133. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/mimetypes.cpython-313.pyc +0 -0
  134. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/operator.cpython-313.pyc +0 -0
  135. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/os.cpython-313.pyc +0 -0
  136. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/pathlib.cpython-313.pyc +0 -0
  137. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/pickle.cpython-313.pyc +0 -0
  138. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/random.cpython-313.pyc +0 -0
  139. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/re.cpython-313.pyc +0 -0
  140. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/secrets.cpython-313.pyc +0 -0
  141. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/shutil.cpython-313.pyc +0 -0
  142. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/somelib.cpython-313.pyc +0 -0
  143. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/tempfile.cpython-313.pyc +0 -0
  144. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/time.cpython-313.pyc +0 -0
  145. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/traceback.cpython-313.pyc +0 -0
  146. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/types.cpython-313.pyc +0 -0
  147. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/uuid.cpython-313.pyc +0 -0
  148. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/warnings.cpython-313.pyc +0 -0
  149. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/__pycache__/weakref.cpython-313.pyc +0 -0
  150. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/abc.py +80 -0
  151. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/base64.py +62 -0
  152. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/bisect.py +52 -0
  153. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/collections.py +187 -0
  154. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/contextlib.py +113 -0
  155. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/copy.py +15 -0
  156. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/csv.py +163 -0
  157. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/dataclasses.py +150 -0
  158. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/datetime.py +171 -0
  159. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/email.py +270 -0
  160. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/enum.py +144 -0
  161. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/fnmatch.py +14 -0
  162. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/functools.py +84 -0
  163. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/glob.py +10 -0
  164. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/hashlib.py +74 -0
  165. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/heapq.py +91 -0
  166. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/hmac.py +31 -0
  167. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/http.py +317 -0
  168. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/importlib.py +126 -0
  169. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/inspect.py +246 -0
  170. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/io.py +471 -0
  171. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/itertools.py +164 -0
  172. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/json.py +80 -0
  173. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/logging.py +193 -0
  174. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/math.py +244 -0
  175. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/mimetypes.py +119 -0
  176. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/operator.py +310 -0
  177. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/os.py +286 -0
  178. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/pathlib.py +196 -0
  179. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/pickle.py +153 -0
  180. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/random.py +125 -0
  181. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/re.py +125 -0
  182. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/secrets.py +29 -0
  183. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/shutil.py +99 -0
  184. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/somelib.py +2 -0
  185. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/tempfile.py +76 -0
  186. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/time.py +65 -0
  187. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/traceback.py +151 -0
  188. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/types.py +247 -0
  189. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/__init__.py +1 -0
  190. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/__pycache__/__init__.cpython-313.pyc +0 -0
  191. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/__pycache__/parse.cpython-313.pyc +0 -0
  192. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/urllib/parse.py +221 -0
  193. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/uuid.py +34 -0
  194. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/warnings.py +82 -0
  195. pyflow/analysis/alias/kcfa/_pythonstan/stubs/stdlib/weakref.py +272 -0
  196. pyflow/analysis/alias/kcfa/_pythonstan/utils/__init__.py +1 -0
  197. pyflow/analysis/alias/kcfa/_pythonstan/utils/ast_rename.py +35 -0
  198. pyflow/analysis/alias/kcfa/_pythonstan/utils/common.py +70 -0
  199. pyflow/analysis/alias/kcfa/_pythonstan/utils/persistent_rb_tree.py +364 -0
  200. pyflow/analysis/alias/kcfa/_pythonstan/utils/temp_var_generator.py +68 -0
  201. pyflow/analysis/alias/kcfa/_pythonstan/utils/toposort.py +63 -0
  202. pyflow/analysis/alias/kcfa/_pythonstan/utils/var_collector.py +72 -0
  203. pyflow/analysis/alias/kcfa/_pythonstan/world/__init__.py +1 -0
  204. pyflow/analysis/alias/kcfa/_pythonstan/world/analysis_manager.py +141 -0
  205. pyflow/analysis/alias/kcfa/_pythonstan/world/class_hierarchy.py +56 -0
  206. pyflow/analysis/alias/kcfa/_pythonstan/world/config.py +93 -0
  207. pyflow/analysis/alias/kcfa/_pythonstan/world/import_manager.py +16 -0
  208. pyflow/analysis/alias/kcfa/_pythonstan/world/namespace.py +327 -0
  209. pyflow/analysis/alias/kcfa/_pythonstan/world/pipeline.py +153 -0
  210. pyflow/analysis/alias/kcfa/_pythonstan/world/scope_manager.py +133 -0
  211. pyflow/analysis/alias/kcfa/_pythonstan/world/world.py +49 -0
  212. pyflow/analysis/alias/kcfa/bridge.py +136 -0
  213. pyflow/analysis/astcollector.py +171 -0
  214. pyflow/analysis/cache/incremental.py +226 -0
  215. pyflow/analysis/callgraph/__init__.py +58 -0
  216. pyflow/analysis/callgraph/ast_based.py +184 -0
  217. pyflow/analysis/callgraph/callgraph.py +86 -0
  218. pyflow/analysis/callgraph/constraint_based/__init__.py +26 -0
  219. pyflow/analysis/callgraph/constraint_based/_analyzer.py +1976 -0
  220. pyflow/analysis/callgraph/constraint_based/_collector.py +704 -0
  221. pyflow/analysis/callgraph/constraint_based/_evaluator.py +984 -0
  222. pyflow/analysis/callgraph/constraint_based/_loader.py +115 -0
  223. pyflow/analysis/callgraph/constraint_based/_resolver.py +2852 -0
  224. pyflow/analysis/callgraph/constraint_based/api.py +233 -0
  225. pyflow/analysis/callgraph/constraint_based/engine.py +717 -0
  226. pyflow/analysis/callgraph/constraint_based/model.py +303 -0
  227. pyflow/analysis/callgraph/formats.py +99 -0
  228. pyflow/analysis/callgraph/pycg_based.py +273 -0
  229. pyflow/analysis/cdg/__init__.py +52 -0
  230. pyflow/analysis/cdg/construction.py +256 -0
  231. pyflow/analysis/cdg/dump.py +415 -0
  232. pyflow/analysis/cdg/graph.py +456 -0
  233. pyflow/analysis/cfg/__init__.py +38 -0
  234. pyflow/analysis/cfg/dfs.py +55 -0
  235. pyflow/analysis/cfg/dom.py +243 -0
  236. pyflow/analysis/cfg/dump.py +322 -0
  237. pyflow/analysis/cfg/expandphi.py +113 -0
  238. pyflow/analysis/cfg/gc.py +93 -0
  239. pyflow/analysis/cfg/graph.py +878 -0
  240. pyflow/analysis/cfg/inline.py +337 -0
  241. pyflow/analysis/cfg/killflow.py +360 -0
  242. pyflow/analysis/cfg/optimize.py +164 -0
  243. pyflow/analysis/cfg/simplify.py +19 -0
  244. pyflow/analysis/cfg/ssa.py +693 -0
  245. pyflow/analysis/cfg/ssatransform.py +13 -0
  246. pyflow/analysis/cfg/structuralanalysis.py +422 -0
  247. pyflow/analysis/cfg/transform.py +527 -0
  248. pyflow/analysis/cpa/__init__.py +657 -0
  249. pyflow/analysis/cpa/base.py +430 -0
  250. pyflow/analysis/cpa/codecloner.py +262 -0
  251. pyflow/analysis/cpa/constraintextractor.py +797 -0
  252. pyflow/analysis/cpa/constraints.py +1071 -0
  253. pyflow/analysis/cpa/simpleimagebuilder.py +299 -0
  254. pyflow/analysis/cpasignature.py +132 -0
  255. pyflow/analysis/cpg/__init__.py +93 -0
  256. pyflow/analysis/cpg/build.py +221 -0
  257. pyflow/analysis/cpg/dump.py +102 -0
  258. pyflow/analysis/cpg/graph.py +1877 -0
  259. pyflow/analysis/cpg/persist.py +346 -0
  260. pyflow/analysis/cpg/profiles.py +286 -0
  261. pyflow/analysis/cpg/rules.py +365 -0
  262. pyflow/analysis/cpg/taint.py +1934 -0
  263. pyflow/analysis/dataflowIR/__init__.py +6 -0
  264. pyflow/analysis/dataflowIR/annotations.py +174 -0
  265. pyflow/analysis/dataflowIR/convert.py +795 -0
  266. pyflow/analysis/dataflowIR/dump.py +443 -0
  267. pyflow/analysis/dataflowIR/graph.py +1648 -0
  268. pyflow/analysis/dataflowIR/ordering.py +134 -0
  269. pyflow/analysis/dataflowIR/predicate.py +233 -0
  270. pyflow/analysis/dataflowIR/transform/__init__.py +15 -0
  271. pyflow/analysis/dataflowIR/transform/dce.py +215 -0
  272. pyflow/analysis/dataflowIR/transform/loadelimination.py +185 -0
  273. pyflow/analysis/dataflowIR/traverse.py +91 -0
  274. pyflow/analysis/ddg/__init__.py +53 -0
  275. pyflow/analysis/ddg/construction.py +310 -0
  276. pyflow/analysis/ddg/dump.py +218 -0
  277. pyflow/analysis/ddg/graph.py +295 -0
  278. pyflow/analysis/dump/__init__.py +15 -0
  279. pyflow/analysis/dump/dumpgraphs.py +93 -0
  280. pyflow/analysis/dump/dumpreport.py +841 -0
  281. pyflow/analysis/dump/dumputil.py +98 -0
  282. pyflow/analysis/fsdf/__init__.py +1107 -0
  283. pyflow/analysis/fsdf/canonicalset.py +176 -0
  284. pyflow/analysis/fsdf/canonicaltree.py +1071 -0
  285. pyflow/analysis/ifds/__init__.py +284 -0
  286. pyflow/analysis/ifds/annotation_fallback.py +21 -0
  287. pyflow/analysis/ifds/annotation_synthesis.py +803 -0
  288. pyflow/analysis/ifds/api.py +567 -0
  289. pyflow/analysis/ifds/backward_solver.py +328 -0
  290. pyflow/analysis/ifds/cfg_adapter.py +1575 -0
  291. pyflow/analysis/ifds/clients/_call_model.py +166 -0
  292. pyflow/analysis/ifds/clients/_client_common.py +1617 -0
  293. pyflow/analysis/ifds/clients/flow_path_collector.py +159 -0
  294. pyflow/analysis/ifds/clients/library_presets.py +1134 -0
  295. pyflow/analysis/ifds/clients/nullness.py +754 -0
  296. pyflow/analysis/ifds/clients/registry/__init__.py +26 -0
  297. pyflow/analysis/ifds/clients/registry/loader.py +688 -0
  298. pyflow/analysis/ifds/clients/registry/validate.py +37 -0
  299. pyflow/analysis/ifds/clients/taint.py +782 -0
  300. pyflow/analysis/ifds/clients/typestate.py +1550 -0
  301. pyflow/analysis/ifds/clients/typestate_engine.py +534 -0
  302. pyflow/analysis/ifds/diagnostics.py +29 -0
  303. pyflow/analysis/ifds/preparation.py +97 -0
  304. pyflow/analysis/ifds/problem.py +363 -0
  305. pyflow/analysis/ifds/queries.py +142 -0
  306. pyflow/analysis/ifds/reporting.py +289 -0
  307. pyflow/analysis/ifds/shadow_scan.py +349 -0
  308. pyflow/analysis/ifds/solver.py +1495 -0
  309. pyflow/analysis/ifds/supergraph.py +186 -0
  310. pyflow/analysis/ifds/transfers.py +187 -0
  311. pyflow/analysis/ipa/__init__.py +77 -0
  312. pyflow/analysis/ipa/calling/__init__.py +17 -0
  313. pyflow/analysis/ipa/calling/callbinder.py +93 -0
  314. pyflow/analysis/ipa/calling/cpa.py +197 -0
  315. pyflow/analysis/ipa/calling/transfer.py +208 -0
  316. pyflow/analysis/ipa/constraintextractor.py +804 -0
  317. pyflow/analysis/ipa/constraints/__init__.py +18 -0
  318. pyflow/analysis/ipa/constraints/base.py +66 -0
  319. pyflow/analysis/ipa/constraints/calls.py +424 -0
  320. pyflow/analysis/ipa/constraints/flow.py +445 -0
  321. pyflow/analysis/ipa/constraints/node.py +299 -0
  322. pyflow/analysis/ipa/constraints/qualifiers.py +17 -0
  323. pyflow/analysis/ipa/constraints/split.py +178 -0
  324. pyflow/analysis/ipa/dump.py +246 -0
  325. pyflow/analysis/ipa/entrypointbuilder.py +52 -0
  326. pyflow/analysis/ipa/escape/__init__.py +19 -0
  327. pyflow/analysis/ipa/escape/objectescape.py +77 -0
  328. pyflow/analysis/ipa/ipanalysis.py +319 -0
  329. pyflow/analysis/ipa/memory/__init__.py +16 -0
  330. pyflow/analysis/ipa/memory/extractorpolicy.py +38 -0
  331. pyflow/analysis/ipa/memory/storegraphpolicy.py +17 -0
  332. pyflow/analysis/ipa/model/__init__.py +18 -0
  333. pyflow/analysis/ipa/model/context.py +277 -0
  334. pyflow/analysis/ipa/model/invocation.py +159 -0
  335. pyflow/analysis/ipa/model/object.py +102 -0
  336. pyflow/analysis/ipa/model/objectname.py +77 -0
  337. pyflow/analysis/ipa/model/region.py +51 -0
  338. pyflow/analysis/ipa/summary/__init__.py +120 -0
  339. pyflow/analysis/ir_utils.py +215 -0
  340. pyflow/analysis/lifetimeanalysis/__init__.py +935 -0
  341. pyflow/analysis/lifetimeanalysis/database/__init__.py +17 -0
  342. pyflow/analysis/lifetimeanalysis/database/base.py +72 -0
  343. pyflow/analysis/lifetimeanalysis/database/lattice.py +189 -0
  344. pyflow/analysis/lifetimeanalysis/database/mapping.py +174 -0
  345. pyflow/analysis/lifetimeanalysis/database/structure.py +224 -0
  346. pyflow/analysis/lifetimeanalysis/database/tupleset.py +141 -0
  347. pyflow/analysis/numbering/__init__.py +17 -0
  348. pyflow/analysis/numbering/dataflow.py +214 -0
  349. pyflow/analysis/numbering/dominance.py +120 -0
  350. pyflow/analysis/numbering/readmodify.py +251 -0
  351. pyflow/analysis/numbering/ssa.py +604 -0
  352. pyflow/analysis/pdg/__init__.py +55 -0
  353. pyflow/analysis/pdg/construction.py +447 -0
  354. pyflow/analysis/pdg/cypher.py +1150 -0
  355. pyflow/analysis/pdg/dump.py +129 -0
  356. pyflow/analysis/pdg/graph.py +308 -0
  357. pyflow/analysis/programculler.py +224 -0
  358. pyflow/analysis/shape/__init__.py +466 -0
  359. pyflow/analysis/shape/constraintbuilder.py +933 -0
  360. pyflow/analysis/shape/constraints.py +510 -0
  361. pyflow/analysis/shape/dataflow.py +202 -0
  362. pyflow/analysis/shape/model/__init__.py +27 -0
  363. pyflow/analysis/shape/model/canonical.py +137 -0
  364. pyflow/analysis/shape/model/configuration.py +78 -0
  365. pyflow/analysis/shape/model/expressions.py +268 -0
  366. pyflow/analysis/shape/model/pathinformation.py +645 -0
  367. pyflow/analysis/shape/model/referencecount.py +212 -0
  368. pyflow/analysis/shape/model/secondary.py +31 -0
  369. pyflow/analysis/shape/model/slots.py +69 -0
  370. pyflow/analysis/shape/regionanalysis.py +152 -0
  371. pyflow/analysis/shape/transferfunctions.py +353 -0
  372. pyflow/analysis/storegraph/__init__.py +19 -0
  373. pyflow/analysis/storegraph/annotations.py +70 -0
  374. pyflow/analysis/storegraph/canonicalobjects.py +329 -0
  375. pyflow/analysis/storegraph/extendedtypes.py +311 -0
  376. pyflow/analysis/storegraph/setmanager.py +123 -0
  377. pyflow/analysis/storegraph/storegraph.py +577 -0
  378. pyflow/analysis/tools.py +112 -0
  379. pyflow/analysis/typeinfo/__init__.py +93 -0
  380. pyflow/analysis/typeinfo/_config.py +84 -0
  381. pyflow/analysis/typeinfo/annotation_resolver.py +483 -0
  382. pyflow/analysis/typeinfo/collector.py +361 -0
  383. pyflow/analysis/typeinfo/constants.py +378 -0
  384. pyflow/analysis/typeinfo/docstring_parser.py +289 -0
  385. pyflow/analysis/typeinfo/generic_binder.py +145 -0
  386. pyflow/analysis/typeinfo/gradual_typing.py +255 -0
  387. pyflow/analysis/typeinfo/models.py +43 -0
  388. pyflow/analysis/typeinfo/service.py +774 -0
  389. pyflow/analysis/typeinfo/string_subtype_inference.py +113 -0
  390. pyflow/analysis/typeinfo/string_subtypes.py +150 -0
  391. pyflow/analysis/typeinfo/stub_loader.py +667 -0
  392. pyflow/analysis/typeinfo/type_inference.py +747 -0
  393. pyflow/analysis/typeinfo/type_utils.py +361 -0
  394. pyflow/analysis/typeinfo/typesystem.py +2346 -0
  395. pyflow/analysis/typeinfo/typetracing.py +672 -0
  396. pyflow/api/__init__.py +94 -0
  397. pyflow/api/entrypoints/__init__.py +36 -0
  398. pyflow/api/entrypoints/declaration.py +345 -0
  399. pyflow/api/entrypoints/entry_point.py +59 -0
  400. pyflow/api/entrypoints/wrappers.py +83 -0
  401. pyflow/api/queries/__init__.py +65 -0
  402. pyflow/api/queries/_cfg_utils.py +53 -0
  403. pyflow/api/queries/_dataflow_ipa.py +29 -0
  404. pyflow/api/queries/_dataflow_reaching_defs.py +105 -0
  405. pyflow/api/queries/_dataflow_store_graph.py +152 -0
  406. pyflow/api/queries/_dataflow_taint.py +76 -0
  407. pyflow/api/queries/_models.py +177 -0
  408. pyflow/api/queries/call_graph.py +168 -0
  409. pyflow/api/queries/capabilities.py +106 -0
  410. pyflow/api/queries/context.py +152 -0
  411. pyflow/api/queries/control_flow.py +35 -0
  412. pyflow/api/queries/data_flow.py +157 -0
  413. pyflow/api/queries/engine.py +201 -0
  414. pyflow/api/queries/localization.py +8 -0
  415. pyflow/api/queries/service.py +339 -0
  416. pyflow/api/queries/tasks/__init__.py +8 -0
  417. pyflow/api/queries/tasks/code_localization.py +425 -0
  418. pyflow/api/queries/tasks/test_generation.py +338 -0
  419. pyflow/api/queries/test_generation.py +8 -0
  420. pyflow/application/__init__.py +109 -0
  421. pyflow/application/context.py +116 -0
  422. pyflow/application/errors.py +55 -0
  423. pyflow/application/makefile.py +213 -0
  424. pyflow/application/passes.py +515 -0
  425. pyflow/application/passmanager.py +755 -0
  426. pyflow/application/pipeline.py +459 -0
  427. pyflow/application/program.py +147 -0
  428. pyflow/checker/__init__.py +51 -0
  429. pyflow/checker/formatters/__init__.py +14 -0
  430. pyflow/checker/formatters/json.py +153 -0
  431. pyflow/checker/formatters/sarif.py +263 -0
  432. pyflow/checker/formatters/text.py +168 -0
  433. pyflow/checker/formatters/utils.py +17 -0
  434. pyflow/checker/llm/__init__.py +19 -0
  435. pyflow/checker/llm/exploit.py +129 -0
  436. pyflow/checker/llm/judge.py +105 -0
  437. pyflow/checker/llm/llm_utils.py +131 -0
  438. pyflow/checker/microbench.py +338 -0
  439. pyflow/checker/pattern/__init__.py +14 -0
  440. pyflow/checker/pattern/checkers/__init__.py +34 -0
  441. pyflow/checker/pattern/checkers/aws_security.py +234 -0
  442. pyflow/checker/pattern/checkers/blacklist_calls.py +54 -0
  443. pyflow/checker/pattern/checkers/blacklist_imports.py +73 -0
  444. pyflow/checker/pattern/checkers/class_pollution.py +459 -0
  445. pyflow/checker/pattern/checkers/command_injection.py +340 -0
  446. pyflow/checker/pattern/checkers/deserialization.py +373 -0
  447. pyflow/checker/pattern/checkers/django_security.py +285 -0
  448. pyflow/checker/pattern/checkers/exception_handling.py +317 -0
  449. pyflow/checker/pattern/checkers/exec_use.py +16 -0
  450. pyflow/checker/pattern/checkers/fastapi_security.py +291 -0
  451. pyflow/checker/pattern/checkers/flask_security.py +264 -0
  452. pyflow/checker/pattern/checkers/hardcoded_password.py +239 -0
  453. pyflow/checker/pattern/checkers/hardcoded_secrets.py +279 -0
  454. pyflow/checker/pattern/checkers/ldap_injection.py +281 -0
  455. pyflow/checker/pattern/checkers/path_traversal.py +124 -0
  456. pyflow/checker/pattern/checkers/shell_injection.py +46 -0
  457. pyflow/checker/pattern/checkers/sql_injection.py +170 -0
  458. pyflow/checker/pattern/checkers/sql_injection_enhanced.py +574 -0
  459. pyflow/checker/pattern/checkers/ssrf.py +419 -0
  460. pyflow/checker/pattern/checkers/template_security.py +310 -0
  461. pyflow/checker/pattern/checkers/weak_crypto.py +89 -0
  462. pyflow/checker/pattern/checkers/xxe_vulnerabilities.py +155 -0
  463. pyflow/checker/pattern/core/__init__.py +17 -0
  464. pyflow/checker/pattern/core/blacklist.py +569 -0
  465. pyflow/checker/pattern/core/config.py +15 -0
  466. pyflow/checker/pattern/core/constants.py +52 -0
  467. pyflow/checker/pattern/core/context.py +276 -0
  468. pyflow/checker/pattern/core/issue.py +325 -0
  469. pyflow/checker/pattern/core/manager.py +253 -0
  470. pyflow/checker/pattern/core/metrics.py +78 -0
  471. pyflow/checker/pattern/core/node_visitor.py +430 -0
  472. pyflow/checker/pattern/core/test_loader.py +41 -0
  473. pyflow/checker/pattern/core/test_properties.py +54 -0
  474. pyflow/checker/pattern/core/test_set.py +33 -0
  475. pyflow/checker/pattern/core/tester.py +244 -0
  476. pyflow/checker/pattern/core/utils.py +167 -0
  477. pyflow/checker/quality.py +374 -0
  478. pyflow/checker/semantic/__init__.py +16 -0
  479. pyflow/checker/semantic/core/__init__.py +23 -0
  480. pyflow/checker/semantic/core/base.py +26 -0
  481. pyflow/checker/semantic/core/context.py +270 -0
  482. pyflow/checker/semantic/core/issue.py +9 -0
  483. pyflow/checker/semantic/core/manager.py +150 -0
  484. pyflow/checker/semantic/core/runner.py +58 -0
  485. pyflow/checker/semantic/detectors/__init__.py +17 -0
  486. pyflow/checker/semantic/detectors/ast_helpers.py +114 -0
  487. pyflow/checker/semantic/detectors/leak.py +500 -0
  488. pyflow/checker/semantic/detectors/null_dereference.py +132 -0
  489. pyflow/checker/semantic/detectors/semantic_taint.py +2258 -0
  490. pyflow/checker/supply_chain.py +568 -0
  491. pyflow/cli/__init__.py +12 -0
  492. pyflow/cli/alias.py +397 -0
  493. pyflow/cli/callgraph.py +185 -0
  494. pyflow/cli/ir.py +461 -0
  495. pyflow/cli/main.py +125 -0
  496. pyflow/cli/optimize.py +603 -0
  497. pyflow/cli/security.py +1262 -0
  498. pyflow/cli/supply_chain.py +114 -0
  499. pyflow/config/nullness/django.json +21 -0
  500. pyflow/config/nullness/fastapi.json +17 -0
  501. pyflow/config/nullness/flask.json +37 -0
  502. pyflow/config/nullness/sql.json +21 -0
  503. pyflow/config/nullness/sqlalchemy.json +33 -0
  504. pyflow/config/nullness/stdlib.json +161 -0
  505. pyflow/config/rule-pack.schema.json +54 -0
  506. pyflow/config/taint/aiohttp.json +640 -0
  507. pyflow/config/taint/cloud.json +485 -0
  508. pyflow/config/taint/concurrency.json +25 -0
  509. pyflow/config/taint/django.json +710 -0
  510. pyflow/config/taint/falcon.json +375 -0
  511. pyflow/config/taint/fastapi.json +192 -0
  512. pyflow/config/taint/flask.json +504 -0
  513. pyflow/config/taint/injection.json +2294 -0
  514. pyflow/config/taint/network.json +367 -0
  515. pyflow/config/taint/nosql.json +166 -0
  516. pyflow/config/taint/pandas.json +463 -0
  517. pyflow/config/taint/requests.json +952 -0
  518. pyflow/config/taint/serialization.json +109 -0
  519. pyflow/config/taint/sql.json +730 -0
  520. pyflow/config/taint/sqlalchemy.json +235 -0
  521. pyflow/config/taint/stdlib.json +4388 -0
  522. pyflow/config/taint/tornado.json +151 -0
  523. pyflow/config/taint/xml.json +89 -0
  524. pyflow/config/typestate/concurrency.json +145 -0
  525. pyflow/config/typestate/network.json +130 -0
  526. pyflow/config/typestate/requests.json +88 -0
  527. pyflow/config/typestate/sql.json +107 -0
  528. pyflow/config/typestate/sqlalchemy.json +45 -0
  529. pyflow/config/typestate/stdlib.json +91 -0
  530. pyflow/config.py +30 -0
  531. pyflow/frontend/__init__.py +28 -0
  532. pyflow/frontend/ast_converter.py +2593 -0
  533. pyflow/frontend/class_hierarchy.py +665 -0
  534. pyflow/frontend/dependency_resolver.py +1836 -0
  535. pyflow/frontend/function_extractor.py +602 -0
  536. pyflow/frontend/object_manager.py +224 -0
  537. pyflow/frontend/programextractor.py +1033 -0
  538. pyflow/frontend/project_resolution.py +511 -0
  539. pyflow/frontend/source_locator.py +163 -0
  540. pyflow/frontend/stub_manager.py +425 -0
  541. pyflow/language/__init__.py +5 -0
  542. pyflow/language/asttools/__init__.py +34 -0
  543. pyflow/language/asttools/annotation.py +242 -0
  544. pyflow/language/asttools/antlrtranslator.py +344 -0
  545. pyflow/language/asttools/astpprint.py +132 -0
  546. pyflow/language/asttools/complexity.py +224 -0
  547. pyflow/language/asttools/decorators.py +71 -0
  548. pyflow/language/asttools/metaast/__init__.py +370 -0
  549. pyflow/language/asttools/metaast/codegeneration.py +622 -0
  550. pyflow/language/asttools/origin.py +83 -0
  551. pyflow/language/asttools/symbols.py +204 -0
  552. pyflow/language/asttools/visitors.py +179 -0
  553. pyflow/language/modules/__init__.py +18 -0
  554. pyflow/language/modules/_scope_graph.py +484 -0
  555. pyflow/language/modules/ast_helper.py +211 -0
  556. pyflow/language/modules/module_definitions.py +240 -0
  557. pyflow/language/modules/project_handler.py +110 -0
  558. pyflow/language/modules/transform.py +290 -0
  559. pyflow/language/modules/util.py +413 -0
  560. pyflow/language/python/__init__.py +21 -0
  561. pyflow/language/python/annotations.py +378 -0
  562. pyflow/language/python/ast.py +749 -0
  563. pyflow/language/python/collapser.py +604 -0
  564. pyflow/language/python/default_markers.py +8 -0
  565. pyflow/language/python/defuse.py +469 -0
  566. pyflow/language/python/fold.py +220 -0
  567. pyflow/language/python/program.py +371 -0
  568. pyflow/language/python/pythonbase.py +353 -0
  569. pyflow/language/python/pythonoutput.py +82 -0
  570. pyflow/language/python/simplecodegen.py +975 -0
  571. pyflow/optimization/__init__.py +29 -0
  572. pyflow/optimization/argumentnormalization.py +429 -0
  573. pyflow/optimization/callconverter.py +295 -0
  574. pyflow/optimization/clone.py +743 -0
  575. pyflow/optimization/codeinlining.py +587 -0
  576. pyflow/optimization/convertboolelimination.py +111 -0
  577. pyflow/optimization/cullprogram.py +155 -0
  578. pyflow/optimization/dataflow/__init__.py +17 -0
  579. pyflow/optimization/dataflow/base.py +780 -0
  580. pyflow/optimization/dataflow/forward.py +681 -0
  581. pyflow/optimization/dataflow/reverse.py +454 -0
  582. pyflow/optimization/dce.py +354 -0
  583. pyflow/optimization/fold.py +780 -0
  584. pyflow/optimization/loadelimination.py +342 -0
  585. pyflow/optimization/methodcall.py +554 -0
  586. pyflow/optimization/rewrite.py +129 -0
  587. pyflow/optimization/simplify.py +143 -0
  588. pyflow/optimization/storeelimination.py +129 -0
  589. pyflow/optimization/termrewrite.py +287 -0
  590. pyflow/stats/__init__.py +436 -0
  591. pyflow/stubs/__init__.py +34 -0
  592. pyflow/stubs/__pycache__/__init__.cpython-313.pyc +0 -0
  593. pyflow/stubs/__pycache__/lltranslator.cpython-313.pyc +0 -0
  594. pyflow/stubs/__pycache__/stubcollector.cpython-313.pyc +0 -0
  595. pyflow/stubs/lltranslator.py +493 -0
  596. pyflow/stubs/std/__init__.py +83 -0
  597. pyflow/stubs/std/__pycache__/__init__.cpython-313.pyc +0 -0
  598. pyflow/stubs/std/__pycache__/argparse_stubs.cpython-313.pyc +0 -0
  599. pyflow/stubs/std/__pycache__/collections_stubs.cpython-313.pyc +0 -0
  600. pyflow/stubs/std/__pycache__/container.cpython-313.pyc +0 -0
  601. pyflow/stubs/std/__pycache__/copy_stubs.cpython-313.pyc +0 -0
  602. pyflow/stubs/std/__pycache__/csv_stubs.cpython-313.pyc +0 -0
  603. pyflow/stubs/std/__pycache__/datetime_stubs.cpython-313.pyc +0 -0
  604. pyflow/stubs/std/__pycache__/functools_stubs.cpython-313.pyc +0 -0
  605. pyflow/stubs/std/__pycache__/hashlib_stubs.cpython-313.pyc +0 -0
  606. pyflow/stubs/std/__pycache__/interpreter.cpython-313.pyc +0 -0
  607. pyflow/stubs/std/__pycache__/io_stubs.cpython-313.pyc +0 -0
  608. pyflow/stubs/std/__pycache__/itertools_stubs.cpython-313.pyc +0 -0
  609. pyflow/stubs/std/__pycache__/json_stubs.cpython-313.pyc +0 -0
  610. pyflow/stubs/std/__pycache__/llfunc.cpython-313.pyc +0 -0
  611. pyflow/stubs/std/__pycache__/logging_stubs.cpython-313.pyc +0 -0
  612. pyflow/stubs/std/__pycache__/mathstubs.cpython-313.pyc +0 -0
  613. pyflow/stubs/std/__pycache__/operator_stubs.cpython-313.pyc +0 -0
  614. pyflow/stubs/std/__pycache__/os_stubs.cpython-313.pyc +0 -0
  615. pyflow/stubs/std/__pycache__/pathlib_stubs.cpython-313.pyc +0 -0
  616. pyflow/stubs/std/__pycache__/pickle_stubs.cpython-313.pyc +0 -0
  617. pyflow/stubs/std/__pycache__/random.cpython-313.pyc +0 -0
  618. pyflow/stubs/std/__pycache__/re_stubs.cpython-313.pyc +0 -0
  619. pyflow/stubs/std/__pycache__/sampler.cpython-313.pyc +0 -0
  620. pyflow/stubs/std/__pycache__/shutil_stubs.cpython-313.pyc +0 -0
  621. pyflow/stubs/std/__pycache__/subprocess_stubs.cpython-313.pyc +0 -0
  622. pyflow/stubs/std/__pycache__/sys_stubs.cpython-313.pyc +0 -0
  623. pyflow/stubs/std/__pycache__/tempfile_stubs.cpython-313.pyc +0 -0
  624. pyflow/stubs/std/__pycache__/threading_stubs.cpython-313.pyc +0 -0
  625. pyflow/stubs/std/__pycache__/time_stubs.cpython-313.pyc +0 -0
  626. pyflow/stubs/std/argparse_stubs.py +200 -0
  627. pyflow/stubs/std/collections_stubs.py +77 -0
  628. pyflow/stubs/std/container.py +374 -0
  629. pyflow/stubs/std/copy_stubs.py +54 -0
  630. pyflow/stubs/std/csv_stubs.py +187 -0
  631. pyflow/stubs/std/datetime_stubs.py +70 -0
  632. pyflow/stubs/std/functools_stubs.py +61 -0
  633. pyflow/stubs/std/hashlib_stubs.py +198 -0
  634. pyflow/stubs/std/interpreter.py +360 -0
  635. pyflow/stubs/std/io_stubs.py +339 -0
  636. pyflow/stubs/std/itertools_stubs.py +89 -0
  637. pyflow/stubs/std/json_stubs.py +40 -0
  638. pyflow/stubs/std/llfunc.py +240 -0
  639. pyflow/stubs/std/logging_stubs.py +295 -0
  640. pyflow/stubs/std/mathstubs.py +393 -0
  641. pyflow/stubs/std/objects/__init__.py +9 -0
  642. pyflow/stubs/std/objects/__pycache__/__init__.cpython-313.pyc +0 -0
  643. pyflow/stubs/std/objects/__pycache__/float.cpython-313.pyc +0 -0
  644. pyflow/stubs/std/objects/__pycache__/int.cpython-313.pyc +0 -0
  645. pyflow/stubs/std/objects/__pycache__/str.cpython-313.pyc +0 -0
  646. pyflow/stubs/std/objects/float.py +248 -0
  647. pyflow/stubs/std/objects/int.py +221 -0
  648. pyflow/stubs/std/objects/str.py +175 -0
  649. pyflow/stubs/std/operator_stubs.py +148 -0
  650. pyflow/stubs/std/os_stubs.py +727 -0
  651. pyflow/stubs/std/pathlib_stubs.py +364 -0
  652. pyflow/stubs/std/pickle_stubs.py +97 -0
  653. pyflow/stubs/std/random.py +29 -0
  654. pyflow/stubs/std/re_stubs.py +178 -0
  655. pyflow/stubs/std/sampler.py +17 -0
  656. pyflow/stubs/std/shutil_stubs.py +212 -0
  657. pyflow/stubs/std/subprocess_stubs.py +149 -0
  658. pyflow/stubs/std/sys_stubs.py +226 -0
  659. pyflow/stubs/std/tempfile_stubs.py +129 -0
  660. pyflow/stubs/std/threading_stubs.py +328 -0
  661. pyflow/stubs/std/time_stubs.py +283 -0
  662. pyflow/stubs/stubcollector.py +463 -0
  663. pyflow/util/PADS/Automata.py +640 -0
  664. pyflow/util/PADS/BFS.py +28 -0
  665. pyflow/util/PADS/Biconnectivity.py +270 -0
  666. pyflow/util/PADS/Bipartite.py +89 -0
  667. pyflow/util/PADS/BipartiteMatching.py +129 -0
  668. pyflow/util/PADS/CardinalityMatching.py +316 -0
  669. pyflow/util/PADS/Chordal.py +33 -0
  670. pyflow/util/PADS/CubicHam.py +351 -0
  671. pyflow/util/PADS/DFS.py +100 -0
  672. pyflow/util/PADS/Eratosthenes.py +138 -0
  673. pyflow/util/PADS/GraphExamples.py +36 -0
  674. pyflow/util/PADS/Graphs.py +82 -0
  675. pyflow/util/PADS/GrayGraph.py +36 -0
  676. pyflow/util/PADS/IntegerPartitions.py +317 -0
  677. pyflow/util/PADS/LCA.py +349 -0
  678. pyflow/util/PADS/LCS.py +38 -0
  679. pyflow/util/PADS/LexBFS.py +32 -0
  680. pyflow/util/PADS/LongestIncreasingSubsequence.py +65 -0
  681. pyflow/util/PADS/Medium.py +414 -0
  682. pyflow/util/PADS/MinimumSpanningTree.py +26 -0
  683. pyflow/util/PADS/OrderedSequence.py +133 -0
  684. pyflow/util/PADS/PartialCube.py +227 -0
  685. pyflow/util/PADS/PartialOrder.py +129 -0
  686. pyflow/util/PADS/PartitionRefinement.py +85 -0
  687. pyflow/util/PADS/ReadUndirectedGraph.py +431 -0
  688. pyflow/util/PADS/Repetitivity.py +160 -0
  689. pyflow/util/PADS/SMAWK.py +190 -0
  690. pyflow/util/PADS/Sequence.py +118 -0
  691. pyflow/util/PADS/StrongConnectivity.py +106 -0
  692. pyflow/util/PADS/Sudoku.py +2028 -0
  693. pyflow/util/PADS/UnionFind.py +63 -0
  694. pyflow/util/PADS/Util.py +28 -0
  695. pyflow/util/PADS/Wrap.py +79 -0
  696. pyflow/util/PADS/__init__.py +13 -0
  697. pyflow/util/PADS/xyzGraph.py +127 -0
  698. pyflow/util/__init__.py +19 -0
  699. pyflow/util/antlr3/__init__.py +134 -0
  700. pyflow/util/antlr3/compat.py +12 -0
  701. pyflow/util/antlr3/constants.py +24 -0
  702. pyflow/util/antlr3/dfa.py +179 -0
  703. pyflow/util/antlr3/dottreegen.py +170 -0
  704. pyflow/util/antlr3/exceptions.py +346 -0
  705. pyflow/util/antlr3/extras.py +11 -0
  706. pyflow/util/antlr3/main.py +198 -0
  707. pyflow/util/antlr3/recognizers.py +1341 -0
  708. pyflow/util/antlr3/streams.py +1250 -0
  709. pyflow/util/antlr3/tokens.py +370 -0
  710. pyflow/util/antlr3/tree.py +2190 -0
  711. pyflow/util/antlr3/treewizard.py +566 -0
  712. pyflow/util/application/__init__.py +13 -0
  713. pyflow/util/application/async_utils.py +101 -0
  714. pyflow/util/application/compilerexceptions.py +21 -0
  715. pyflow/util/application/console.py +235 -0
  716. pyflow/util/application/errorhandler.py +241 -0
  717. pyflow/util/canonical.py +204 -0
  718. pyflow/util/debug/__init__.py +11 -0
  719. pyflow/util/debug/blame.py +94 -0
  720. pyflow/util/debug/debugger.py +105 -0
  721. pyflow/util/debug/trace.py +56 -0
  722. pyflow/util/graphalgorithim/__init__.py +17 -0
  723. pyflow/util/graphalgorithim/basic.py +77 -0
  724. pyflow/util/graphalgorithim/color.py +104 -0
  725. pyflow/util/graphalgorithim/djtree.py +299 -0
  726. pyflow/util/graphalgorithim/dominator.py +531 -0
  727. pyflow/util/graphalgorithim/exclusiongraph.py +624 -0
  728. pyflow/util/graphalgorithim/merge.py +221 -0
  729. pyflow/util/io/__init__.py +6 -0
  730. pyflow/util/io/dot.py +540 -0
  731. pyflow/util/io/filesystem.py +210 -0
  732. pyflow/util/io/formatting.py +71 -0
  733. pyflow/util/io/report.py +224 -0
  734. pyflow/util/io/xmloutput.py +270 -0
  735. pyflow/util/json_dict.py +92 -0
  736. pyflow/util/monkeypatch/__init__.py +21 -0
  737. pyflow/util/monkeypatch/xcollections.py +206 -0
  738. pyflow/util/monkeypatch/xmath.py +108 -0
  739. pyflow/util/monkeypatch/xnamedtuple.py +180 -0
  740. pyflow/util/monkeypatch/xtypes.py +56 -0
  741. pyflow/util/orderedset.py +420 -0
  742. pyflow/util/pydot.py +1998 -0
  743. pyflow/util/python/__init__.py +136 -0
  744. pyflow/util/python/apply.py +180 -0
  745. pyflow/util/python/calling.py +558 -0
  746. pyflow/util/python/opnames.py +153 -0
  747. pyflow/util/randomness.py +230 -0
  748. pyflow/util/singleton.py +112 -0
  749. pyflow/util/tvl.py +321 -0
  750. pyflow/util/typedispatch.py +342 -0
  751. pyflow/util/unionfind.py +169 -0
  752. pyflow_analysis-0.1.0.dist-info/METADATA +184 -0
  753. pyflow_analysis-0.1.0.dist-info/RECORD +757 -0
  754. pyflow_analysis-0.1.0.dist-info/WHEEL +5 -0
  755. pyflow_analysis-0.1.0.dist-info/entry_points.txt +2 -0
  756. pyflow_analysis-0.1.0.dist-info/licenses/LICENSE.txt +202 -0
  757. pyflow_analysis-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,975 @@
1
+ """Simple code generation for Python AST.
2
+
3
+ This module provides SimpleExprGen, which generates Python code from AST.
4
+ It handles:
5
+ - Expression generation: Converting AST expressions to Python code
6
+ - Statement generation: Converting AST statements to Python code
7
+ - Variable renaming: Generating unique names for local variables
8
+ - Variable collapsing: Inlining collapsable variables
9
+ - Constant handling: Proper representation of constants
10
+
11
+ The code generator produces readable Python code that preserves the
12
+ semantics of the original AST.
13
+ """
14
+
15
+ import types
16
+ import sys
17
+
18
+ from pyflow.util.typedispatch import *
19
+ from pyflow.language.python.pythonoutput import PythonOutput
20
+
21
+ from pyflow.language.python import defuse
22
+ from pyflow.language.python import collapser
23
+ from pyflow.language.python.default_markers import MISSING_DEFAULT
24
+ from pyflow.util.python import opnames
25
+
26
+ from pyflow.language.python import ast, program
27
+
28
+ import re
29
+
30
+ isIdentifier = re.compile(r"^([a-zA-Z_]\w*)?$")
31
+
32
+
33
+ def typeString(t):
34
+ """Convert type to string representation.
35
+
36
+ Args:
37
+ t: Type object
38
+
39
+ Returns:
40
+ str: String representation of type
41
+ """
42
+ if t:
43
+ return "<%s>" % ", ".join(set([str(label.baseType()) for label in t.labels]))
44
+ else:
45
+ return "<?>"
46
+
47
+
48
+ class UncollapsableCodeError(Exception):
49
+ """Exception raised when code cannot be collapsed."""
50
+
51
+ pass
52
+
53
+
54
+ def getConstant(node, t=None):
55
+ """Extract constant value from an Existing node.
56
+
57
+ Args:
58
+ node: Existing node with constant value
59
+ t: Expected type (optional, for validation)
60
+
61
+ Returns:
62
+ object: Constant Python value
63
+
64
+ Raises:
65
+ AssertionError: If node is not constant or wrong type
66
+ """
67
+ assert isinstance(node, ast.Existing) and node.object.isConstant(), node
68
+ if t != None:
69
+ assert isinstance(node.object.pyobj, t)
70
+ return node.object.pyobj
71
+
72
+
73
+ def getExistingStr(node):
74
+ """Get string representation of an Existing node.
75
+
76
+ For lexical constants, returns Python repr. For other objects,
77
+ returns a placeholder representation.
78
+
79
+ Args:
80
+ node: Existing node
81
+
82
+ Returns:
83
+ str: String representation
84
+
85
+ Raises:
86
+ AssertionError: If node is not Existing
87
+ """
88
+ assert isinstance(node, ast.Existing)
89
+ if node.object.isLexicalConstant():
90
+ return repr(node.object.pyobj)
91
+ else:
92
+ obj = node.object
93
+ if hasattr(obj, " pyobj"):
94
+ obj = obj.pyobj
95
+
96
+ return "|[%r]|" % obj
97
+
98
+
99
+ class SimpleExprGen(TypeDispatcher):
100
+ """Simple code generator for Python AST.
101
+
102
+ SimpleExprGen generates Python code from AST nodes. It handles:
103
+ - Expression generation: Converting expressions to Python code
104
+ - Variable renaming: Generating unique names for variables
105
+ - Variable collapsing: Inlining collapsable variables
106
+ - Constant representation: Proper handling of constants
107
+
108
+ Attributes:
109
+ localLUT: Dictionary mapping Local nodes to generated names
110
+ names: Set of used names (for uniqueness)
111
+ uid: Unique identifier counter for name generation
112
+ collapsed: Dictionary mapping collapsed variables to their expressions
113
+ parent: Parent code generator (for nested code)
114
+ """
115
+
116
+ __namedispatch__ = True # HACK emulates old visitor
117
+
118
+ def __init__(self, parent):
119
+ """Initialize code generator.
120
+
121
+ Args:
122
+ parent: Parent code generator (or None for top-level)
123
+ """
124
+ TypeDispatcher.__init__(self)
125
+
126
+ # For renaming locals
127
+ self.localLUT = {}
128
+ self.names = set()
129
+ self.uid = 0
130
+
131
+ self.collapsed = {}
132
+
133
+ self.parent = parent
134
+
135
+ def generateUniqueLocalName(self, base):
136
+ """Generate a unique local variable name.
137
+
138
+ Generates a unique name based on base, appending a unique ID if needed.
139
+ Handles invalid identifiers from bytecode compiler.
140
+
141
+ Args:
142
+ base: Base name for the variable
143
+
144
+ Returns:
145
+ str: Unique variable name
146
+ """
147
+ # The bytecode compiler can generate invalid names for list comprehensions/tuple comprehensions/etc.
148
+ if not isIdentifier.match(base):
149
+ base = ""
150
+
151
+ name = base
152
+
153
+ # Find a unique name.
154
+ while not name or name in self.names:
155
+ name = "%s_%d" % (base, self.uid)
156
+ self.uid += 1
157
+ return name
158
+
159
+ def getLocalName(self, node):
160
+ """Get or generate a name for a local variable.
161
+
162
+ Returns the generated name for a Local node, generating one if needed.
163
+
164
+ Args:
165
+ node: Local node to get name for
166
+
167
+ Returns:
168
+ str: Generated variable name
169
+ """
170
+ # HACK assumes locals will not conflict with non-local names
171
+ # TODO preregister globals and cells
172
+ # TODO preregister "MakeFunction" names.
173
+
174
+ if not node in self.localLUT:
175
+ base = node.name if node.name else ""
176
+ name = self.generateUniqueLocalName(base)
177
+ self.setLocalName(node, name)
178
+ return self.localLUT[node]
179
+
180
+ def setLocalName(self, node, name):
181
+ """Set the name for a local variable.
182
+
183
+ Args:
184
+ node: Local node to set name for
185
+ name: Name to set (None generates anonymous name)
186
+
187
+ Raises:
188
+ AssertionError: If node already has a name
189
+ """
190
+ assert not node in self.localLUT, "%r has already been named: %s." % (
191
+ node,
192
+ self.localLUT[node],
193
+ )
194
+
195
+ if name is None:
196
+ name = self.generateUniqueLocalName("")
197
+ name = "!" + name
198
+ self.names.add(name)
199
+ self.localLUT[node] = name
200
+ elif isIdentifier.match(name):
201
+ self.names.add(name)
202
+ self.localLUT[node] = name
203
+
204
+ def visitLocal(self, node):
205
+ return self.getLocalName(node), -1
206
+
207
+ def visitDoNotCare(self, node):
208
+ return "-", -1
209
+
210
+ def visitExisting(self, node):
211
+ s = getExistingStr(node)
212
+ return s, -1
213
+
214
+ def visitGetGlobal(self, node):
215
+ name = getConstant(node.name, str)
216
+ return name, -1
217
+
218
+ def visitCell(self, node):
219
+ return node.name, -1
220
+
221
+ def visitGetCell(self, node):
222
+ # HACK
223
+ print("Warning: AST contains GetCell node.")
224
+ return "None", -1
225
+
226
+ def visitGetCellDeref(self, node):
227
+ return self(node.cell)
228
+
229
+ def visitImport(self, node):
230
+ return (
231
+ "__import__(%r, globals(), locals(), %r, %d)"
232
+ % (node.name, node.fromlist, node.level)
233
+ ), 4
234
+
235
+ def visitGetIter(self, node):
236
+ return ("iter(%s)" % (self.process(node.expr, 24))), 4
237
+
238
+ def visitConvertToBool(self, node):
239
+ return ("bool(%s)" % (self.process(node.expr, 24))), 4
240
+
241
+ def visitAllocate(self, node):
242
+ # Synax for allocating containers.
243
+ if isinstance(node.expr, ast.Existing):
244
+ obj = node.expr.object
245
+ if isinstance(obj, program.Object):
246
+ pyobj = obj.pyobj
247
+ if pyobj is list:
248
+ return "[]", 2
249
+ elif pyobj is dict:
250
+ return "{}", 2
251
+
252
+ return ("<allocate>(%s)" % (self.process(node.expr, 24))), 4
253
+
254
+ def visitLoad(self, node):
255
+ return (
256
+ "<load>(%s, %r, %s)"
257
+ % (self.process(node.expr, 24), node.fieldtype, self.process(node.name, 24))
258
+ ), 4
259
+
260
+ # def visitStore(self, node):
261
+ # return ("<store>(%s, %r, %s, %s)" % (self.process(node.expr, 24), node.fieldtype, self.process(node.name, 24), self.process(node.value, 24))), 4
262
+
263
+ def visitCheck(self, node):
264
+ return (
265
+ "<check>(%s, %r, %s)"
266
+ % (self.process(node.expr, 24), node.fieldtype, self.process(node.name, 24))
267
+ ), 4
268
+
269
+ def visitGetAttr(self, node):
270
+ # HACK
271
+ # prec = 7
272
+ prec = 4
273
+ name = getConstant(node.name, str)
274
+ return ("%s.%s" % (self.process(node.expr, prec), name)), prec
275
+
276
+ def visitGetSubscript(self, node):
277
+ # HACK
278
+ # prec = 6
279
+ prec = 4
280
+
281
+ return (
282
+ "%s[%s]" % (self.process(node.expr, prec), self.process(node.subscript, 2))
283
+ ), prec
284
+
285
+ def visitUnaryPrefixOp(self, node):
286
+ prec = opnames.unaryPrefixPrecedence[node.op]
287
+ return (node.op + self.process(node.expr, prec)), prec
288
+
289
+ def visitNot(self, node):
290
+ prec = 20
291
+ return ("not " + self.process(node.expr, prec)), prec
292
+
293
+ def visitIs(self, node):
294
+ prec = opnames.binaryOpPrecedence["is"]
295
+
296
+ left = self.process(node.left, prec, False)
297
+ right = self.process(node.right, prec, True)
298
+
299
+ return (left + " == " + right), prec
300
+
301
+ def visitBinaryOp(self, node):
302
+ # assert not node.op in opnames.inplaceOps
303
+
304
+ op = node.op
305
+
306
+ if op in opnames.inplaceOps:
307
+ prec = 24
308
+ flipBinding = False
309
+ op = "<%s>" % op
310
+ else:
311
+ prec = opnames.binaryOpPrecedence[op]
312
+ flipBinding = op == "**"
313
+
314
+ left = self.process(node.left, prec, flipBinding)
315
+ right = self.process(node.right, prec, not flipBinding)
316
+
317
+ if op in opnames.mustHaveSpace:
318
+ op = " %s " % op
319
+
320
+ return (left + op + right), prec
321
+
322
+ def visitYield(self, node):
323
+ expr = self.process(node.expr, 24)
324
+ return "yield %s" % expr, 24 # No parenth, so low precedence. Otherwise, 3?
325
+
326
+ def visitBuildTuple(self, node):
327
+ args = [self.process(arg, 24) for arg in node.args]
328
+ return (
329
+ "%s," % ", ".join(args)
330
+ ), 24 # No parenth, so low precedence. Otherwise, 3?
331
+
332
+ def visitBuildList(self, node):
333
+ args = [self.process(arg, 24) for arg in node.args]
334
+ return ("[%s]" % ", ".join(args)), 2
335
+
336
+ def visitBuildMap(self, node):
337
+ pairs = list(zip(node.args[0::2], node.args[1::2]))
338
+ items = []
339
+ for key, value in pairs:
340
+ key_src = self.process(key, 24)
341
+ value_src = self.process(value, 24)
342
+ items.append(f"{key_src}: {value_src}")
343
+ return ("{%s}" % ", ".join(items)), 2
344
+
345
+ def processNone(self, node, prec, replace):
346
+ if not node:
347
+ return replace
348
+ else:
349
+ return self.process(node, prec)
350
+
351
+ def visitBuildSlice(self, node):
352
+ args = [
353
+ self.processNone(arg, 24, "None")
354
+ for arg in (node.start, node.stop, node.step)
355
+ ]
356
+ return ("slice(%s)" % ", ".join(args)), 4
357
+
358
+ def visitGetSlice(self, node):
359
+ prec = 4
360
+ expr = self.process(node.expr, prec)
361
+
362
+ if node.step:
363
+ args = (node.start, node.stop, node.step)
364
+ else:
365
+ args = (node.start, node.stop)
366
+
367
+ args = [self.processNone(arg, 24, "") for arg in args]
368
+ return ("%s[%s]" % (expr, ":".join(args))), prec
369
+
370
+ def getArgString(self, node):
371
+ args = [self.process(arg, 24) for arg in node.args]
372
+
373
+ args.extend(
374
+ ["%s=%s" % (name, self.process(arg, 24)) for name, arg in node.kwds]
375
+ )
376
+
377
+ if node.vargs:
378
+ args.append("*%s" % self.process(node.vargs, 24))
379
+
380
+ if node.kargs:
381
+ args.append("**%s" % self.process(node.kargs, 24))
382
+
383
+ return ", ".join(args)
384
+
385
+ def visitCall(self, node):
386
+ prec = 4
387
+ expr = self.process(node.expr, prec)
388
+ assert isinstance(expr, str)
389
+
390
+ argstr = self.getArgString(node)
391
+
392
+ return ("%s(%s)" % (expr, argstr)), prec
393
+
394
+ def visitDirectCall(self, node):
395
+ prec = 4
396
+
397
+ if node.code is not None:
398
+ funcname = node.code.name
399
+ else:
400
+ funcname = "???" # This is an error, but if it occurs we need to be able to visualize it.
401
+
402
+ if node.selfarg:
403
+ selfarg = self.process(node.selfarg, prec)
404
+ else:
405
+ selfarg = "None"
406
+
407
+ argstr = self.getArgString(node)
408
+
409
+ return ("<%s, %s>(%s)" % (funcname, selfarg, argstr)), prec
410
+
411
+ def visitMethodCall(self, node):
412
+ prec = 4
413
+
414
+ expr = self.process(node.expr, prec)
415
+ name = self.process(node.name, prec)
416
+
417
+ argstr = self.getArgString(node)
418
+
419
+ return ("%s{%s}(%s)" % (expr, name, argstr)), prec
420
+
421
+ def visitCached(self, node):
422
+ if node in self.collapsed:
423
+ return self.collapsed[node]
424
+ else:
425
+ return self(node)
426
+
427
+ @defaultdispatch
428
+ def visitDefault(self, node):
429
+ # Default handler for unhandled node types
430
+ return "<unhandled:%s>" % type(node).__name__, -1
431
+
432
+ def visitShortCircutOr(self, node):
433
+ prec = 22
434
+ partial = []
435
+
436
+ for i, term in enumerate(node.terms):
437
+ assert isinstance(term, ast.Condition), term
438
+ text, inner = self.parent.process(term)
439
+ partial.append(protect(text, inner, prec))
440
+
441
+ if i == 0:
442
+ self.parent.enterSupress()
443
+
444
+ self.parent.exitSupress()
445
+
446
+ return " or ".join(partial), prec
447
+
448
+ def visitShortCircutAnd(self, node):
449
+ prec = 21
450
+ partial = []
451
+ for i, term in enumerate(node.terms):
452
+ assert isinstance(term, ast.Condition), term
453
+ text, inner = self.parent.process(term)
454
+ partial.append(protect(text, inner, prec))
455
+ if i == 0:
456
+ self.parent.enterSupress()
457
+
458
+ self.parent.exitSupress()
459
+ return " and ".join(partial), prec
460
+
461
+ def process(self, node, precedence=24, right=False):
462
+ text, innerPrec = self.visitCached(node)
463
+ text = protect(text, innerPrec, precedence, right)
464
+ return text
465
+
466
+ def processCollapsed(self, lcl, expr):
467
+ assert lcl in self.collapsable, (lcl, self.collapsable)
468
+ self.collapsed[lcl] = self.visitCached(expr)
469
+
470
+
471
+ def protect(text, inner, outer, right=False):
472
+ if inner > outer or right and inner == outer:
473
+ text = "(%s)" % text
474
+ return text
475
+
476
+
477
+ class SimpleCodeGen(TypeDispatcher):
478
+ __namedispatch__ = True # HACK emulates old visitor
479
+
480
+ def __init__(self, out=None):
481
+ TypeDispatcher.__init__(self)
482
+
483
+ if out is None:
484
+ out = PythonOutput(sys.stdout)
485
+ elif not isinstance(out, PythonOutput):
486
+ out = PythonOutput(out)
487
+ self.out = out
488
+
489
+ self.collapsable = set()
490
+
491
+ self.seg = SimpleExprGen(self)
492
+ self.seg.collapsable = self.collapsable
493
+
494
+ self.supressStatements = 0
495
+
496
+ def getLocalName(self, node):
497
+ return self.seg.getLocalName(node)
498
+
499
+ def enterSupress(self):
500
+ self.supressStatements += 1
501
+
502
+ def exitSupress(self):
503
+ assert self.supressStatements > 0
504
+ self.supressStatements -= 1
505
+
506
+ def emitStatement(self, stmt):
507
+ if self.supressStatements:
508
+ if False:
509
+ raise UncollapsableCodeError(stmt)
510
+ else:
511
+ print("Tried to emit %r inside a conditional." % stmt)
512
+ return
513
+
514
+ self.out.emitStatement(stmt)
515
+
516
+ def processNoEmit(self, node):
517
+ self.enterSupress()
518
+ ret = self(node)
519
+ self.exitSupress()
520
+ return ret
521
+
522
+ def visitInputBlock(self, node):
523
+ for input in node.inputs:
524
+ self.emitStatement("%r => %s" % (input.src, self.seg.process(input.lcl)))
525
+
526
+ def visitOutputBlock(self, node):
527
+ for output in node.outputs:
528
+ self.emitStatement("%s => %r" % (self.seg.process(output.expr), output.dst))
529
+
530
+ def visitReturn(self, node):
531
+ expr = ", ".join([self.seg.process(expr) for expr in node.exprs])
532
+
533
+ if expr != "None":
534
+ self.emitStatement("return %s" % expr)
535
+ else:
536
+ self.emitStatement("return")
537
+
538
+ def visitRaise(self, node):
539
+ args = []
540
+ if node.exception:
541
+ args.append(self.seg.process(node.exception))
542
+ if node.parameter:
543
+ args.append(self.seg.process(node.parameter))
544
+ if node.traceback:
545
+ args.append(self.seg.process(node.traceback))
546
+
547
+ if args:
548
+ self.emitStatement("raise %s" % ", ".join(args))
549
+ else:
550
+ # TODO make illegal outside of an except block?
551
+ self.emitStatement("raise")
552
+
553
+ def visitBreak(self, node):
554
+ self.emitStatement("break")
555
+
556
+ def visitContinue(self, node):
557
+ self.emitStatement("continue")
558
+
559
+ def visitSetAttr(self, node):
560
+ name = getConstant(node.name, str)
561
+ stmt = "%s.%s = %s" % (
562
+ self.seg.process(node.expr, 7),
563
+ name,
564
+ self.seg.process(node.value),
565
+ )
566
+ self.emitStatement(stmt)
567
+
568
+ def visitDeleteAttr(self, node):
569
+ name = getConstant(node.name, str)
570
+ stmt = "del %s.%s" % (self.seg.process(node.expr, 7), name)
571
+ self.emitStatement(stmt)
572
+
573
+ def visitSetCellDeref(self, node):
574
+ stmt = "%s = %s" % (self.seg.process(node.cell), self.seg.process(node.value))
575
+ self.emitStatement(stmt)
576
+
577
+ def handleSliceArgs(self, node):
578
+ if node.step:
579
+ args = (node.start, node.stop, node.step)
580
+ else:
581
+ args = (node.start, node.stop)
582
+
583
+ args = [self.seg.processNone(arg, 24, "") for arg in args]
584
+ return ":".join(args)
585
+
586
+ def visitSetSlice(self, node):
587
+ value = self.seg.process(node.value)
588
+ expr = self.seg.process(node.expr, 4)
589
+
590
+ args = self.handleSliceArgs(node)
591
+
592
+ stmt = "%s[%s] = %s" % (expr, args, value)
593
+
594
+ self.emitStatement(stmt)
595
+
596
+ def visitDeleteSlice(self, node):
597
+ expr = self.seg.process(node.expr, 4)
598
+ args = self.handleSliceArgs(node)
599
+
600
+ stmt = "del %s[%s]" % (expr, args)
601
+
602
+ self.emitStatement(stmt)
603
+
604
+ def visitSetSubscript(self, node):
605
+ value = self.seg.process(node.value)
606
+ expr = self.seg.process(node.expr, 7)
607
+ subscript = self.seg.process(node.subscript)
608
+
609
+ stmt = "%s[%s] = %s" % (expr, subscript, value)
610
+
611
+ self.emitStatement(stmt)
612
+
613
+ def visitDeleteSubscript(self, node):
614
+ expr = self.seg.process(node.expr, 7)
615
+ subscript = self.seg.process(node.subscript)
616
+
617
+ stmt = "del %s[%s]" % (expr, subscript)
618
+
619
+ self.emitStatement(stmt)
620
+
621
+ def visitSetGlobal(self, node):
622
+ name = getConstant(node.name)
623
+ value = self.seg.process(node.value)
624
+
625
+ stmt = "%s = %s" % (name, value)
626
+ self.emitStatement(stmt)
627
+
628
+ def visitDeleteGlobal(self, node):
629
+ name = getConstant(node.name)
630
+ stmt = "del %s" % (name)
631
+ self.emitStatement(stmt)
632
+
633
+ def visitUnpackSequence(self, node):
634
+ assert not self.supressStatements
635
+ expr = self.seg.process(node.expr)
636
+ targets = [self.seg.process(target) for target in node.targets]
637
+ stmt = "%s, = %s" % ((", ".join(targets)), expr)
638
+ self.emitStatement(stmt)
639
+
640
+ def visitAssign(self, node):
641
+ if isinstance(node.expr, ast.BinaryOp) and node.expr.op in opnames.inplaceOps:
642
+ assert len(node.lcls) == 1
643
+ target = node.lcls[0]
644
+
645
+ # assert not node.lcl in self.collapsable
646
+ # Workarround for synthesizing inplace BinaryOps that don't put their result into the left argument.
647
+ # If the operation actually is inplace, don't hack it.
648
+
649
+ temp = node.expr.right
650
+ if target != node.expr.left:
651
+ if target == node.expr.right:
652
+ # Take care of the case Assign(a, BinaryOp(b, inplace, a))
653
+ # Otherwise the subsequent statement cobbers the right value.
654
+ temp = ast.Local(None)
655
+ stmt = "%s = %s" % (
656
+ self.seg.process(temp),
657
+ self.seg.process(node.expr.right),
658
+ )
659
+ self.emitStatement(stmt)
660
+
661
+ stmt = "%s = %s" % (
662
+ self.seg.process(target),
663
+ self.seg.process(node.expr.left),
664
+ )
665
+ self.emitStatement(stmt)
666
+
667
+ stmt = "%s %s %s" % (
668
+ self.seg.process(target),
669
+ node.expr.op,
670
+ self.seg.process(temp),
671
+ )
672
+ self.emitStatement(stmt)
673
+ elif isinstance(node.expr, ast.MakeFunction):
674
+ assert len(node.lcls) == 1
675
+ # HACK to rename the function
676
+ self(node.expr)
677
+ name = node.expr.code.name
678
+ lcl = self.seg.process(node.lcls[0])
679
+ if name != lcl:
680
+ self.emitStatement("%s = %s" % (lcl, name))
681
+ elif (
682
+ isinstance(node.expr, ast.Existing)
683
+ and node.expr.object.isConstant()
684
+ and isinstance(node.expr.object.pyobj, types.CodeType)
685
+ ):
686
+ # HACK
687
+ pass
688
+ ## elif isinstance(node.expr, (ast.ShortCircutAnd, ast.ShortCircutOr)):
689
+ ## expr, p = self(node.expr)
690
+ ##
691
+ ## stmt = "%s = %s" % (self.seg.process(node.lcl), expr)
692
+ ## self.emitStatement(stmt)
693
+ else:
694
+ if (
695
+ len(node.lcls) == 1
696
+ and node.lcls[0] in self.collapsable
697
+ and self.supressStatements
698
+ ):
699
+ # if node.lcl in self.collapsable:
700
+ self.seg.processCollapsed(node.lcls[0], node.expr)
701
+ else:
702
+ stmt = "%s = %s" % (
703
+ ", ".join([self.seg.process(lcl) for lcl in node.lcls]),
704
+ self.seg.process(node.expr),
705
+ )
706
+
707
+ self.emitStatement(stmt)
708
+
709
+ def visitDiscard(self, node):
710
+ stmt = self.seg.process(node.expr)
711
+ self.emitStatement(stmt)
712
+
713
+ def visitAssert(self, node):
714
+ if node.message:
715
+ stmt = "assert %s, %s" % (
716
+ self.seg.process(node.test, 24),
717
+ self.seg.process(node.message, 24),
718
+ )
719
+ else:
720
+ stmt = "assert %s" % (self.seg.process(node.test, 24))
721
+
722
+ self.emitStatement(stmt)
723
+
724
+ def visitStore(self, node):
725
+ stmt = "<store>(%s, %r, %s, %s)" % (
726
+ self.seg.process(node.expr, 24),
727
+ node.fieldtype,
728
+ self.seg.process(node.name, 24),
729
+ self.seg.process(node.value, 24),
730
+ )
731
+ self.emitStatement(stmt)
732
+
733
+ def visitDelete(self, node):
734
+ lcl = self.seg.process(node.lcl)
735
+ self.emitStatement("del %s" % lcl)
736
+
737
+ def visitPrint(self, node):
738
+ # Generate Python 3 print() function calls instead of Python 2 print statements
739
+ args = []
740
+
741
+ if node.expr:
742
+ expr = self.seg.process(node.expr)
743
+ args.append(expr)
744
+
745
+ if node.target:
746
+ target = self.seg.process(node.target)
747
+ args.append("file=%s" % target)
748
+
749
+ if args:
750
+ self.emitStatement("print(%s)" % ", ".join(args))
751
+ else:
752
+ self.emitStatement("print()")
753
+
754
+ def visitCondition(self, node):
755
+ self(node.preamble)
756
+
757
+ conditional = node.conditional
758
+
759
+ if isinstance(conditional, ast.ConvertToBool):
760
+ conditional = conditional.expr
761
+
762
+ if conditional in self.seg.collapsed:
763
+ return self.seg.collapsed[conditional]
764
+ else:
765
+ return self.seg(conditional)
766
+
767
+ def visitShortCircutOr(self, node):
768
+ prec = 22
769
+ partial = []
770
+ for term in node.terms:
771
+ text, inner = self(term)
772
+ partial.append(protect(text, inner, prec))
773
+ return " or ".join(partial), prec
774
+
775
+ def visitShortCircutAnd(self, node):
776
+ prec = 21
777
+ partial = []
778
+ for term in node.terms:
779
+ text, inner = self(term)
780
+ partial.append(protect(text, inner, prec))
781
+ return " and ".join(partial), prec
782
+
783
+ def visitSwitch(self, node):
784
+ cond, prec = self(node.condition)
785
+
786
+ self.out.startBlock("if %s" % cond)
787
+ self(node.t)
788
+ self.out.endBlock()
789
+
790
+ elseBlock = node.f
791
+
792
+ while elseBlock and elseBlock.significant():
793
+ if len(elseBlock.blocks) == 1 and isinstance(
794
+ elseBlock.blocks[0], ast.Switch
795
+ ):
796
+ switch = elseBlock.blocks[0]
797
+ cond, prec = self(switch.condition)
798
+ self.out.startBlock("elif %s" % cond)
799
+ self(switch.t)
800
+ self.out.endBlock()
801
+
802
+ elseBlock = switch.f
803
+ else:
804
+ self.out.startBlock("else")
805
+ self(elseBlock)
806
+ self.out.endBlock()
807
+ break
808
+
809
+ def visitTypeSwitchCase(self, node):
810
+ types = []
811
+ for t in node.types:
812
+ cond = self.seg.process(t)
813
+ types.append(cond)
814
+
815
+ if node.expr is not None:
816
+ expr = self.seg.process(node.expr)
817
+ self.out.startBlock("{case %s => %s}" % (", ".join(types), expr))
818
+ else:
819
+ self.out.startBlock("{case %s}" % (", ".join(types)))
820
+
821
+ self(node.body)
822
+ self.out.endBlock()
823
+
824
+ def visitTypeSwitch(self, node):
825
+ cond = self.seg.process(node.conditional)
826
+ self.out.startBlock("<type switch %s>" % cond)
827
+ for case in node.cases:
828
+ self(case)
829
+ self.out.endBlock()
830
+
831
+ def visitExceptionHandler(self, node):
832
+ self.processNoEmit(node.preamble)
833
+
834
+ t = self.seg.process(node.type)
835
+ args = [t]
836
+
837
+ if node.value:
838
+ value = self.seg.process(node.value)
839
+ args.append(value)
840
+
841
+ self.out.startBlock("except %s" % " as ".join(args))
842
+ self(node.body)
843
+ self.out.endBlock()
844
+
845
+ def visitTryExceptFinally(self, node):
846
+ self.out.startBlock("try")
847
+ self(node.body)
848
+ self.out.endBlock()
849
+
850
+ for handler in node.handlers:
851
+ self(handler)
852
+
853
+ if node.defaultHandler:
854
+ self.out.startBlock("except")
855
+ self(node.defaultHandler)
856
+ self.out.endBlock()
857
+
858
+ if node.else_:
859
+ self.out.startBlock("else")
860
+ self(node.else_)
861
+ self.out.endBlock()
862
+
863
+ if node.finally_:
864
+ self.out.startBlock("finally")
865
+ self(node.finally_)
866
+ self.out.endBlock()
867
+
868
+ @defaultdispatch
869
+ def visitDefault(self, node):
870
+ # Default handler for unhandled node types
871
+ self.emitStatement("# Unhandled node type: %s" % type(node).__name__)
872
+
873
+ def visitWhile(self, node):
874
+ cond, prec = self(node.condition)
875
+
876
+ self.out.startBlock("while %s" % cond)
877
+
878
+ self(node.body)
879
+
880
+ # Do the conditions for the next loop.
881
+ # Should, in fact, produce nothing.
882
+ cond, prec = self(node.condition)
883
+
884
+ self.out.endBlock()
885
+
886
+ if node.else_ and node.else_.significant():
887
+ self.out.startBlock("else")
888
+ self(node.else_)
889
+ self.out.endBlock()
890
+
891
+ def visitFor(self, node):
892
+ iterator = node.iterator
893
+ index = node.index
894
+ self.out.startBlock(
895
+ "for %s in %s" % (self.seg.process(index), self.seg.process(iterator))
896
+ )
897
+
898
+ self(node.body)
899
+
900
+ self.out.endBlock()
901
+
902
+ if node.else_ and node.else_.significant():
903
+ self.out.startBlock("else")
904
+ self(node.else_)
905
+ self.out.endBlock()
906
+
907
+ def visitSuite(self, node):
908
+ for child in node.blocks:
909
+ self(child)
910
+
911
+ def visitCode(self, node, name=None):
912
+ if name is None:
913
+ name = node.name
914
+ assert isIdentifier.match(name), name
915
+
916
+ (defines, uses), (globaldefines, globaluses) = defuse.evaluateCode(None, node)
917
+
918
+ collapsable = collapser.evaluateCode(None, node, defines, uses)
919
+ self.collapsable.update(collapsable)
920
+
921
+ p = node.codeparameters
922
+
923
+ # Set parmeter names
924
+ for lcl, pname in zip(p.params, p.paramnames):
925
+ self.seg.setLocalName(lcl, pname)
926
+
927
+ args = [self.seg.process(param) for param in p.params]
928
+
929
+ if p.defaults:
930
+ default_start = len(args) - len(p.defaults)
931
+ for offset, default in enumerate(p.defaults):
932
+ pyobj = getattr(getattr(default, "object", None), "pyobj", None)
933
+ if pyobj is MISSING_DEFAULT:
934
+ continue
935
+ index = default_start + offset
936
+ args[index] = "%s=%s" % (args[index], self.seg.process(default))
937
+
938
+ if p.vparam:
939
+ args.append("*%s" % self.seg.process(p.vparam))
940
+
941
+ if p.kparam:
942
+ args.append("**%s" % self.seg.process(p.kparam))
943
+
944
+ self.out.startBlock("def %s(%s)" % (name, ", ".join(args)))
945
+
946
+ # If globals are written to, define them here.
947
+ glbldef = [name for name in globaldefines.keys()]
948
+ if glbldef:
949
+ self.out.emitStatement("global %s" % ", ".join(glbldef))
950
+
951
+ self(node.ast)
952
+ self.out.endBlock()
953
+
954
+ def visitFunctionDef(self, node):
955
+ assert not node.decorators
956
+ self.visitCode(node.code, node.name)
957
+
958
+ def visitClassDef(self, node):
959
+ assert not node.decorators
960
+ bases = [self.seg.process(base) for base in node.bases]
961
+ self.out.startBlock("class %s(%s)" % (node.name, ", ".join(bases)))
962
+ self(node.body)
963
+ self.out.endBlock()
964
+
965
+ def visitMakeFunction(self, node):
966
+ assert not node.defaults
967
+
968
+ # assert not node.cells
969
+ self(node.code)
970
+
971
+ def visitLibrary(self, node):
972
+ self.emitStatement("# CANNOT GENERATE CODE FOR LIBRARY.")
973
+
974
+ def process(self, node):
975
+ return self(node)