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,277 @@
1
+ /**
2
+ * TurboPython Runtime - UninitHeapStorage
3
+ *
4
+ * Heap-allocated uninitialized storage for T elements.
5
+ * Allocates raw memory for `capacity` elements via ::operator new.
6
+ * Caller is responsible for managing element lifetimes via
7
+ * construct() / destroy().
8
+ *
9
+ * Non-copyable but movable: copy would alias heap memory, move transfers ownership.
10
+ * To grow: allocate new storage, move elements over, destroy old, move-assign.
11
+ */
12
+
13
+ #pragma once
14
+
15
+ #include <cstddef>
16
+ #include <cstdint>
17
+ #include <cstring>
18
+ #include <new>
19
+ #include <span>
20
+ #include <type_traits>
21
+ #include <utility>
22
+
23
+ #include "core.hpp"
24
+
25
+ #ifndef NDEBUG
26
+ #include <vector>
27
+ #endif
28
+
29
+ namespace tpy {
30
+
31
+ template <typename T>
32
+ class UninitHeapStorage {
33
+ public:
34
+ UninitHeapStorage(uint32_t capacity)
35
+ : data_(static_cast<T*>(::operator new(sizeof(T) * capacity, std::align_val_t(alignof(T)))))
36
+ , capacity_(capacity)
37
+ #ifndef NDEBUG
38
+ , alive_(capacity, false)
39
+ #endif
40
+ {}
41
+
42
+ ~UninitHeapStorage() {
43
+ #ifndef NDEBUG
44
+ for (std::size_t i = 0; i < capacity_; ++i) {
45
+ if (alive_[i]) {
46
+ tpy_panic("UninitHeapStorage destroyed with live elements");
47
+ }
48
+ }
49
+ #endif
50
+ if (data_) {
51
+ ::operator delete(data_, std::align_val_t(alignof(T)));
52
+ }
53
+ }
54
+
55
+ // Non-copyable
56
+ UninitHeapStorage(const UninitHeapStorage&) = delete;
57
+ UninitHeapStorage& operator=(const UninitHeapStorage&) = delete;
58
+
59
+ // Movable (transfers ownership, source becomes empty)
60
+ UninitHeapStorage(UninitHeapStorage&& other) noexcept
61
+ : data_(other.data_)
62
+ , capacity_(other.capacity_)
63
+ #ifndef NDEBUG
64
+ , alive_(std::move(other.alive_))
65
+ #endif
66
+ {
67
+ other.data_ = nullptr;
68
+ other.capacity_ = 0;
69
+ }
70
+
71
+ UninitHeapStorage& operator=(UninitHeapStorage&& other) noexcept {
72
+ if (this != &other) {
73
+ #ifndef NDEBUG
74
+ for (std::size_t i = 0; i < capacity_; ++i) {
75
+ if (alive_[i]) {
76
+ tpy_panic("UninitHeapStorage move-assigned with live elements");
77
+ }
78
+ }
79
+ #endif
80
+ if (data_) {
81
+ ::operator delete(data_, std::align_val_t(alignof(T)));
82
+ }
83
+ data_ = other.data_;
84
+ capacity_ = other.capacity_;
85
+ #ifndef NDEBUG
86
+ alive_ = std::move(other.alive_);
87
+ #endif
88
+ other.data_ = nullptr;
89
+ other.capacity_ = 0;
90
+ }
91
+ return *this;
92
+ }
93
+
94
+ void init(uint32_t i, T&& value) {
95
+ #ifndef NDEBUG
96
+ if (i >= capacity_) {
97
+ tpy_panic("UninitHeapStorage::init index out of bounds");
98
+ }
99
+ if (alive_[i]) {
100
+ tpy_panic("UninitHeapStorage::init on already-alive slot");
101
+ }
102
+ alive_[i] = true;
103
+ #endif
104
+ ::new (static_cast<void*>(&data_[i])) T(std::move(value));
105
+ }
106
+
107
+ void init(uint32_t i, const T& value) {
108
+ #ifndef NDEBUG
109
+ if (i >= capacity_) {
110
+ tpy_panic("UninitHeapStorage::init index out of bounds");
111
+ }
112
+ if (alive_[i]) {
113
+ tpy_panic("UninitHeapStorage::init on already-alive slot");
114
+ }
115
+ alive_[i] = true;
116
+ #endif
117
+ ::new (static_cast<void*>(&data_[i])) T(value);
118
+ }
119
+
120
+ void init0(T&& value) { init(0, std::move(value)); }
121
+ void init0(const T& value) { init(0, value); }
122
+
123
+ void drop(uint32_t i) {
124
+ #ifndef NDEBUG
125
+ if (i >= capacity_) {
126
+ tpy_panic("UninitHeapStorage::drop index out of bounds");
127
+ }
128
+ if (!alive_[i]) {
129
+ tpy_panic("UninitHeapStorage::drop on dead slot");
130
+ }
131
+ alive_[i] = false;
132
+ #endif
133
+ data_[i].~T();
134
+ }
135
+
136
+ void drop0() { drop(0); }
137
+
138
+ T& load(uint32_t i) {
139
+ #ifndef NDEBUG
140
+ if (i >= capacity_) {
141
+ tpy_panic("UninitHeapStorage::load index out of bounds");
142
+ }
143
+ if (!alive_[i]) {
144
+ tpy_panic("UninitHeapStorage::load on dead slot");
145
+ }
146
+ #endif
147
+ return data_[i];
148
+ }
149
+
150
+ const T& load(uint32_t i) const {
151
+ #ifndef NDEBUG
152
+ if (i >= capacity_) {
153
+ tpy_panic("UninitHeapStorage::load index out of bounds");
154
+ }
155
+ if (!alive_[i]) {
156
+ tpy_panic("UninitHeapStorage::load on dead slot");
157
+ }
158
+ #endif
159
+ return data_[i];
160
+ }
161
+
162
+ T& load0() { return load(0); }
163
+ const T& load0() const { return load(0); }
164
+
165
+ T take(uint32_t i) {
166
+ #ifndef NDEBUG
167
+ if (i >= capacity_) {
168
+ tpy_panic("UninitHeapStorage::take index out of bounds");
169
+ }
170
+ if (!alive_[i]) {
171
+ tpy_panic("UninitHeapStorage::take on dead slot");
172
+ }
173
+ alive_[i] = false;
174
+ #endif
175
+ T result = std::move(data_[i]);
176
+ data_[i].~T();
177
+ return result;
178
+ }
179
+
180
+ T take0() { return take(0); }
181
+
182
+ T* ptr() { return data_; }
183
+ const T* ptr() const { return data_; }
184
+
185
+ uint32_t capacity() const { return capacity_; }
186
+
187
+ void init_from_span(uint32_t start, std::span<const T> src) {
188
+ #ifndef NDEBUG
189
+ if (start + src.size() > capacity_) {
190
+ tpy_panic("UninitHeapStorage::init_from_span: span exceeds capacity");
191
+ }
192
+ for (std::size_t i = 0; i < src.size(); ++i) {
193
+ if (alive_[start + i]) {
194
+ tpy_panic("UninitHeapStorage::init_from_span on already-alive slot");
195
+ }
196
+ alive_[start + i] = true;
197
+ }
198
+ #endif
199
+ if constexpr (std::is_trivially_copyable_v<T>) {
200
+ std::memcpy(static_cast<void*>(&data_[start]), src.data(), src.size() * sizeof(T));
201
+ } else {
202
+ for (std::size_t i = 0; i < src.size(); ++i) {
203
+ ::new (static_cast<void*>(&data_[start + i])) T(src[i]);
204
+ }
205
+ }
206
+ }
207
+
208
+ void drop_n(uint32_t start, uint32_t count) {
209
+ #ifndef NDEBUG
210
+ for (uint32_t i = 0; i < count; ++i) {
211
+ uint32_t idx = start + i;
212
+ if (idx >= capacity_) {
213
+ tpy_panic("UninitHeapStorage::drop_n index out of bounds");
214
+ }
215
+ if (!alive_[idx]) {
216
+ tpy_panic("UninitHeapStorage::drop_n on dead slot");
217
+ }
218
+ alive_[idx] = false;
219
+ }
220
+ #endif
221
+ if constexpr (!std::is_trivially_destructible_v<T>) {
222
+ for (uint32_t i = 0; i < count; ++i) {
223
+ data_[start + i].~T();
224
+ }
225
+ }
226
+ }
227
+
228
+ void shift(uint32_t src, uint32_t dst, uint32_t count) {
229
+ if (count == 0 || src == dst) return;
230
+ #ifndef NDEBUG
231
+ for (uint32_t i = 0; i < count; ++i) {
232
+ if (src + i >= capacity_ || dst + i >= capacity_) {
233
+ tpy_panic("UninitHeapStorage::shift index out of bounds");
234
+ }
235
+ if (!alive_[src + i]) {
236
+ tpy_panic("UninitHeapStorage::shift on dead source slot");
237
+ }
238
+ }
239
+ for (uint32_t i = 0; i < count; ++i) {
240
+ alive_[src + i] = false;
241
+ }
242
+ for (uint32_t i = 0; i < count; ++i) {
243
+ alive_[dst + i] = true;
244
+ }
245
+ #endif
246
+ if constexpr (std::is_trivially_copyable_v<T>) {
247
+ std::memmove(static_cast<void*>(&data_[dst]),
248
+ static_cast<const void*>(&data_[src]),
249
+ static_cast<std::size_t>(count) * sizeof(T));
250
+ } else if (dst < src) {
251
+ for (uint32_t i = 0; i < count; ++i) {
252
+ ::new (static_cast<void*>(&data_[dst + i]))
253
+ T(std::move(data_[src + i]));
254
+ data_[src + i].~T();
255
+ }
256
+ } else {
257
+ for (uint32_t i = count; i > 0; --i) {
258
+ uint32_t idx = i - 1;
259
+ ::new (static_cast<void*>(&data_[dst + idx]))
260
+ T(std::move(data_[src + idx]));
261
+ data_[src + idx].~T();
262
+ }
263
+ }
264
+ }
265
+
266
+ // TODO: emplace(i, args...) for perfect-forwarding construction
267
+
268
+ private:
269
+ T* data_;
270
+ uint32_t capacity_;
271
+
272
+ #ifndef NDEBUG
273
+ std::vector<bool> alive_;
274
+ #endif
275
+ };
276
+
277
+ } // namespace tpy
@@ -0,0 +1,174 @@
1
+ /**
2
+ * TurboPython Runtime - varargs<T>
3
+ *
4
+ * Span-like view for *args parameters.
5
+ *
6
+ * Value types (is_value_type_v<T>): thin wrapper around contiguous T storage.
7
+ * No indirection, no branches -- equivalent to std::span<T>.
8
+ *
9
+ * Non-value types: dual-mode view.
10
+ * Direct mode: contiguous T storage (*list unpacking into vector/array).
11
+ * Indirect mode: T* pointer array (individual args packed by address).
12
+ * operator[] returns T& in both modes.
13
+ */
14
+
15
+ #pragma once
16
+
17
+ #include "type_traits.hpp"
18
+
19
+ #include <array>
20
+ #include <cstdint>
21
+ #include <span>
22
+
23
+ namespace tpy {
24
+
25
+ // Primary template: non-value types (dual-mode)
26
+ template<typename T, bool IsValue = is_value_type_v<T>>
27
+ struct varargs {
28
+ T* direct_ = nullptr;
29
+ T* const* indirect_ = nullptr;
30
+ int32_t size_ = 0;
31
+
32
+ varargs() = default;
33
+
34
+ // Direct mode: contiguous T storage (*list unpacking)
35
+ varargs(std::span<T> s) : direct_(s.data()), size_(static_cast<int32_t>(s.size())) {}
36
+
37
+ template<size_t N>
38
+ varargs(std::array<T, N>& arr) : direct_(arr.data()), size_(static_cast<int32_t>(N)) {}
39
+
40
+ // Indirect mode: pointer array (individual args)
41
+ template<size_t N>
42
+ varargs(std::array<T*, N>& arr) : indirect_(arr.data()), size_(static_cast<int32_t>(N)) {}
43
+
44
+ // Readonly view of a mutable varargs<U> -- forwarding `*xs` where `xs` is a
45
+ // mutable `*args` param into a `readonly[...]` vararg. Present only when T
46
+ // is const. The pointer-array conversion (`U* const*` -> `const U* const*`,
47
+ // i.e. `T* const*`) is a plain implicit qualification conversion -- legal
48
+ // because the enclosing pointer level is already const -- not a reinterpret.
49
+ template<typename U = T, std::enable_if_t<std::is_const_v<U>, int> = 0>
50
+ varargs(const varargs<std::remove_const_t<U>>& o)
51
+ : direct_(o.direct_),
52
+ indirect_(o.indirect_),
53
+ size_(o.size_) {}
54
+
55
+ T& operator[](int32_t i) const {
56
+ return indirect_ ? *indirect_[i] : direct_[i];
57
+ }
58
+
59
+ int32_t size() const { return size_; }
60
+ bool empty() const { return size_ == 0; }
61
+
62
+ // Python-style slice preserving direct-vs-indirect mode. Returns another
63
+ // varargs of the same instantiation with adjusted pointers + size -- the
64
+ // only correct shape, since indirect-mode storage (`T* const*`) cannot be
65
+ // exposed as `std::span<T>`. Indices follow Python clamp semantics.
66
+ varargs slice(int32_t start, int32_t stop) const {
67
+ int32_t i = start;
68
+ int32_t j = stop;
69
+ if (i < 0) i += size_;
70
+ if (j < 0) j += size_;
71
+ if (i < 0) i = 0;
72
+ if (j < 0) j = 0;
73
+ if (i > size_) i = size_;
74
+ if (j > size_) j = size_;
75
+ varargs r;
76
+ if (i >= j) return r;
77
+ r.size_ = j - i;
78
+ if (direct_) r.direct_ = direct_ + i;
79
+ if (indirect_) r.indirect_ = indirect_ + i;
80
+ return r;
81
+ }
82
+
83
+ struct iterator {
84
+ T* direct_;
85
+ T* const* indirect_;
86
+
87
+ T& operator*() const { return indirect_ ? **indirect_ : *direct_; }
88
+
89
+ iterator& operator++() {
90
+ if (indirect_) ++indirect_; else ++direct_;
91
+ return *this;
92
+ }
93
+
94
+ bool operator==(const iterator& o) const {
95
+ return indirect_ ? indirect_ == o.indirect_ : direct_ == o.direct_;
96
+ }
97
+ bool operator!=(const iterator& o) const { return !(*this == o); }
98
+ };
99
+
100
+ iterator begin() const { return {direct_, indirect_}; }
101
+ iterator end() const {
102
+ return {direct_ ? direct_ + size_ : nullptr,
103
+ indirect_ ? indirect_ + size_ : nullptr};
104
+ }
105
+ };
106
+
107
+ // Value type specialization: direct only, no indirection overhead
108
+ template<typename T>
109
+ struct varargs<T, true> {
110
+ T* data_ = nullptr;
111
+ int32_t size_ = 0;
112
+
113
+ varargs() = default;
114
+
115
+ varargs(std::span<T> s) : data_(s.data()), size_(static_cast<int32_t>(s.size())) {}
116
+
117
+ template<size_t N>
118
+ varargs(std::array<T, N>& arr) : data_(arr.data()), size_(static_cast<int32_t>(N)) {}
119
+
120
+ // Readonly view of a mutable value-type varargs<U> (forwarding into a
121
+ // `readonly[...]` value-type vararg). Present only when T is const.
122
+ template<typename U = T, std::enable_if_t<std::is_const_v<U>, int> = 0>
123
+ varargs(const varargs<std::remove_const_t<U>>& o)
124
+ : data_(o.data_), size_(o.size_) {}
125
+
126
+ T& operator[](int32_t i) const { return data_[i]; }
127
+ int32_t size() const { return size_; }
128
+ bool empty() const { return size_ == 0; }
129
+ T* data() const { return data_; }
130
+
131
+ using iterator = T*;
132
+ T* begin() const { return data_; }
133
+ T* end() const { return data_ + size_; }
134
+ };
135
+
136
+ template<typename T, bool V>
137
+ int32_t __len__(const varargs<T, V>& v) { return v.size(); }
138
+
139
+ template<typename T, bool V>
140
+ T& __getitem__(const varargs<T, V>& v, int32_t i) { return v[i]; }
141
+
142
+ } // namespace tpy
143
+
144
+ #include "container_ops.hpp"
145
+
146
+ namespace tpy {
147
+
148
+ // list_slice on a non-value varargs returns another varargs (preserving
149
+ // direct-vs-indirect mode), not std::span<T> -- the generic Container
150
+ // list_slice in container_ops.hpp would call `c.data()` which non-value
151
+ // varargs intentionally doesn't expose (indirect storage is `T* const*`,
152
+ // not contiguous T). The value-type varargs path stays on the generic
153
+ // template via its own `data()` (defined in the value-type specialization).
154
+ template<typename T>
155
+ varargs<T, false> list_slice(varargs<T, false>& c, int32_t start, int32_t stop) {
156
+ return c.slice(start, stop);
157
+ }
158
+
159
+ template<typename T>
160
+ varargs<T, false> list_slice(const varargs<T, false>& c, int32_t start, int32_t stop) {
161
+ return c.slice(start, stop);
162
+ }
163
+
164
+ template<typename T>
165
+ varargs<T, false> list_slice(varargs<T, false>& c, BasicSlice sl) {
166
+ return c.slice(sl.start.value_or(0), sl.stop.value_or(SLICE_END));
167
+ }
168
+
169
+ template<typename T>
170
+ varargs<T, false> list_slice(const varargs<T, false>& c, BasicSlice sl) {
171
+ return c.slice(sl.start.value_or(0), sl.stop.value_or(SLICE_END));
172
+ }
173
+
174
+ } // namespace tpy
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Pointer-variant utilities for non-value union types.
3
+ *
4
+ * Non-value unions (e.g. Dog | Cat where members are records) use a two-layer
5
+ * representation:
6
+ * - Storage: std::variant<Dog, Cat> (owns values)
7
+ * - Reference: std::variant<Dog*, Cat*> (borrows values)
8
+ *
9
+ * to_ptr_variant() converts a storage variant reference into a pointer variant.
10
+ * std::monostate members (representing None in nullable unions) pass through.
11
+ */
12
+
13
+ #pragma once
14
+
15
+ #include <variant>
16
+ #include <type_traits>
17
+
18
+ namespace tpy {
19
+
20
+ namespace detail {
21
+
22
+ // Map T -> T*, but monostate -> monostate
23
+ template<typename T>
24
+ struct ptr_of { using type = T*; };
25
+
26
+ template<>
27
+ struct ptr_of<std::monostate> { using type = std::monostate; };
28
+
29
+ // Map T -> const T*, but monostate -> monostate
30
+ template<typename T>
31
+ struct const_ptr_of { using type = const T*; };
32
+
33
+ template<>
34
+ struct const_ptr_of<std::monostate> { using type = std::monostate; };
35
+
36
+ // Try to convert alternative I: if active, emplace pointer into result.
37
+ // Returns true (short-circuits fold) on match.
38
+ template<std::size_t I, typename Result, typename Variant>
39
+ bool try_emplace_ptr(Result& r, Variant& v) {
40
+ if (v.index() != I) return false;
41
+ using Alt = std::variant_alternative_t<I, std::remove_cvref_t<Variant>>;
42
+ if constexpr (std::is_same_v<Alt, std::monostate>) {
43
+ r.template emplace<I>(std::monostate{});
44
+ } else {
45
+ r.template emplace<I>(&std::get<I>(v));
46
+ }
47
+ return true;
48
+ }
49
+
50
+ template<typename Result, typename Variant, std::size_t... Is>
51
+ Result to_ptr_variant_impl(Variant& v, std::index_sequence<Is...>) {
52
+ Result r;
53
+ (try_emplace_ptr<Is>(r, v) || ...);
54
+ return r;
55
+ }
56
+
57
+ } // namespace detail
58
+
59
+ // Convert std::variant<Ts...>& -> std::variant<Ts*...> (monostate passthrough)
60
+ template<typename... Ts>
61
+ std::variant<typename detail::ptr_of<Ts>::type...>
62
+ to_ptr_variant(std::variant<Ts...>& v) {
63
+ using Result = std::variant<typename detail::ptr_of<Ts>::type...>;
64
+ return detail::to_ptr_variant_impl<Result>(v, std::index_sequence_for<Ts...>{});
65
+ }
66
+
67
+ // Convert const std::variant<Ts...>& -> std::variant<const Ts*...> (monostate passthrough)
68
+ template<typename... Ts>
69
+ std::variant<typename detail::const_ptr_of<Ts>::type...>
70
+ to_const_ptr_variant(const std::variant<Ts...>& v) {
71
+ using Result = std::variant<typename detail::const_ptr_of<Ts>::type...>;
72
+ return detail::to_ptr_variant_impl<Result>(v, std::index_sequence_for<Ts...>{});
73
+ }
74
+
75
+ // Convert mutable pointer variant to const pointer variant:
76
+ // std::variant<T*...> -> std::variant<const T*...>
77
+ // Handles monostate (nullable unions) by passing it through.
78
+ namespace detail {
79
+ template<typename Result>
80
+ struct to_const_visitor {
81
+ template<typename T>
82
+ Result operator()(T* p) const { return static_cast<const T*>(p); }
83
+ Result operator()(std::monostate m) const { return m; }
84
+ };
85
+ } // namespace detail
86
+
87
+ template<typename Result, typename... Alts>
88
+ Result ptr_variant_to_const(const std::variant<Alts...>& v) {
89
+ return std::visit(detail::to_const_visitor<Result>{}, v);
90
+ }
91
+
92
+ // Reverse: convert pointer variant to value variant (copies active member).
93
+ // Used when storing into fields/containers that own their values.
94
+ // ValueVariant = target type (e.g. std::variant<Dog, Cat>)
95
+ // PtrVariant = source type (e.g. std::variant<Dog*, Cat*>)
96
+ namespace detail {
97
+
98
+ // Visitor that converts each pointer alternative to its value type.
99
+ // Constructs the Result variant directly, avoiding default-construction
100
+ // (which would require the first alternative to be default-constructible).
101
+ template<typename Result>
102
+ struct deref_visitor {
103
+ template<typename T>
104
+ Result operator()(T* p) const { return Result{*p}; }
105
+
106
+ Result operator()(std::monostate) const { return Result{std::monostate{}}; }
107
+ };
108
+
109
+ } // namespace detail
110
+
111
+ // Convert pointer variant to value variant: to_value_variant<std::variant<Dog,Cat>>(pv)
112
+ // Caller must specify the target value-variant type explicitly.
113
+ template<typename ValueVariant, typename... PtrAlts>
114
+ ValueVariant to_value_variant(const std::variant<PtrAlts...>& v) {
115
+ return std::visit(detail::deref_visitor<ValueVariant>{}, v);
116
+ }
117
+
118
+ } // namespace tpy
@@ -0,0 +1,104 @@
1
+ // Out-of-line helpers for TPy's `socket` stdlib module.
2
+ //
3
+ // Exists because:
4
+ // * struct addrinfo's field order is not portable across Linux and
5
+ // BSD/macOS (ai_addr and ai_canonname are swapped). Declaring it at
6
+ // @native(binding="C") level would only work on one platform family.
7
+ // tpy_resolve_ipv4 walks the list here and hands back a flat 4-byte
8
+ // IPv4 address.
9
+ // * `errno` and gai_strerror need `<errno.h>` / `<netdb.h>`, whose
10
+ // macros we keep out of every TPy-generated TU by hiding them
11
+ // behind these helpers.
12
+ //
13
+ // Everything else in the socket module binds libc directly via @native
14
+ // against the forward decls in runtime/cpp/include/tpy/stdlib/socket_h.hpp.
15
+ //
16
+ // We intentionally do NOT `#include` socket_h.hpp here: its libc forward
17
+ // decls (using `void*` sockaddr pointers, no `noexcept`) conflict with
18
+ // the real libc decls the system headers bring in. ABI consistency for
19
+ // the three `tpy_*` symbols is maintained manually -- trivial with three
20
+ // short signatures, and the only alternative is duplicating two parallel
21
+ // header variants.
22
+
23
+ #include <cerrno>
24
+ #include <cstdint>
25
+ #include <cstring>
26
+ #include <string>
27
+
28
+ #include <sys/socket.h>
29
+ #include <netinet/in.h>
30
+ #include <netdb.h>
31
+
32
+ namespace {
33
+
34
+ // Thread-local so two threads running concurrent resolves don't stomp
35
+ // each other's error messages. The buffer is a fixed size because
36
+ // gai_strerror / strerror messages are short; we copy to decouple the
37
+ // returned pointer from libc's internal buffer reuse.
38
+ thread_local char g_resolve_err[256] = {0};
39
+
40
+ void set_resolve_error(const char* msg) {
41
+ if (msg == nullptr) {
42
+ g_resolve_err[0] = '\0';
43
+ return;
44
+ }
45
+ std::strncpy(g_resolve_err, msg, sizeof(g_resolve_err) - 1);
46
+ g_resolve_err[sizeof(g_resolve_err) - 1] = '\0';
47
+ }
48
+
49
+ } // namespace
50
+
51
+ extern "C" {
52
+
53
+ int tpy_resolve_ipv4(const std::uint8_t* host, std::uint64_t host_len,
54
+ std::uint8_t out[4]) {
55
+ // getaddrinfo requires a null-terminated C string. TPy `str` is
56
+ // std::string_view -- not guaranteed terminated -- so copy into a
57
+ // local std::string. reinterpret_cast<const char*> because TPy
58
+ // binding types string bytes as uint8_t* but std::string takes char*;
59
+ // the underlying bytes are identical.
60
+ std::string host_s(reinterpret_cast<const char*>(host), host_len);
61
+
62
+ addrinfo hints{};
63
+ hints.ai_family = AF_INET;
64
+ hints.ai_socktype = SOCK_STREAM;
65
+
66
+ addrinfo* res = nullptr;
67
+ int rc = getaddrinfo(host_s.c_str(), nullptr, &hints, &res);
68
+ if (rc != 0) {
69
+ set_resolve_error(gai_strerror(rc));
70
+ return -1;
71
+ }
72
+ if (res == nullptr) {
73
+ // getaddrinfo returned 0 but no results -- shouldn't happen,
74
+ // but guard anyway.
75
+ set_resolve_error("no addresses returned");
76
+ return -1;
77
+ }
78
+ if (res->ai_addr == nullptr) {
79
+ // Defensive: with AF_INET + SOCK_STREAM hints every returned
80
+ // entry should carry a sockaddr_in in ai_addr. A broken or
81
+ // custom resolver library could in theory break this
82
+ // invariant; fail cleanly rather than dereference null.
83
+ freeaddrinfo(res);
84
+ set_resolve_error("getaddrinfo returned entry with null ai_addr");
85
+ return -1;
86
+ }
87
+ // Copy the first A-record's 4 bytes. `sin_addr.s_addr` is already in
88
+ // network byte order, which is what the caller wants for sockaddr_in.
89
+ auto* sin = reinterpret_cast<sockaddr_in*>(res->ai_addr);
90
+ std::memcpy(out, &sin->sin_addr, 4);
91
+ freeaddrinfo(res);
92
+ set_resolve_error(nullptr);
93
+ return 0;
94
+ }
95
+
96
+ int tpy_errno() {
97
+ return errno;
98
+ }
99
+
100
+ const char* tpy_last_resolve_error() {
101
+ return g_resolve_err;
102
+ }
103
+
104
+ } // extern "C"