tpy-lang 0.3.0.dev0__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 (333) hide show
  1. tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
  2. tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
  3. tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
  4. tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
  5. tpyc/__init__.py +104 -0
  6. tpyc/__main__.py +6 -0
  7. tpyc/_buildinfo.py +1 -0
  8. tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
  9. tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
  10. tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
  11. tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
  12. tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
  13. tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
  14. tpyc/_data/lib/tpy/_functools_macros.py +80 -0
  15. tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
  16. tpyc/_data/lib/tpy/argparse.py +2062 -0
  17. tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
  18. tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
  19. tpyc/_data/lib/tpy/base64.py +410 -0
  20. tpyc/_data/lib/tpy/bisect.py +39 -0
  21. tpyc/_data/lib/tpy/builtins.py +38 -0
  22. tpyc/_data/lib/tpy/dataclasses.py +354 -0
  23. tpyc/_data/lib/tpy/enum.py +23 -0
  24. tpyc/_data/lib/tpy/functools.py +33 -0
  25. tpyc/_data/lib/tpy/hashlib.py +206 -0
  26. tpyc/_data/lib/tpy/heapq.py +118 -0
  27. tpyc/_data/lib/tpy/io.py +395 -0
  28. tpyc/_data/lib/tpy/json.py +221 -0
  29. tpyc/_data/lib/tpy/math.py +406 -0
  30. tpyc/_data/lib/tpy/random.py +597 -0
  31. tpyc/_data/lib/tpy/re.py +467 -0
  32. tpyc/_data/lib/tpy/socket.py +379 -0
  33. tpyc/_data/lib/tpy/struct.py +178 -0
  34. tpyc/_data/lib/tpy/sys.py +40 -0
  35. tpyc/_data/lib/tpy/time.py +39 -0
  36. tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
  37. tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
  38. tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
  39. tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
  40. tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
  41. tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
  42. tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
  43. tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
  44. tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
  45. tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
  46. tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
  47. tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
  48. tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
  49. tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
  50. tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
  51. tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
  52. tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
  53. tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
  54. tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
  55. tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
  56. tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
  57. tpyc/_data/lib/tpy/tpy/_version.py +29 -0
  58. tpyc/_data/lib/tpy/tpy/bits.py +28 -0
  59. tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
  60. tpyc/_data/lib/tpy/tpy/extern.py +8 -0
  61. tpyc/_data/lib/tpy/tpy/mem.py +49 -0
  62. tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
  63. tpyc/_data/lib/tpy/tpy/version.py +21 -0
  64. tpyc/_data/lib/tpy/typing.py +13 -0
  65. tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
  66. tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
  67. tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
  68. tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
  69. tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
  70. tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
  71. tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
  72. tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
  73. tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
  74. tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
  75. tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
  76. tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
  77. tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
  78. tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
  79. tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
  80. tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
  81. tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
  82. tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
  83. tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
  84. tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
  85. tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
  86. tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
  87. tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
  88. tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
  89. tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
  90. tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
  91. tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
  92. tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
  93. tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
  94. tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
  95. tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
  96. tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
  97. tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
  98. tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
  99. tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
  100. tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
  101. tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
  102. tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
  103. tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
  104. tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
  105. tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
  106. tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
  107. tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
  108. tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
  109. tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
  110. tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
  111. tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
  112. tpyc/_data/runtime/cpp/third_party/README.md +58 -0
  113. tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
  114. tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
  115. tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
  116. tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
  117. tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
  118. tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
  119. tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
  120. tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
  121. tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
  122. tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
  123. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
  124. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
  125. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
  126. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
  127. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
  128. tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
  129. tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
  130. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
  131. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
  132. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
  133. tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
  134. tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
  135. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
  136. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
  137. tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
  138. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
  139. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
  140. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
  141. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
  142. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
  143. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
  144. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
  145. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
  146. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
  147. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
  148. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
  149. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
  150. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
  151. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
  152. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
  153. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
  154. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
  155. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
  156. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
  157. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
  158. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
  159. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
  160. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
  161. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
  162. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
  163. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
  164. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
  165. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
  166. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
  167. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
  168. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
  169. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
  170. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
  171. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
  172. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
  173. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
  174. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
  175. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
  176. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
  177. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
  178. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
  179. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
  180. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
  181. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
  182. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
  183. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
  184. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
  185. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
  186. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
  187. tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
  188. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
  189. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
  190. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
  191. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
  192. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
  193. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
  194. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
  195. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
  196. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
  197. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
  198. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
  199. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
  200. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
  201. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
  202. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
  203. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
  204. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
  205. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
  206. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
  207. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
  208. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
  209. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
  210. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
  211. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
  212. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
  213. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
  214. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
  215. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
  216. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
  217. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
  218. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
  219. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
  220. tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
  221. tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
  222. tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
  223. tpyc/build/__init__.py +7 -0
  224. tpyc/build/pcre2.py +122 -0
  225. tpyc/build/third_party.py +413 -0
  226. tpyc/cli.py +822 -0
  227. tpyc/codegen_cpp/__init__.py +18 -0
  228. tpyc/codegen_cpp/builtins.py +484 -0
  229. tpyc/codegen_cpp/context.py +2064 -0
  230. tpyc/codegen_cpp/expressions.py +5940 -0
  231. tpyc/codegen_cpp/functions.py +1913 -0
  232. tpyc/codegen_cpp/gen_async.py +3258 -0
  233. tpyc/codegen_cpp/gen_generators.py +657 -0
  234. tpyc/codegen_cpp/generator.py +2258 -0
  235. tpyc/codegen_cpp/match.py +1997 -0
  236. tpyc/codegen_cpp/param_const.py +172 -0
  237. tpyc/codegen_cpp/protocols.py +907 -0
  238. tpyc/codegen_cpp/records.py +1654 -0
  239. tpyc/codegen_cpp/resumable_cfg.py +1651 -0
  240. tpyc/codegen_cpp/statements.py +4963 -0
  241. tpyc/codegen_cpp/string_dispatch.py +76 -0
  242. tpyc/codegen_cpp/test_context.py +46 -0
  243. tpyc/codegen_cpp/test_param_const.py +113 -0
  244. tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
  245. tpyc/codegen_cpp/type_resolution.py +53 -0
  246. tpyc/codegen_cpp/types.py +436 -0
  247. tpyc/codegen_cpp/variant_access.py +135 -0
  248. tpyc/coercions.py +749 -0
  249. tpyc/compilation_context.py +57 -0
  250. tpyc/compiler.py +3945 -0
  251. tpyc/cycle_detection.py +358 -0
  252. tpyc/diagnostics.py +135 -0
  253. tpyc/dump_types.py +353 -0
  254. tpyc/frontend_diagnostics.py +47 -0
  255. tpyc/frontend_ir/__init__.py +140 -0
  256. tpyc/frontend_ir/lower.py +1098 -0
  257. tpyc/frontend_ir/nodes.py +718 -0
  258. tpyc/frontend_ir/resolver_adapter.py +151 -0
  259. tpyc/frontend_plugin.py +209 -0
  260. tpyc/install_docs.py +81 -0
  261. tpyc/liveness.py +756 -0
  262. tpyc/macro_api.py +1724 -0
  263. tpyc/macro_loader.py +497 -0
  264. tpyc/module_names.py +64 -0
  265. tpyc/modules/__init__.py +31 -0
  266. tpyc/modules/defs.py +89 -0
  267. tpyc/modules/registry.py +36 -0
  268. tpyc/modules/resolver.py +192 -0
  269. tpyc/modules/type_resolution.py +629 -0
  270. tpyc/namespace.py +172 -0
  271. tpyc/parse/__init__.py +84 -0
  272. tpyc/parse/imports.py +490 -0
  273. tpyc/parse/nodes.py +1732 -0
  274. tpyc/parse/parser.py +4043 -0
  275. tpyc/parse/resolve_refs.py +466 -0
  276. tpyc/parse/type_resolver.py +1060 -0
  277. tpyc/prescan.py +254 -0
  278. tpyc/qnames.py +149 -0
  279. tpyc/repl.py +529 -0
  280. tpyc/repl_backends.py +848 -0
  281. tpyc/sema/__init__.py +21 -0
  282. tpyc/sema/analyzer.py +3625 -0
  283. tpyc/sema/bound_check.py +72 -0
  284. tpyc/sema/builder_trace.py +684 -0
  285. tpyc/sema/calls.py +5406 -0
  286. tpyc/sema/compatibility.py +2107 -0
  287. tpyc/sema/context.py +1243 -0
  288. tpyc/sema/expressions.py +3737 -0
  289. tpyc/sema/flow_facts.py +199 -0
  290. tpyc/sema/init_tracker.py +150 -0
  291. tpyc/sema/list_literals.py +69 -0
  292. tpyc/sema/literal_utils.py +27 -0
  293. tpyc/sema/local_deduction.py +1088 -0
  294. tpyc/sema/macros.py +179 -0
  295. tpyc/sema/match.py +1177 -0
  296. tpyc/sema/method_expansion.py +347 -0
  297. tpyc/sema/methods.py +2197 -0
  298. tpyc/sema/mutation_propagation.py +268 -0
  299. tpyc/sema/narrowing.py +857 -0
  300. tpyc/sema/numeric_lattice.py +160 -0
  301. tpyc/sema/operators.py +402 -0
  302. tpyc/sema/overloads.py +841 -0
  303. tpyc/sema/protocols.py +1209 -0
  304. tpyc/sema/reach_analysis.py +202 -0
  305. tpyc/sema/registration.py +3156 -0
  306. tpyc/sema/scope_tracker.py +193 -0
  307. tpyc/sema/statements.py +4426 -0
  308. tpyc/sema/type_ops.py +1879 -0
  309. tpyc/sema/value_range.py +181 -0
  310. tpyc/symbol_binding.py +259 -0
  311. tpyc/test_c3_mro.py +208 -0
  312. tpyc/test_cli_argv.py +52 -0
  313. tpyc/test_compiler.py +559 -0
  314. tpyc/test_contains_type_param.py +101 -0
  315. tpyc/test_cycle_detection.py +221 -0
  316. tpyc/test_dump_types.py +225 -0
  317. tpyc/test_install_docs.py +65 -0
  318. tpyc/test_local_cpp_form.py +135 -0
  319. tpyc/test_macro_loader.py +76 -0
  320. tpyc/test_method_expansion.py +254 -0
  321. tpyc/test_nominal_identity.py +182 -0
  322. tpyc/test_overloads.py +410 -0
  323. tpyc/test_parse.py +303 -0
  324. tpyc/test_parse_type_ref.py +506 -0
  325. tpyc/test_parse_version_info.py +58 -0
  326. tpyc/test_reach_analysis.py +72 -0
  327. tpyc/test_ref_type.py +216 -0
  328. tpyc/test_send_sync_substitution.py +276 -0
  329. tpyc/test_tuple_mutation_propagation.py +206 -0
  330. tpyc/test_type_def_registry.py +1729 -0
  331. tpyc/test_union_types.py +195 -0
  332. tpyc/type_def_registry.py +975 -0
  333. tpyc/typesys.py +5104 -0
