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
tpyc/parse/imports.py ADDED
@@ -0,0 +1,490 @@
1
+ """
2
+ TurboPython import processing.
3
+
4
+ Constants and logic for handling import statements during parsing.
5
+ """
6
+
7
+ from __future__ import annotations
8
+ import ast
9
+ from typing import Callable
10
+
11
+ from .nodes import (
12
+ ParseError, SourceLocation, RelativeImportKey,
13
+ TpyImport, ParseWarning,
14
+ )
15
+ from ..module_names import public_module_name
16
+
17
+ # Implicit stdlib modules -- always compiled by the compiler, so imports from
18
+ # these modules don't need TpyImport nodes for __tpy_init() ordering.
19
+ _IMPLICIT_MODULES = frozenset({"typing", "tpy", "builtins"})
20
+
21
+ # Private submodule -> public module name overrides.
22
+ # Used when public_module_name() can't derive the correct public name
23
+ # (e.g. tpy._bootstrap._extern maps to tpy.extern, not tpy).
24
+ _PRIVATE_MODULE_PUBLIC_NAMES: dict[str, str] = {
25
+ "tpy._bootstrap._extern": "tpy.extern",
26
+ "tpy._typing": "typing",
27
+ }
28
+
29
+
30
+ class NonLiteralAllError(Exception):
31
+ """Raised when __all__ is defined but not evaluable at compile time.
32
+
33
+ Carries the offending value's AST node so the caller can surface a
34
+ line/column in the user-facing diagnostic.
35
+ """
36
+ def __init__(self, message: str, node: 'ast.AST | None' = None):
37
+ super().__init__(message)
38
+ self.node = node
39
+
40
+
41
+ def read_module_all(tree: ast.Module) -> 'tuple[frozenset[str], SourceLocation] | None':
42
+ """Capture the module's own `__all__` from its top-level scope.
43
+
44
+ Returns `(literal frozenset, loc)` when `__all__` is defined as a
45
+ compile-time literal (list / tuple / set); `loc` points at the
46
+ literal's RHS so callers can emit diagnostics that pin the
47
+ `__all__` declaration. Returns `None` when `__all__` is not
48
+ defined. Raises `NonLiteralAllError` when `__all__` is defined but
49
+ is not a literal.
50
+
51
+ Mirrors the `__all__` branch of `scan_star_exports`; lives next to
52
+ it so the parser can capture this without re-walking the source.
53
+ Consumed by `Compiler._expand_star_imports_for_module` to filter
54
+ `from M import *` against the source's per-attribute table.
55
+ """
56
+ all_value = None
57
+ for node in ast.iter_child_nodes(tree):
58
+ if isinstance(node, ast.Assign):
59
+ for target in node.targets:
60
+ if isinstance(target, ast.Name) and target.id == "__all__":
61
+ all_value = node.value
62
+ elif (isinstance(node, ast.AnnAssign)
63
+ and isinstance(node.target, ast.Name)
64
+ and node.target.id == "__all__" and node.value):
65
+ all_value = node.value
66
+ if all_value is None:
67
+ return None
68
+ try:
69
+ names = frozenset(ast.literal_eval(all_value))
70
+ except (ValueError, TypeError):
71
+ raise NonLiteralAllError(
72
+ "__all__ is not a compile-time literal", all_value)
73
+ return names, SourceLocation(all_value.lineno, all_value.col_offset)
74
+
75
+
76
+ def scan_star_exports(source: str) -> frozenset[str]:
77
+ """Determine which names a module exports for 'from X import *'.
78
+
79
+ If ``__all__`` is defined as a literal, returns exactly those names.
80
+ If ``__all__`` is defined but not a compile-time literal, raises
81
+ ``NonLiteralAllError``.
82
+ Otherwise returns all public top-level names (functions, classes,
83
+ assignments, annotated assignments, and imported names) whose name
84
+ does not start with ``_`` -- matching CPython semantics.
85
+ """
86
+ tree = ast.parse(source)
87
+ explicit_all = read_module_all(tree)
88
+ if explicit_all is not None:
89
+ return explicit_all[0]
90
+
91
+ # No __all__ -- collect all public top-level names (matching CPython)
92
+ names: set[str] = set()
93
+ for node in ast.iter_child_nodes(tree):
94
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
95
+ if not node.name.startswith("_"):
96
+ names.add(node.name)
97
+ elif isinstance(node, ast.ClassDef):
98
+ if not node.name.startswith("_"):
99
+ names.add(node.name)
100
+ elif isinstance(node, ast.Assign):
101
+ for target in node.targets:
102
+ if isinstance(target, ast.Name) and not target.id.startswith("_"):
103
+ names.add(target.id)
104
+ elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
105
+ if not node.target.id.startswith("_"):
106
+ names.add(node.target.id)
107
+ elif isinstance(node, ast.ImportFrom) and node.names:
108
+ if node.names[0].name != "*":
109
+ for alias in node.names:
110
+ local = alias.asname or alias.name
111
+ if not local.startswith("_"):
112
+ names.add(local)
113
+ return frozenset(names)
114
+
115
+
116
+ def _read_module_all(module_path: str) -> frozenset[str]:
117
+ """Read star exports from a stdlib .py module under lib/tpy/."""
118
+ # Deferred: tpyc.__init__ imports tpyc.parse, so top-level would be circular.
119
+ from tpyc import get_lib_dir
120
+ path = get_lib_dir() / "tpy" / module_path
121
+ if not path.exists():
122
+ return frozenset()
123
+ return scan_star_exports(path.read_text())
124
+
125
+
126
+ _module_all_cache: dict[str, frozenset[str]] = {}
127
+
128
+
129
+ def _get_module_all(module_path: str) -> frozenset[str]:
130
+ """Get __all__ from a module file (cached)."""
131
+ if module_path not in _module_all_cache:
132
+ _module_all_cache[module_path] = _read_module_all(module_path)
133
+ return _module_all_cache[module_path]
134
+
135
+
136
+ def get_tpy_exports() -> frozenset[str]:
137
+ """Get the set of names exported by 'from tpy import *' (cached)."""
138
+ return _get_module_all("tpy/__init__.py")
139
+
140
+
141
+ def get_builtins_exports() -> frozenset[str]:
142
+ """Get the set of names exported by builtins (cached)."""
143
+ return _get_module_all("builtins.py")
144
+
145
+
146
+ def get_typing_exports() -> frozenset[str]:
147
+ """Get the set of names exported by typing (cached)."""
148
+ return _get_module_all("typing.py")
149
+
150
+
151
+ def route_stdlib_name(name: str) -> 'tuple[str, str] | None':
152
+ """Return `(stdlib_module, name)` if `name` is exported by one of
153
+ the implicit stdlib modules (`tpy` / `builtins` / `typing`), else
154
+ `None`. Lets cross-module re-exports of stdlib names canonicalize
155
+ against the public stdlib module rather than the source module
156
+ (so e.g. `Int32` re-exported through `utils` still resolves at
157
+ `tpy.Int32`, not `utils.Int32`).
158
+ """
159
+ if name in get_tpy_exports():
160
+ return ("tpy", name)
161
+ if name in get_builtins_exports():
162
+ return ("builtins", name)
163
+ if name in get_typing_exports():
164
+ return ("typing", name)
165
+ return None
166
+
167
+
168
+ def is_parser_keyword(module_name: str, name: str) -> bool:
169
+ """Check if a specific name from a module is a parser keyword.
170
+
171
+ Only one name remains hardcoded: tpy.extern.builtin_decorator, which
172
+ must be recognized before any .py stubs can be compiled (bootstrap).
173
+ """
174
+ if "._" in module_name:
175
+ pub = _PRIVATE_MODULE_PUBLIC_NAMES.get(module_name) or public_module_name(module_name)
176
+ if pub == "tpy.extern":
177
+ return name == "builtin_decorator"
178
+ return False
179
+
180
+
181
+ class ImportProcessor:
182
+ """Processes and tracks import statements during parsing.
183
+
184
+ Separates import validation and tracking (semantic concerns)
185
+ from pure syntax parsing.
186
+ """
187
+
188
+ def __init__(self, warn_fn, module_name: str | None = None,
189
+ is_package_init: bool = False):
190
+ self._warn = warn_fn
191
+ self._module_name = module_name
192
+ self._is_package_init = is_package_init
193
+ self.tpy_import_aliases: dict[str, str] = {}
194
+ self.tpy_star_import: bool = False
195
+ # Set of module names that had 'from X import *'
196
+ self.star_imports: set[str] = set()
197
+ # Reference to the module's imports dict, set during process_import_from.
198
+ # Used by the parser for type resolution of imported builtin submodule types.
199
+ self.imports: dict[str, set[tuple[str, str]] | None] | None = None
200
+ # Reverse index: local_name -> (module_name, original_name) for O(1) lookup
201
+ self._name_index: dict[str, tuple[str, str]] = {}
202
+ # Local names whose import tuple has been rewritten by
203
+ # `canonicalize_name_index` to point at the defining module
204
+ # rather than a re-export facade. `TypeResolver` consults this
205
+ # set to gate `_module_qname` minting: parser-level aliases and
206
+ # builtin-module lookups are NOT canonicalized and so stay as
207
+ # bare `NominalType` without a qname.
208
+ self._canonical_imports: set[str] = set()
209
+
210
+ def _resolve_placeholder_module(self, key: str) -> str:
211
+ """Resolve a relative import placeholder to a public module name.
212
+
213
+ Uses the current module_name to compute the absolute path, then
214
+ applies public_module_name to map private submodules to public parents.
215
+ Falls back to the raw key if module_name is not set.
216
+
217
+ For package __init__.py files, the module name IS the package, so
218
+ level=1 means "within this package" (0 levels up from the package).
219
+ For regular files, the module name includes the filename, so level=1
220
+ means "same directory" (1 component stripped).
221
+ """
222
+ if not self._module_name:
223
+ return key
224
+ decoded = RelativeImportKey.decode(key)
225
+ parts = self._module_name.split(".")
226
+ # For __init__.py, package = module name; for regular files, package = parent
227
+ package_parts = parts if self._is_package_init else parts[:-1]
228
+ levels_up = decoded.level - 1
229
+ if levels_up > len(package_parts):
230
+ return key
231
+ base_parts = package_parts[:len(package_parts) - levels_up]
232
+ if decoded.partial:
233
+ absolute = ".".join(base_parts + [decoded.partial])
234
+ else:
235
+ absolute = ".".join(base_parts)
236
+ return _PRIVATE_MODULE_PUBLIC_NAMES.get(absolute) or public_module_name(absolute)
237
+
238
+ def get_import_source(self, local_name: str) -> tuple[str, str] | None:
239
+ """Find source module and original name for an imported name.
240
+
241
+ Returns (module_name, original_name) or None.
242
+ For relative imports from private submodules, the module name is
243
+ resolved to the public parent (e.g. tpy._core._types -> tpy, tpy._builtins._list -> tpy).
244
+ """
245
+ return self._name_index.get(local_name)
246
+
247
+ def canonicalize_name_index(
248
+ self, lookup: Callable[[str, str], tuple[str, str] | None],
249
+ ) -> None:
250
+ """Rewrite name-index entries to point at defining modules.
251
+
252
+ For each `(surface_module, original_name)` tuple, call `lookup`.
253
+ When it returns a tuple, record the name as canonical
254
+ (`is_canonical()` becomes True) and replace the entry if the
255
+ lookup changed it. Called by the compiler between parse and
256
+ sema to redirect re-export facades to the module that actually
257
+ declares the symbol, so `TypeResolver` can mint canonical
258
+ `_module_qname` on its first pass -- but only for names whose
259
+ lookup succeeded (records / enums / protocols), keeping aliases
260
+ and other non-type imports free of qname pollution that would
261
+ suppress downstream resolution passes.
262
+ """
263
+ for local_name, (surface, original) in list(self._name_index.items()):
264
+ target = lookup(surface, original)
265
+ if target is None:
266
+ continue
267
+ if target != (surface, original):
268
+ self._name_index[local_name] = target
269
+ self._canonical_imports.add(local_name)
270
+
271
+ def is_canonical(self, local_name: str) -> bool:
272
+ """True if `local_name`'s import tuple was canonicalized and
273
+ points at the defining module for a record / enum / protocol."""
274
+ return local_name in self._canonical_imports
275
+
276
+ def _index_import(self, module_name: str, original: str, local: str) -> None:
277
+ """Add a name to the reverse lookup index."""
278
+ if RelativeImportKey.is_placeholder(module_name):
279
+ resolved = self._resolve_placeholder_module(module_name)
280
+ self._name_index[local] = (resolved, original)
281
+ else:
282
+ self._name_index[local] = (module_name, original)
283
+
284
+ def _index_star_import(self, module_name: str, name: str) -> None:
285
+ """Index a star-imported name, attributing stdlib re-exports correctly.
286
+
287
+ If the name is a known tpy/builtins/typing export, bind it from the
288
+ original stdlib module so the parser resolves types correctly (e.g.
289
+ Int32 should always resolve as a tpy type, even when re-exported
290
+ through a user module).
291
+ """
292
+ stdlib = route_stdlib_name(name)
293
+ if stdlib is not None:
294
+ self._name_index[name] = stdlib
295
+ else:
296
+ self._index_import(module_name, name, name)
297
+
298
+ def index_imported_name(
299
+ self, local_name: str, source_module: str, original_name: str,
300
+ ) -> None:
301
+ """Add a `(source_module, original_name)` entry for `local_name`
302
+ if not already present. Lets external callers (compile-time
303
+ star-import expansion in particular) extend the name index
304
+ without touching `_name_index` directly."""
305
+ if local_name not in self._name_index:
306
+ self._name_index[local_name] = (source_module, original_name)
307
+
308
+ def _resolve_star_import(self, module_name: str) -> frozenset[str] | None:
309
+ """Resolve star import exports for an implicit-stdlib module
310
+ (`tpy` / `builtins` / `typing`).
311
+
312
+ Reads the module's `__all__` straight from the corresponding
313
+ `lib/tpy/.../__init__.py`. Non-stdlib star imports never reach
314
+ this method -- they are deferred to compile time via
315
+ `Compiler._expand_star_imports_for_module`.
316
+ """
317
+ assert module_name in _IMPLICIT_MODULES, (
318
+ f"_resolve_star_import called for non-implicit module "
319
+ f"{module_name!r}; user-module star imports are expanded "
320
+ f"at compile time, not parse time."
321
+ )
322
+ if module_name == "tpy":
323
+ return get_tpy_exports()
324
+ if module_name == "builtins":
325
+ return get_builtins_exports()
326
+ if module_name == "typing":
327
+ return get_typing_exports()
328
+ return None
329
+
330
+ def _resolve_relative_to_absolute(self, level: int, partial: str | None) -> str | None:
331
+ """Resolve a relative import to an absolute module name.
332
+
333
+ Pure path computation without public_module_name mapping,
334
+ so the result can be passed to the star import resolver.
335
+ """
336
+ if not self._module_name:
337
+ return None
338
+ parts = self._module_name.split(".")
339
+ package_parts = parts if self._is_package_init else parts[:-1]
340
+ levels_up = level - 1
341
+ if levels_up > len(package_parts):
342
+ return None
343
+ base_parts = package_parts[:len(package_parts) - levels_up]
344
+ if partial:
345
+ return ".".join(base_parts + [partial])
346
+ return ".".join(base_parts)
347
+
348
+ def process_import(self, node: ast.Import, imports: dict, user_module_imports: dict,
349
+ top_level_stmts: list, module_aliases: dict,
350
+ bare_module_imports: set) -> None:
351
+ """Process 'import X' or 'import X as Y' statement."""
352
+ for alias in node.names:
353
+ module_name = alias.name
354
+ local_name = alias.asname or module_name
355
+ user_module_imports[module_name] = node.lineno
356
+ bare_module_imports.add(module_name)
357
+ if module_name not in imports:
358
+ imports[module_name] = set()
359
+ if local_name != module_name:
360
+ module_aliases[module_name] = local_name
361
+ if module_name not in _IMPLICIT_MODULES:
362
+ if not any(isinstance(s, TpyImport) and s.module_name == module_name for s in top_level_stmts):
363
+ import_alias = local_name if local_name != module_name else None
364
+ top_level_stmts.append(TpyImport(module_name=module_name, alias=import_alias, loc=SourceLocation(node.lineno, node.col_offset)))
365
+
366
+ def process_import_from(self, node: ast.ImportFrom, imports: dict, user_module_imports: dict,
367
+ top_level_stmts: list, module_aliases: dict) -> None:
368
+ """Process 'from X import Y' statement."""
369
+ self.imports = imports
370
+ module_name = node.module
371
+ level = node.level
372
+
373
+ # Handle relative imports (level > 0)
374
+ if level > 0:
375
+ key = RelativeImportKey(level=level, line=node.lineno, col=node.col_offset, partial=module_name or "")
376
+ placeholder = key.encode()
377
+
378
+ # Track as user module import
379
+ user_module_imports[placeholder] = node.lineno
380
+
381
+ imports[placeholder] = set()
382
+ for alias in node.names:
383
+ if alias.name == "*":
384
+ # Star imports of (resolved-to-)user modules are
385
+ # expanded at compile time against the source's
386
+ # per-module attribute table -- see
387
+ # `Compiler._expand_star_imports_and_propagate_reexports`.
388
+ # The parser leaves the imports[placeholder] set
389
+ # empty as a deferred-expansion marker.
390
+ self.star_imports.add(placeholder)
391
+ top_level_stmts.append(TpyImport(
392
+ module_name=placeholder, level=level,
393
+ relative_name=module_name,
394
+ loc=SourceLocation(node.lineno, node.col_offset)))
395
+ return
396
+ local_name = alias.asname or alias.name
397
+ imports[placeholder].add((alias.name, local_name))
398
+ self._index_import(placeholder, alias.name, local_name)
399
+
400
+ # Each relative import statement gets its own TpyImport
401
+ top_level_stmts.append(TpyImport(
402
+ module_name=placeholder,
403
+ level=level,
404
+ relative_name=module_name,
405
+ loc=SourceLocation(node.lineno, node.col_offset)
406
+ ))
407
+ return
408
+
409
+ if module_name is None:
410
+ raise ParseError("Invalid import: no module name", node)
411
+
412
+ # Skip __future__ imports -- CPython compatibility, no-op for TurboPython
413
+ if module_name == "__future__":
414
+ return
415
+
416
+ # tpy has special star-import and alias tracking. Cannot collapse
417
+ # into the generic `_IMPLICIT_MODULES` branch below because (a) the
418
+ # `tpy_star_import` flag drives sema's `register_tpy_star_import`
419
+ # (which registers all tpy type aliases), and (b) the name_index
420
+ # entries route directly to `("tpy", name)` rather than the
421
+ # `_index_star_import` stdlib-routing dispatch the generic branch
422
+ # uses for re-exports of stdlib names.
423
+ if module_name == "tpy":
424
+ if any(alias.name == "*" for alias in node.names):
425
+ exports = self._resolve_star_import("tpy")
426
+ if not exports:
427
+ exports = frozenset()
428
+ imports["tpy"] = {(name, name) for name in exports}
429
+ for name in exports:
430
+ self._name_index[name] = ("tpy", name)
431
+ self.tpy_star_import = True
432
+ self.star_imports.add("tpy")
433
+ return
434
+ if "tpy" not in imports:
435
+ imports["tpy"] = set()
436
+ current = imports["tpy"]
437
+ if current is not None:
438
+ for alias in node.names:
439
+ original_name = alias.name
440
+ local_name = alias.asname if alias.asname else alias.name
441
+ current.add((original_name, local_name))
442
+ self._index_import("tpy", original_name, local_name)
443
+ self.tpy_import_aliases[local_name] = original_name
444
+ return
445
+
446
+ # Handle star imports for non-tpy modules. `from tpy import *`
447
+ # is handled above; `builtins` / `typing` keep parser-time
448
+ # resolution because the standalone parser (no compiler
449
+ # context) still needs to see those names. Every other star
450
+ # import (user modules, relative resolved to a non-implicit
451
+ # name) is expanded at compile time against the source
452
+ # module's per-attribute table.
453
+ if any(alias.name == "*" for alias in node.names):
454
+ if module_name in _IMPLICIT_MODULES:
455
+ star_exports = self._resolve_star_import(module_name)
456
+ if star_exports is None:
457
+ raise ParseError(
458
+ f"'from {module_name} import *': could not resolve module exports", node)
459
+ imports[module_name] = {(name, name) for name in star_exports}
460
+ for name in star_exports:
461
+ if name not in self._name_index:
462
+ self._index_star_import(module_name, name)
463
+ else:
464
+ imports[module_name] = set()
465
+ self.star_imports.add(module_name)
466
+ user_module_imports[module_name] = node.lineno
467
+ if module_name not in _IMPLICIT_MODULES:
468
+ if not any(isinstance(s, TpyImport) and s.module_name == module_name for s in top_level_stmts):
469
+ top_level_stmts.append(TpyImport(module_name=module_name, loc=SourceLocation(node.lineno, node.col_offset)))
470
+ return
471
+
472
+ # Track all imported names in the imports dict
473
+ if module_name not in imports:
474
+ imports[module_name] = set()
475
+ current = imports[module_name]
476
+ has_non_keyword = False
477
+ if current is not None:
478
+ for alias in node.names:
479
+ local_name = alias.asname if alias.asname else alias.name
480
+ current.add((alias.name, local_name))
481
+ self._index_import(module_name, alias.name, local_name)
482
+ if not is_parser_keyword(module_name, alias.name):
483
+ has_non_keyword = True
484
+
485
+ # Trigger file resolution for any module with non-keyword names.
486
+ if has_non_keyword or not any(is_parser_keyword(module_name, a.name) for a in node.names):
487
+ user_module_imports[module_name] = node.lineno
488
+ if module_name not in _IMPLICIT_MODULES:
489
+ if not any(isinstance(s, TpyImport) and s.module_name == module_name for s in top_level_stmts):
490
+ top_level_stmts.append(TpyImport(module_name=module_name, loc=SourceLocation(node.lineno, node.col_offset)))