@@ -0,0 +1,199 @@
1
+ """
2
+ FlowFacts -- immutable snapshot of flow-sensitive analysis state.
3
+
4
+ Captures the flow-sensitive properties that must be saved, restored,
5
+ and merged at branch/loop boundaries: definite assignment, termination,
6
+ rvalue tracking, parameter provenance, safe-to-return locals, pointer
7
+ non-null status, type narrowing, and consumed-variable tracking.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ from dataclasses import dataclass
13
+ from enum import Enum, auto
14
+ from typing import TYPE_CHECKING
15
+
16
+ from .context import BorrowKind, BORROW_KIND_RANK
17
+ from .value_range import ValueRange
18
+
19
+ if TYPE_CHECKING:
20
+ from ..typesys import TpyType
21
+
22
+
23
+ class _MergePolicy(Enum):
24
+ INTERSECT = auto()
25
+ UNION = auto()
26
+
27
+
28
+ def _merge_sets(
29
+ then_set: frozenset[str],
30
+ else_set: frozenset[str],
31
+ then_term: bool,
32
+ else_term: bool,
33
+ policy: _MergePolicy,
34
+ ) -> frozenset[str]:
35
+ """Merge two frozensets across branch endpoints.
36
+
37
+ When a branch terminates (return/break/raise), it cannot reach the
38
+ merge point, so only the other branch's set matters. When both are
39
+ live, ``policy`` decides: INTERSECT (conservative -- must hold on
40
+ both paths) or UNION (conservative -- may hold on either path).
41
+ """
42
+ if then_term and else_term:
43
+ return then_set | else_set
44
+ if then_term:
45
+ return else_set
46
+ if else_term:
47
+ return then_set
48
+ if policy is _MergePolicy.INTERSECT:
49
+ return then_set & else_set
50
+ return then_set | else_set
51
+
52
+
53
+ def _merge_narrowed(
54
+ then_narrowed: frozenset[tuple[str, TpyType]],
55
+ else_narrowed: frozenset[tuple[str, TpyType]],
56
+ then_term: bool,
57
+ else_term: bool,
58
+ ) -> frozenset[tuple[str, TpyType]]:
59
+ """Merge narrowed-type mappings, represented as frozensets of (name, type) pairs.
60
+
61
+ When both branches are live, only narrowings that agree on both sides
62
+ survive (key present in both with equal type).
63
+ """
64
+ if then_term and else_term:
65
+ then_dict = dict(then_narrowed)
66
+ then_dict.update(else_narrowed)
67
+ return frozenset(then_dict.items())
68
+ if then_term:
69
+ return else_narrowed
70
+ if else_term:
71
+ return then_narrowed
72
+ then_dict = dict(then_narrowed)
73
+ else_dict = dict(else_narrowed)
74
+ merged = {k: v for k, v in then_dict.items()
75
+ if k in else_dict and else_dict[k] == v}
76
+ return frozenset(merged.items())
77
+
78
+
79
+ def _merge_value_ranges(
80
+ then_ranges: frozenset[tuple[str, ValueRange]],
81
+ else_ranges: frozenset[tuple[str, ValueRange]],
82
+ then_term: bool,
83
+ else_term: bool,
84
+ ) -> frozenset[tuple[str, ValueRange]]:
85
+ """Merge value range mappings across branch endpoints.
86
+
87
+ When both branches are live, per-variable ranges are merged (widened)
88
+ using ValueRange.merge. Variables tracked on only one branch are dropped
89
+ (conservative -- we can only use a fact if it holds on all paths).
90
+ """
91
+ if then_term and else_term:
92
+ then_dict = dict(then_ranges)
93
+ then_dict.update(else_ranges)
94
+ return frozenset(then_dict.items())
95
+ if then_term:
96
+ return else_ranges
97
+ if else_term:
98
+ return then_ranges
99
+ then_dict = dict(then_ranges)
100
+ else_dict = dict(else_ranges)
101
+ merged = {}
102
+ for k, v in then_dict.items():
103
+ if k in else_dict:
104
+ merged[k] = ValueRange.merge(v, else_dict[k])
105
+ return frozenset(merged.items())
106
+
107
+
108
+ def _merge_borrow_triples(
109
+ then_borrows: frozenset[tuple[str, str, BorrowKind]],
110
+ else_borrows: frozenset[tuple[str, str, BorrowKind]],
111
+ then_term: bool,
112
+ else_term: bool,
113
+ ) -> frozenset[tuple[str, str, BorrowKind]]:
114
+ """Merge borrow (storage, borrower, kind) triples across branch endpoints.
115
+
116
+ Uses UNION policy: a borrow exists after the merge if it exists in
117
+ either live branch (conservative -- may hold on either path).
118
+ When the same (storage, borrower) has different kinds on the two branches,
119
+ the more dangerous kind wins (element > alias, ptr > alias, iter > alias).
120
+ """
121
+ if then_term and else_term:
122
+ combined = then_borrows | else_borrows
123
+ elif then_term:
124
+ combined = else_borrows
125
+ elif else_term:
126
+ combined = then_borrows
127
+ else:
128
+ combined = then_borrows | else_borrows
129
+ # Deduplicate (storage, borrower) pairs, keeping the more dangerous kind
130
+ best: dict[tuple[str, str], BorrowKind] = {}
131
+ for storage, borrower, kind in combined:
132
+ key = (storage, borrower)
133
+ prev = best.get(key)
134
+ if prev is None or BORROW_KIND_RANK[kind] > BORROW_KIND_RANK[prev]:
135
+ best[key] = kind
136
+ return frozenset((s, b, k) for (s, b), k in best.items())
137
+
138
+
139
+ @dataclass(frozen=True, slots=True)
140
+ class FlowFacts:
141
+ """Immutable snapshot of flow-sensitive analysis state."""
142
+
143
+ definitely_assigned: frozenset[str] = frozenset()
144
+ init_terminated: bool = False
145
+ rvalue_vars: frozenset[str] = frozenset()
146
+ param_provenance_vars: frozenset[str] = frozenset()
147
+ safe_to_return_vars: frozenset[str] = frozenset()
148
+ non_null_ptr_vars: frozenset[str] = frozenset()
149
+ narrowed_types: frozenset[tuple[str, TpyType]] = frozenset()
150
+ consumed_vars: frozenset[str] = frozenset()
151
+ # Borrow map: (storage_name, borrower_name, BorrowKind) triples.
152
+ # "__for_iter" is used as the borrower for implicit for-loop iterator borrows.
153
+ borrows: frozenset[tuple[str, str, BorrowKind]] = frozenset()
154
+ value_ranges: frozenset[tuple[str, ValueRange]] = frozenset()
155
+
156
+ @staticmethod
157
+ def merge(then: FlowFacts, else_: FlowFacts) -> FlowFacts:
158
+ """Merge flow facts from then/else branches."""
159
+ then_term = then.init_terminated
160
+ else_term = else_.init_terminated
161
+ return FlowFacts(
162
+ definitely_assigned=_merge_sets(
163
+ then.definitely_assigned, else_.definitely_assigned,
164
+ then_term, else_term, _MergePolicy.INTERSECT,
165
+ ),
166
+ init_terminated=then_term and else_term,
167
+ rvalue_vars=_merge_sets(
168
+ then.rvalue_vars, else_.rvalue_vars,
169
+ then_term, else_term, _MergePolicy.INTERSECT,
170
+ ),
171
+ param_provenance_vars=_merge_sets(
172
+ then.param_provenance_vars, else_.param_provenance_vars,
173
+ then_term, else_term, _MergePolicy.INTERSECT,
174
+ ),
175
+ safe_to_return_vars=_merge_sets(
176
+ then.safe_to_return_vars, else_.safe_to_return_vars,
177
+ then_term, else_term, _MergePolicy.INTERSECT,
178
+ ),
179
+ non_null_ptr_vars=_merge_sets(
180
+ then.non_null_ptr_vars, else_.non_null_ptr_vars,
181
+ then_term, else_term, _MergePolicy.INTERSECT,
182
+ ),
183
+ narrowed_types=_merge_narrowed(
184
+ then.narrowed_types, else_.narrowed_types,
185
+ then_term, else_term,
186
+ ),
187
+ consumed_vars=_merge_sets(
188
+ then.consumed_vars, else_.consumed_vars,
189
+ then_term, else_term, _MergePolicy.UNION,
190
+ ),
191
+ borrows=_merge_borrow_triples(
192
+ then.borrows, else_.borrows,
193
+ then_term, else_term,
194
+ ),
195
+ value_ranges=_merge_value_ranges(
196
+ then.value_ranges, else_.value_ranges,
197
+ then_term, else_term,
198
+ ),
199
+ )
@@ -0,0 +1,150 @@
1
+ """
2
+ TurboPython Definite-Assignment Tracker
3
+
4
+ Tracks which variables are guaranteed to be initialized on all paths
5
+ reaching the current point. Prevents use-before-assignment errors that
6
+ would be undefined behavior in generated C++.
7
+ """
8
+
9
+ from __future__ import annotations
10
+ from typing import TYPE_CHECKING
11
+
12
+ from .flow_facts import FlowFacts
13
+
14
+ if TYPE_CHECKING:
15
+ from ..typesys import TpyType
16
+ from .context import SemanticContext
17
+
18
+
19
+
20
+
21
+ class InitTracker:
22
+ """Definite-assignment and rvalue-vars flow analysis."""
23
+
24
+ def __init__(self, ctx: SemanticContext):
25
+ self.ctx = ctx
26
+
27
+ def save(self) -> FlowFacts:
28
+ return FlowFacts(
29
+ definitely_assigned=frozenset(self.ctx.func.definitely_assigned),
30
+ init_terminated=self.ctx.func.init_terminated,
31
+ rvalue_vars=frozenset(self.ctx.func.rvalue_vars),
32
+ param_provenance_vars=frozenset(self.ctx.func.param_provenance_vars),
33
+ safe_to_return_vars=frozenset(self.ctx.func.safe_to_return_vars),
34
+ non_null_ptr_vars=frozenset(self.ctx.func.non_null_ptr_vars),
35
+ narrowed_types=frozenset(self.ctx.func.narrowed_types.items()),
36
+ consumed_vars=frozenset(self.ctx.func.consumed_vars),
37
+ borrows=self.ctx.func.borrow_tracker.freeze(),
38
+ value_ranges=frozenset(self.ctx.func.value_ranges.items()),
39
+ )
40
+
41
+ def restore(self, state: FlowFacts) -> None:
42
+ self.ctx.func.definitely_assigned = set(state.definitely_assigned)
43
+ self.ctx.func.init_terminated = state.init_terminated
44
+ self.ctx.func.rvalue_vars = set(state.rvalue_vars)
45
+ self.ctx.func.param_provenance_vars = set(state.param_provenance_vars)
46
+ self.ctx.func.safe_to_return_vars = set(state.safe_to_return_vars)
47
+ self.ctx.func.non_null_ptr_vars = set(state.non_null_ptr_vars)
48
+ # Invariant: pending post-access ptr-narrowing flushes at statement
49
+ # boundary (see `analyze_stmt` try/finally). Any entries surviving a
50
+ # restore would leak into a branch they don't belong to.
51
+ self.ctx.func.pending_non_null_ptr_vars.clear()
52
+ self.ctx.func.narrowed_types = dict(state.narrowed_types)
53
+ self.ctx.func.consumed_vars = set(state.consumed_vars)
54
+ self.ctx.func.borrow_tracker.restore_from_frozen(state.borrows)
55
+ self.ctx.func.value_ranges = dict(state.value_ranges)
56
+
57
+ def mark_assigned(self, name: str) -> None:
58
+ self.ctx.func.definitely_assigned.add(name)
59
+
60
+ def mark_terminated(self) -> None:
61
+ self.ctx.func.init_terminated = True
62
+
63
+ def mark_provenance(self, name: str, is_param_derived: bool) -> None:
64
+ """Track whether a variable's storage derives from parameters/globals."""
65
+ if is_param_derived:
66
+ self.ctx.func.param_provenance_vars.add(name)
67
+ else:
68
+ self.ctx.func.param_provenance_vars.discard(name)
69
+
70
+ def mark_safe_to_return(self, name: str, is_safe: bool) -> None:
71
+ """Record that returning ``name`` after this binding is non-dangling.
72
+
73
+ Membership is what is_dangling_return consults for locals, so callers
74
+ must also keep this set a superset of param_provenance_vars (the
75
+ merge invariant relied on by FlowFacts.merge / apply_loop_exit_facts).
76
+ See is_safe_to_return_expr in compatibility.py for the source rule.
77
+ """
78
+ if is_safe:
79
+ self.ctx.func.safe_to_return_vars.add(name)
80
+ else:
81
+ self.ctx.func.safe_to_return_vars.discard(name)
82
+
83
+ def mark_non_null_ptr(self, name: str, is_non_null: bool) -> None:
84
+ """Track whether a pointer variable is provably non-null."""
85
+ if is_non_null:
86
+ self.ctx.func.non_null_ptr_vars.add(name)
87
+ else:
88
+ self.ctx.func.non_null_ptr_vars.discard(name)
89
+
90
+ def add_loop_var_provenance(self, name: str) -> None:
91
+ # Both sets must move together: leaving safe_to_return_vars empty
92
+ # while populating param_provenance_vars would let an intersecting
93
+ # merge drop the var from safe_to_return_vars while keeping it in
94
+ # param_provenance_vars, breaking the documented subset invariant.
95
+ self.ctx.func.param_provenance_vars.add(name)
96
+ self.ctx.func.safe_to_return_vars.add(name)
97
+
98
+ def remove_loop_var_provenance(self, name: str) -> None:
99
+ self.ctx.func.param_provenance_vars.discard(name)
100
+ self.ctx.func.safe_to_return_vars.discard(name)
101
+
102
+ def apply_loop_entry_facts(
103
+ self,
104
+ before: FlowFacts,
105
+ condition_type_facts: dict[str, TpyType] | None = None,
106
+ ) -> None:
107
+ """Apply flow facts at loop body entry.
108
+
109
+ Restores the state from just before the loop, so that outer
110
+ narrowing proven by enclosing if-blocks is preserved inside the
111
+ loop body. Any additional narrowing the loop condition itself
112
+ proves (e.g. ``while x is not None``) is layered on top.
113
+ """
114
+ self.ctx.func.definitely_assigned = set(before.definitely_assigned)
115
+ self.ctx.func.init_terminated = False
116
+ self.ctx.func.rvalue_vars = set(before.rvalue_vars)
117
+ self.ctx.func.param_provenance_vars = set(before.param_provenance_vars)
118
+ self.ctx.func.safe_to_return_vars = set(before.safe_to_return_vars)
119
+ self.ctx.func.non_null_ptr_vars = set(before.non_null_ptr_vars)
120
+ self.ctx.func.narrowed_types = dict(before.narrowed_types)
121
+ self.ctx.func.consumed_vars = set(before.consumed_vars)
122
+ self.ctx.func.borrow_tracker.restore_from_frozen(before.borrows)
123
+ self.ctx.func.value_ranges = dict(before.value_ranges)
124
+ if condition_type_facts is not None:
125
+ self.ctx.func.narrowed_types.update(condition_type_facts)
126
+
127
+ def merge_branches(self, then_state: FlowFacts, else_state: FlowFacts) -> None:
128
+ self.restore(FlowFacts.merge(then_state, else_state))
129
+
130
+ def apply_loop_exit_facts(self, before: FlowFacts) -> None:
131
+ """Apply post-loop state for a may-execute-zero-times loop.
132
+
133
+ Call with live post-body state still in ``ctx.func.*``. Monotone
134
+ kill-facts (pointer non-null, parameter provenance, safe-to-return,
135
+ type narrowing) survive iff they held both before the loop AND at
136
+ body exit, so a reassignment that cleared a fact is not undone by
137
+ ``restore(before)``.
138
+
139
+ Single-pass conservative approximation -- proper fixpoint belongs
140
+ with the THIR/MIR migration (see ``docs/IR_DESIGN.md``).
141
+ """
142
+ body_end_nn_ptr = frozenset(self.ctx.func.non_null_ptr_vars)
143
+ body_end_param_prov = frozenset(self.ctx.func.param_provenance_vars)
144
+ body_end_safe_return = frozenset(self.ctx.func.safe_to_return_vars)
145
+ body_end_narrowed = frozenset(self.ctx.func.narrowed_types.items())
146
+ self.restore(before)
147
+ self.ctx.func.non_null_ptr_vars &= body_end_nn_ptr
148
+ self.ctx.func.param_provenance_vars &= body_end_param_prov
149
+ self.ctx.func.safe_to_return_vars &= body_end_safe_return
150
+ self.ctx.func.narrowed_types = dict(body_end_narrowed & before.narrowed_types)
@@ -0,0 +1,69 @@
1
+ """
2
+ TurboPython Iterable Type Helpers
3
+
4
+ General-purpose iterable-type queries (is_type_iterable, get_iterable_element_type).
5
+ List literal deduction logic has moved to local_deduction.LocalTypeDeduction.
6
+ """
7
+
8
+ from __future__ import annotations
9
+ from typing import TYPE_CHECKING
10
+
11
+ from ..typesys import (
12
+ TpyType, GenExprType,
13
+ is_protocol_type,
14
+ )
15
+ from ..diagnostics import SemanticError
16
+
17
+ if TYPE_CHECKING:
18
+ from ..parse import SourceLocation
19
+ from .context import SemanticContext
20
+
21
+ from tpyc import modules as builtin_modules
22
+ from ..type_def_registry import is_iterator_adapter
23
+
24
+
25
+ class IterableHelper:
26
+ """General-purpose iterable type queries."""
27
+
28
+ def __init__(self, ctx: SemanticContext):
29
+ self.ctx = ctx
30
+
31
+ def is_type_iterable(self, typ: TpyType) -> bool:
32
+ """Check if a type is iterable.
33
+
34
+ A type is iterable if it:
35
+ - Is a NativeIterable[T], Iterator[T], Iterable[T], or
36
+ Spannable[T] protocol type (used as parameter type)
37
+ - Is a compiler-internal iterator adapter (CopyIter[T], OwnIter[T],
38
+ generator-expression type) or SpanIter[T] (stub-declared but its
39
+ __iter__(self) -> Self currently bypasses the unified lookup --
40
+ the parser doesn't resolve Self to SpanIter, so the adapter
41
+ allowlist covers it; low-priority follow-up)
42
+ - Has __next__() (Iterator conformance)
43
+ - Has __iter__() returning an iterator type
44
+ """
45
+ if is_protocol_type(typ) and typ.qualified_name() in builtin_modules.ITERABLE_PROTOCOL_QNAMES:
46
+ return True
47
+ if is_iterator_adapter(typ) or isinstance(typ, GenExprType):
48
+ return True
49
+ if builtin_modules.get_iter_element_type(typ, registry=self.ctx.registry) is not None:
50
+ return True
51
+ if builtin_modules.get_error_return_next_element_type(typ, registry=self.ctx.registry) is not None:
52
+ return True
53
+ return False
54
+
55
+ def get_iterable_element_type_or_none(self, iterable_type: TpyType) -> TpyType | None:
56
+ """Get the element type of an iterable, or None if not iterable."""
57
+ return builtin_modules.get_iterable_element_type(iterable_type, registry=self.ctx.registry)
58
+
59
+ def get_iterable_element_type(
60
+ self, iterable_type: TpyType, loc: SourceLocation | None = None,
61
+ ) -> TpyType:
62
+ """Get the element type of an iterable for for-each loops.
63
+
64
+ Raises SemanticError if type is not iterable.
65
+ """
66
+ elem_type = self.get_iterable_element_type_or_none(iterable_type)
67
+ if elem_type is not None:
68
+ return elem_type
69
+ raise SemanticError(f"Cannot iterate over type {iterable_type}", loc)
@@ -0,0 +1,27 @@
1
+ """Shared helpers for extracting literal values from AST expression nodes.
2
+
3
+ Handles bare `str` / `int` / `bool` literals plus the unary-minus form
4
+ `-<int_literal>` (CPython encodes `-1` as `TpyUnaryOp("-", TpyIntLiteral(1))`),
5
+ and peels a single `TpyCoerce` wrapper so callers don't have to.
6
+ """
7
+ from ..parse import (
8
+ TpyExpr, TpyStrLiteral, TpyIntLiteral, TpyBoolLiteral, TpyUnaryOp, TpyCoerce,
9
+ )
10
+ from ..typesys import LiteralValue, LiteralTag
11
+
12
+
13
+ def literal_value_from_expr(expr: TpyExpr | None) -> LiteralValue | None:
14
+ """Return a tagged `LiteralValue` for a literal AST node, else None."""
15
+ if expr is None:
16
+ return None
17
+ inner = expr.expr if isinstance(expr, TpyCoerce) else expr
18
+ if isinstance(inner, TpyStrLiteral):
19
+ return LiteralValue(LiteralTag.STR, inner.value)
20
+ if isinstance(inner, TpyBoolLiteral):
21
+ return LiteralValue(LiteralTag.BOOL, inner.value)
22
+ if isinstance(inner, TpyIntLiteral):
23
+ return LiteralValue(LiteralTag.INT, inner.value)
24
+ if (isinstance(inner, TpyUnaryOp) and inner.op == "-"
25
+ and isinstance(inner.operand, TpyIntLiteral)):
26
+ return LiteralValue(LiteralTag.INT, -inner.operand.value)
27
+ return None