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,750 @@
1
+ /**
2
+ * TurboPython Runtime - Dunder Free Functions
3
+ *
4
+ * Protocol free functions (__len__, __getitem__, __setitem__) that bridge
5
+ * Python dunder methods to C++ types. Overloads handle index normalization
6
+ * and bounds checking (Python semantics). Default templates forward to the
7
+ * user type's own dunder method.
8
+ */
9
+
10
+ #pragma once
11
+
12
+ #include <array>
13
+ #include <cstddef>
14
+ #include <cstdint>
15
+ #include <cstring>
16
+ #include <expected>
17
+ #include <format>
18
+ #include <functional>
19
+ #include <ranges>
20
+ #include <span>
21
+ #include <sstream>
22
+ #include <string>
23
+ #include <string_view>
24
+ #include <tuple>
25
+ #include <type_traits>
26
+ #include <vector>
27
+
28
+ #include "bigint.hpp"
29
+ #include "enum.hpp"
30
+ #include "format.hpp"
31
+ #include "container_ops.hpp"
32
+ #include "next_iter.hpp"
33
+ #include "ordered_map.hpp"
34
+ #include "span_iter.hpp"
35
+
36
+ namespace tpy {
37
+
38
+ // =============================================
39
+ // tpy::__len__
40
+ // =============================================
41
+
42
+ // Overload: std::vector (most specific, checked first)
43
+ template<typename T>
44
+ int32_t __len__(const std::vector<T>& x) {
45
+ return static_cast<int32_t>(x.size());
46
+ }
47
+
48
+ // Overload: std::array
49
+ template<typename T, std::size_t N>
50
+ int32_t __len__(const std::array<T, N>& x) {
51
+ return static_cast<int32_t>(x.size());
52
+ }
53
+
54
+ // Overload: std::span (const and non-const)
55
+ template<typename T>
56
+ int32_t __len__(std::span<const T> x) {
57
+ return static_cast<int32_t>(x.size());
58
+ }
59
+
60
+ template<typename T>
61
+ int32_t __len__(std::span<T> x) {
62
+ return static_cast<int32_t>(x.size());
63
+ }
64
+
65
+ // Overload: std::string
66
+ inline int32_t __len__(const std::string& x) {
67
+ return static_cast<int32_t>(x.size());
68
+ }
69
+
70
+ // Overload: std::string_view
71
+ inline int32_t __len__(std::string_view x) {
72
+ return static_cast<int32_t>(x.size());
73
+ }
74
+
75
+ // Overload: const char* (string literals)
76
+ inline int32_t __len__(const char* x) {
77
+ return static_cast<int32_t>(std::string_view(x).size());
78
+ }
79
+
80
+ // Overload: char (Char type -- always length 1)
81
+ inline int32_t __len__(char) {
82
+ return 1;
83
+ }
84
+
85
+ // Overload: ordered_map (dict)
86
+ template<typename K, typename V>
87
+ int32_t __len__(const ordered_map<K, V>& x) {
88
+ return x.size();
89
+ }
90
+
91
+ // Default template: user types that define __len__() method
92
+ // This is checked last due to the requires clause
93
+ template<typename T>
94
+ requires requires(const T& t) { { t.__len__() } -> std::convertible_to<int32_t>; }
95
+ int32_t __len__(const T& x) {
96
+ return x.__len__();
97
+ }
98
+
99
+ // User types returning BigInt from __len__()
100
+ template<typename T>
101
+ requires (requires(const T& t) { { t.__len__() } -> std::same_as<BigInt>; }
102
+ && !requires(const T& t) { { t.__len__() } -> std::convertible_to<int32_t>; })
103
+ int32_t __len__(const T& x) {
104
+ return x.__len__().template to_fixed_check<int32_t>();
105
+ }
106
+
107
+ // =============================================
108
+ // tpy::__getitem__
109
+ // =============================================
110
+
111
+ // Overload: std::vector
112
+ template<typename T>
113
+ decltype(auto) __getitem__(const std::vector<T>& x, int32_t i) {
114
+ auto idx = normalize_index(x, i, "list index out of range");
115
+ return x[idx];
116
+ }
117
+
118
+ template<typename T>
119
+ decltype(auto) __getitem__(std::vector<T>& x, int32_t i) {
120
+ auto idx = normalize_index(x, i, "list index out of range");
121
+ return x[idx];
122
+ }
123
+
124
+ // Overload: std::array
125
+ template<typename T, std::size_t N>
126
+ decltype(auto) __getitem__(const std::array<T, N>& x, int32_t i) {
127
+ auto idx = normalize_index(x, i, "array index out of range");
128
+ return x[idx];
129
+ }
130
+
131
+ template<typename T, std::size_t N>
132
+ decltype(auto) __getitem__(std::array<T, N>& x, int32_t i) {
133
+ auto idx = normalize_index(x, i, "array index out of range");
134
+ return x[idx];
135
+ }
136
+
137
+ // Overload: std::span (const)
138
+ template<typename T>
139
+ decltype(auto) __getitem__(std::span<const T> x, int32_t i) {
140
+ auto idx = normalize_index(x, i, "span index out of range");
141
+ return x[idx];
142
+ }
143
+
144
+ // Overload: std::span (mutable)
145
+ template<typename T>
146
+ T& __getitem__(std::span<T> x, int32_t i) {
147
+ auto idx = normalize_index(x, i, "span index out of range");
148
+ return x[idx];
149
+ }
150
+
151
+ // Overload: std::string
152
+ inline char __getitem__(const std::string& x, int32_t i) {
153
+ auto idx = normalize_index(x, i, "string index out of range");
154
+ return x[idx];
155
+ }
156
+
157
+ // Overload: std::string_view
158
+ inline char __getitem__(std::string_view x, int32_t i) {
159
+ auto idx = normalize_index(x, i, "string index out of range");
160
+ return x[idx];
161
+ }
162
+
163
+ // Overload: ordered_map (dict) -- key can be any compatible type
164
+ template<typename K, typename V, typename KeyArg>
165
+ const V& __getitem__(const ordered_map<K, V>& m, const KeyArg& key) {
166
+ auto it = m.find(K(key));
167
+ if (it == m.items_end()) raise_key_error("KeyError");
168
+ return (*it).second;
169
+ }
170
+
171
+ template<typename K, typename V, typename KeyArg>
172
+ V& __getitem__(ordered_map<K, V>& m, const KeyArg& key) {
173
+ auto it = m.find(K(key));
174
+ if (it == m.items_end()) raise_key_error("KeyError");
175
+ return (*it).second;
176
+ }
177
+
178
+ // Default template: user types that define __getitem__() method
179
+ template<typename T>
180
+ requires requires(const T& t, int32_t i) { t.__getitem__(i); }
181
+ decltype(auto) __getitem__(const T& x, int32_t i) {
182
+ return x.__getitem__(i);
183
+ }
184
+
185
+ template<typename T>
186
+ requires requires(T& t, int32_t i) { t.__getitem__(i); }
187
+ decltype(auto) __getitem__(T& x, int32_t i) {
188
+ return x.__getitem__(i);
189
+ }
190
+
191
+ // =============================================
192
+ // tpy::__setitem__
193
+ // =============================================
194
+
195
+ // Overload: std::vector
196
+ template<typename T, typename V>
197
+ void __setitem__(std::vector<T>& x, int32_t i, V&& v) {
198
+ auto idx = normalize_index(x, i, "list assignment index out of range");
199
+ x[idx] = std::forward<V>(v);
200
+ }
201
+
202
+ // Overload: std::array
203
+ template<typename T, std::size_t N, typename V>
204
+ void __setitem__(std::array<T, N>& x, int32_t i, V&& v) {
205
+ auto idx = normalize_index(x, i, "array index out of range");
206
+ x[idx] = std::forward<V>(v);
207
+ }
208
+
209
+ // Overload: std::span (mutable)
210
+ template<typename T, typename V>
211
+ void __setitem__(std::span<T> x, int32_t i, V&& v) {
212
+ auto idx = normalize_index(x, i, "span index out of range");
213
+ x[idx] = std::forward<V>(v);
214
+ }
215
+
216
+ // Overload: ordered_map (dict)
217
+ template<typename K, typename V, typename KeyArg, typename ValArg>
218
+ void __setitem__(ordered_map<K, V>& m, const KeyArg& key, ValArg&& value) {
219
+ // K(key) avoids double-conversion (find takes const K&); value is
220
+ // forwarded raw into insert_or_assign's universal-ref VV.
221
+ m.insert_or_assign(K(key), std::forward<ValArg>(value));
222
+ }
223
+
224
+ // Default template: user types that define __setitem__() method
225
+ template<typename T, typename V>
226
+ requires requires(T& t, int32_t i, V&& val) { t.__setitem__(i, std::forward<V>(val)); }
227
+ void __setitem__(T& x, int32_t i, V&& v) {
228
+ x.__setitem__(i, std::forward<V>(v));
229
+ }
230
+
231
+ // =============================================
232
+ // tpy::__delitem__
233
+ // =============================================
234
+
235
+ // Overload: std::vector (list)
236
+ template<typename T>
237
+ void __delitem__(std::vector<T>& x, int32_t i) {
238
+ auto idx = normalize_index(x, i, "list assignment index out of range");
239
+ x.erase(x.begin() + static_cast<std::ptrdiff_t>(idx));
240
+ }
241
+
242
+ // Overload: ordered_map (dict) -- throws KeyError on missing key
243
+ template<typename K, typename V, typename KeyArg>
244
+ void __delitem__(ordered_map<K, V>& m, const KeyArg& key) {
245
+ if (!m.erase(K(key))) {
246
+ raise_key_error("KeyError");
247
+ }
248
+ }
249
+
250
+ // Default template: user types that define __delitem__() method
251
+ template<typename T>
252
+ requires requires(T& t, int32_t i) { t.__delitem__(i); }
253
+ void __delitem__(T& x, int32_t i) {
254
+ x.__delitem__(i);
255
+ }
256
+
257
+ // =============================================
258
+ // tpy::__bool__
259
+ // =============================================
260
+
261
+ // Overload: ordered_map (dict)
262
+ template<typename K, typename V>
263
+ bool __bool__(const ordered_map<K, V>& m) {
264
+ return !m.empty();
265
+ }
266
+
267
+ // Default template: user types that define __bool__() method
268
+ template<typename T>
269
+ requires requires(const T& t) { { t.__bool__() } -> std::convertible_to<bool>; }
270
+ bool __bool__(const T& x) {
271
+ return x.__bool__();
272
+ }
273
+
274
+ // =============================================
275
+ // tpy::__str__
276
+ // =============================================
277
+
278
+ // Builtin type overloads (needed for generic T contexts)
279
+ inline std::string __str__(bool x) { return x ? "True" : "False"; }
280
+ inline std::string __str__(std::nullptr_t) { return "None"; }
281
+ inline std::string __str__(std::monostate) { return "None"; }
282
+ inline std::string __str__(char x) { return std::string(1, x); }
283
+ inline std::string __str__(int8_t x) { return std::to_string(x); }
284
+ inline std::string __str__(int16_t x) { return std::to_string(x); }
285
+ inline std::string __str__(int32_t x) { return std::to_string(x); }
286
+ inline std::string __str__(int64_t x) { return std::to_string(x); }
287
+ inline std::string __str__(uint8_t x) { return std::to_string(x); }
288
+ inline std::string __str__(uint16_t x) { return std::to_string(x); }
289
+ inline std::string __str__(uint32_t x) { return std::to_string(x); }
290
+ inline std::string __str__(uint64_t x) { return std::to_string(x); }
291
+ inline std::string __str__(double x) { return format_float(x); }
292
+ inline std::string __str__(float x) { return format_float(static_cast<double>(x)); }
293
+ inline std::string __str__(const std::string& x) { return x; }
294
+ inline std::string __str__(std::string_view x) { return std::string(x); }
295
+ inline std::string __str__(const BigInt& x) { return x.to_string(); }
296
+
297
+ // Default template: user types that define __str__() method
298
+ template<typename T>
299
+ requires requires(const T& t) { t.__str__(); }
300
+ auto __str__(const T& x) {
301
+ return x.__str__();
302
+ }
303
+
304
+ // Fallback: types with __repr__ but no __str__ (matches Python behavior)
305
+ template<typename T>
306
+ requires (!requires(const T& t) { t.__str__(); })
307
+ && requires(const T& t) { t.__repr__(); }
308
+ auto __str__(const T& x) {
309
+ return x.__repr__();
310
+ }
311
+
312
+ // Fallback for formattable types without __str__/__repr__ (e.g. int, double).
313
+ template<typename T>
314
+ requires (!requires(const T& t) { t.__str__(); })
315
+ && (!requires(const T& t) { t.__repr__(); })
316
+ && std::formattable<T, char>
317
+ auto __str__(const T& x) {
318
+ return std::format("{}", x);
319
+ }
320
+
321
+ // Enum str: same shape as enum __repr__ above. Python prints str(e) and
322
+ // repr(e) identically for enums ("TypeName.MEMBER"), so delegate.
323
+ template<typename T>
324
+ requires std::is_enum_v<T>
325
+ && requires(T x) { ::tpy::EnumUtil<T>::name(x); }
326
+ inline std::string __str__(T x) {
327
+ return ::tpy::detail::enum_repr_string(x);
328
+ }
329
+
330
+ // Fallback for types with operator<< but no __str__/__repr__/formattable.
331
+ // Excludes enums for the same reason as the __repr__ fallback above.
332
+ template<typename T>
333
+ requires (!requires(const T& t) { t.__str__(); })
334
+ && (!requires(const T& t) { t.__repr__(); })
335
+ && (!std::is_enum_v<T>)
336
+ && (!std::formattable<T, char>)
337
+ && requires(std::ostream& os, const T& t) { os << t; }
338
+ std::string __str__(const T& x) {
339
+ std::ostringstream ss;
340
+ ss << x;
341
+ return ss.str();
342
+ }
343
+
344
+ // Union (std::variant): visit the active alternative and recurse. Pointer
345
+ // alternatives (T*) are dereffed before dispatch (matches the variant
346
+ // repr overload below).
347
+ template<typename... Ts>
348
+ std::string __str__(const std::variant<Ts...>& v) {
349
+ return std::visit([](auto&& a) -> std::string {
350
+ using A = std::remove_cvref_t<decltype(a)>;
351
+ if constexpr (std::is_pointer_v<A>) {
352
+ return std::string(::tpy::__str__(*a));
353
+ } else {
354
+ return std::string(::tpy::__str__(a));
355
+ }
356
+ }, v);
357
+ }
358
+
359
+ // =============================================
360
+ // tpy::__repr__
361
+ // =============================================
362
+
363
+ // Forward decl: repr_of is the user-facing dispatch helper, defined in
364
+ // tpy.hpp after every header that contributes __repr__ overloads (notably
365
+ // bytes_ops.hpp which adds __repr__ for raw Bytes). Optional/variant repr
366
+ // templates above use it for ADL into per-record __repr__ overrides;
367
+ // qualified lookup of `::tpy::repr_of` from a template body needs the
368
+ // name visible at parse time, so the forward declaration precedes those
369
+ // template bodies.
370
+ template<typename T> auto repr_of(const T& x);
371
+
372
+ // Default template: user types that define __repr__() method
373
+ template<typename T>
374
+ requires requires(const T& t) { t.__repr__(); }
375
+ auto __repr__(const T& x) {
376
+ return x.__repr__();
377
+ }
378
+
379
+ // User records without __repr__: emit the Python default
380
+ // `<ClassName object at 0xADDR>` form. The class name comes from a
381
+ // `static constexpr __tpy_class_name__` member emitted by codegen.
382
+ template<typename T>
383
+ requires (!requires(const T& t) { t.__repr__(); })
384
+ && requires { T::__tpy_class_name__; }
385
+ inline std::string __repr__(const T& x) {
386
+ std::ostringstream ss;
387
+ ::tpy::print_object_default(ss, T::__tpy_class_name__, x);
388
+ return ss.str();
389
+ }
390
+
391
+ // Bool: Python repr uses True/False (not C++ true/false)
392
+ inline std::string_view __repr__(bool x) {
393
+ return x ? "True" : "False";
394
+ }
395
+
396
+ // None: repr matches str ("None")
397
+ inline std::string_view __repr__(std::nullptr_t) {
398
+ return "None";
399
+ }
400
+
401
+ // std::monostate is the TPy unit type at value-bearing positions
402
+ // (Future[None], list[None], ...). Mirror the nullptr_t overload so
403
+ // any_repr_capable<monostate> matches and Any cells holding None
404
+ // route to "None" rather than the typeid fallback.
405
+ inline std::string_view __repr__(std::monostate) {
406
+ return "None";
407
+ }
408
+
409
+ // Strings: Python repr quotes and escapes control chars / quote / backslash.
410
+ // The const char* overload steals string-literal calls before the templated
411
+ // formattable fallback (which would otherwise emit raw bytes via std::format).
412
+ inline std::string __repr__(const std::string& x) {
413
+ return repr_quote_string(x);
414
+ }
415
+ inline std::string __repr__(std::string_view x) {
416
+ return repr_quote_string(x);
417
+ }
418
+ inline std::string __repr__(const char* x) {
419
+ return repr_quote_string(std::string_view(x));
420
+ }
421
+
422
+ // Optional: None or repr(value).
423
+ template<typename T>
424
+ std::string __repr__(const std::optional<T>& x) {
425
+ if (!x.has_value()) return "None";
426
+ if constexpr (std::same_as<T, std::string> || std::same_as<T, std::string_view>) {
427
+ return repr_quote_string(*x);
428
+ } else if constexpr (std::same_as<T, bool>) {
429
+ return *x ? "True" : "False";
430
+ } else if constexpr (std::floating_point<T>) {
431
+ return format_float(static_cast<double>(*x));
432
+ } else {
433
+ // repr_of (not direct ::tpy::__repr__) so ADL into T's namespace
434
+ // can reach per-record overrides; a qualified call from a runtime
435
+ // template body would freeze the candidate set at definition.
436
+ return std::string(::tpy::repr_of(*x));
437
+ }
438
+ }
439
+
440
+ // Python-faithful repr for floating point: always shows trailing .0
441
+ inline std::string __repr__(double x) { return format_float(x); }
442
+ inline std::string __repr__(float x) { return format_float(static_cast<double>(x)); }
443
+
444
+ // Fallback for formattable types without __repr__ (e.g. int).
445
+ template<typename T>
446
+ requires (!requires(const T& t) { t.__repr__(); })
447
+ && (!std::same_as<T, std::string>)
448
+ && (!std::same_as<T, std::string_view>)
449
+ && (!std::floating_point<T>)
450
+ && std::formattable<T, char>
451
+ auto __repr__(const T& x) {
452
+ return std::format("{}", x);
453
+ }
454
+
455
+ // Enum repr: any enum type with an EnumUtil specialization renders as
456
+ // "TypeName.MEMBER". The operator<<-fallback below explicitly excludes
457
+ // enums via `!std::is_enum_v<T>`, so this template is the only candidate
458
+ // for enum types (partitioning, not partial ordering -- the constraint
459
+ // sets are disjoint, not subsumption-related). For @native enums there
460
+ // is no operator<< at all, so this is the only repr path; for tpy-defined
461
+ // enums it produces the same "TypeName.MEMBER" output that the operator<<
462
+ // body would have generated.
463
+ template<typename T>
464
+ requires std::is_enum_v<T>
465
+ && requires(T x) { ::tpy::EnumUtil<T>::name(x); }
466
+ inline std::string __repr__(T x) {
467
+ return ::tpy::detail::enum_repr_string(x);
468
+ }
469
+
470
+ // Fallback for types with operator<< but no __repr__/formattable.
471
+ // Excludes TPy records (`__tpy_class_name__`-tagged) so the default-repr
472
+ // template above wins unambiguously -- otherwise both templates match
473
+ // for records without __repr__. Also excludes enums so the
474
+ // EnumUtil-driven template above wins for enum types (constraint sets
475
+ // don't subsume, so we disambiguate by partitioning).
476
+ template<typename T>
477
+ requires (!requires(const T& t) { t.__repr__(); })
478
+ && (!requires { T::__tpy_class_name__; })
479
+ && (!std::is_enum_v<T>)
480
+ && (!std::formattable<T, char>)
481
+ && requires(std::ostream& os, const T& t) { os << t; }
482
+ std::string __repr__(const T& x) {
483
+ std::ostringstream ss;
484
+ ss << x;
485
+ return ss.str();
486
+ }
487
+
488
+ // Union (std::variant): visit the active alternative and recurse. Each
489
+ // alternative type must have its own __repr__ overload reachable above;
490
+ // pointer-variant alternatives (T*) are dereffed before dispatch. Goes
491
+ // through repr_of so ADL on the alternative type finds per-record
492
+ // overrides emitted alongside user records.
493
+ template<typename... Ts>
494
+ std::string __repr__(const std::variant<Ts...>& v) {
495
+ return std::visit([](auto&& a) -> std::string {
496
+ using A = std::remove_cvref_t<decltype(a)>;
497
+ if constexpr (std::is_pointer_v<A>) {
498
+ return std::string(::tpy::repr_of(*a));
499
+ } else {
500
+ return std::string(::tpy::repr_of(a));
501
+ }
502
+ }, v);
503
+ }
504
+
505
+ // =============================================
506
+ // tpy::__hash__
507
+ // =============================================
508
+
509
+ // Integral types (int8_t through uint64_t, bool, char)
510
+ template<typename T>
511
+ requires std::integral<T>
512
+ uint64_t __hash__(T x) {
513
+ return static_cast<uint64_t>(std::hash<T>{}(x));
514
+ }
515
+
516
+ // Floating-point
517
+ inline uint64_t __hash__(double x) {
518
+ return static_cast<uint64_t>(std::hash<double>{}(x));
519
+ }
520
+
521
+ // std::monostate is the TPy unit type at value-bearing positions; map
522
+ // to Python's hash(None) (== 0 on most CPython builds, but the only
523
+ // requirement is stability + matching None==None equality).
524
+ inline uint64_t __hash__(std::monostate) {
525
+ return 0;
526
+ }
527
+
528
+ // Strings
529
+ inline uint64_t __hash__(const std::string& x) {
530
+ return static_cast<uint64_t>(std::hash<std::string>{}(x));
531
+ }
532
+ inline uint64_t __hash__(std::string_view x) {
533
+ return static_cast<uint64_t>(std::hash<std::string_view>{}(x));
534
+ }
535
+ inline uint64_t __hash__(const char* x) {
536
+ return static_cast<uint64_t>(std::hash<std::string_view>{}(std::string_view(x)));
537
+ }
538
+
539
+ // Bytes (std::vector<uint8_t>) and BytesView (std::span<const uint8_t>)
540
+ inline uint64_t __hash__(const std::vector<uint8_t>& x) {
541
+ return static_cast<uint64_t>(std::hash<std::string_view>{}(
542
+ std::string_view(reinterpret_cast<const char*>(x.data()), x.size())));
543
+ }
544
+ inline uint64_t __hash__(std::span<const uint8_t> x) {
545
+ return static_cast<uint64_t>(std::hash<std::string_view>{}(
546
+ std::string_view(reinterpret_cast<const char*>(x.data()), x.size())));
547
+ }
548
+
549
+ // Enum types
550
+ template<typename T>
551
+ requires std::is_enum_v<T>
552
+ uint64_t __hash__(T x) {
553
+ return static_cast<uint64_t>(std::hash<std::underlying_type_t<T>>{}(
554
+ static_cast<std::underlying_type_t<T>>(x)));
555
+ }
556
+
557
+ // Default: user types with __hash__() method
558
+ template<typename T>
559
+ requires requires(const T& t) { { t.__hash__() } -> std::convertible_to<uint64_t>; }
560
+ uint64_t __hash__(const T& x) {
561
+ return static_cast<uint64_t>(x.__hash__());
562
+ }
563
+
564
+ // User types with __hash__() returning BigInt
565
+ template<typename T>
566
+ requires (requires(const T& t) { { t.__hash__() } -> std::same_as<BigInt>; }
567
+ && !requires(const T& t) { { t.__hash__() } -> std::convertible_to<uint64_t>; })
568
+ uint64_t __hash__(const T& x) {
569
+ return x.__hash__().hash();
570
+ }
571
+
572
+ // =============================================
573
+ // tpy::hash_combine -- Boost-style hash combining for dataclass __hash__
574
+ // =============================================
575
+
576
+ inline uint64_t hash_combine(uint64_t seed) {
577
+ return seed;
578
+ }
579
+
580
+ template<typename T, typename... Rest>
581
+ uint64_t hash_combine(uint64_t seed, const T& val, const Rest&... rest) {
582
+ seed ^= __hash__(val) + 0x9e3779b97f4a7c15ULL + (seed << 6) + (seed >> 2);
583
+ return hash_combine(seed, rest...);
584
+ }
585
+
586
+ // Tuple types
587
+ template<typename... Ts>
588
+ uint64_t __hash__(const std::tuple<Ts...>& t) {
589
+ return std::apply([](const auto&... elems) {
590
+ return hash_combine(0, elems...);
591
+ }, t);
592
+ }
593
+
594
+ // =============================================
595
+ // native_iterator: wraps C++ begin/end into __next__() / __iter__()
596
+ // Inherits begin()/end() from next_iter_mixin so the result of
597
+ // tpy::__iter__() can also be used in C++ range-for loops.
598
+ //
599
+ // __next__() returns val_or_ref<deref_type> to preserve reference
600
+ // semantics: value types are copied, non-value types are returned
601
+ // as pointers (transparent via .get()). This allows protocol-typed
602
+ // iteration (Iterable[T], Iterator[T]) to mutate container elements.
603
+ // =============================================
604
+
605
+ template<typename Iter, typename T>
606
+ struct native_iterator
607
+ : next_iter_mixin<native_iterator<Iter, T>, val_or_ref<std::remove_reference_t<decltype(*std::declval<Iter&>())>>> {
608
+ using deref_type = std::remove_reference_t<decltype(*std::declval<Iter&>())>;
609
+ using next_type = val_or_ref<deref_type>;
610
+
611
+ Iter current_;
612
+ Iter end_;
613
+
614
+ native_iterator(Iter begin, Iter end) : current_(begin), end_(end) {}
615
+
616
+ std::expected<next_type, StopIteration> __next__() {
617
+ if (current_ == end_) return tpy::make_unexpected(StopIteration{});
618
+ return next_type(*current_++);
619
+ }
620
+
621
+ native_iterator& __iter__() { return *this; }
622
+
623
+ // Opaque repr, matching CPython's behavior for iterator objects.
624
+ friend std::ostream& operator<<(std::ostream& os, const native_iterator&) {
625
+ return os << "<iterator>";
626
+ }
627
+ };
628
+
629
+ // =============================================
630
+ // tpy::__iter__
631
+ // =============================================
632
+
633
+ // Overload: std::vector (mutable -- preserves element references)
634
+ template<typename T>
635
+ auto __iter__(std::vector<T>& x) {
636
+ return native_iterator<typename std::vector<T>::iterator, T>{x.begin(), x.end()};
637
+ }
638
+
639
+ // Overload: std::vector (const)
640
+ template<typename T>
641
+ auto __iter__(const std::vector<T>& x) {
642
+ return native_iterator<typename std::vector<T>::const_iterator, T>{x.begin(), x.end()};
643
+ }
644
+
645
+ // Overload: std::array (mutable)
646
+ template<typename T, std::size_t N>
647
+ auto __iter__(std::array<T, N>& x) {
648
+ return native_iterator<typename std::array<T, N>::iterator, T>{x.begin(), x.end()};
649
+ }
650
+
651
+ // Overload: std::array (const)
652
+ template<typename T, std::size_t N>
653
+ auto __iter__(const std::array<T, N>& x) {
654
+ return native_iterator<typename std::array<T, N>::const_iterator, T>{x.begin(), x.end()};
655
+ }
656
+
657
+ // Overload: std::span (const)
658
+ template<typename T>
659
+ auto __iter__(std::span<const T> x) {
660
+ return native_iterator<typename std::span<const T>::iterator, T>{x.begin(), x.end()};
661
+ }
662
+
663
+ // Overload: std::span (mutable)
664
+ template<typename T>
665
+ auto __iter__(std::span<T> x) {
666
+ return native_iterator<typename std::span<T>::iterator, T>{x.begin(), x.end()};
667
+ }
668
+
669
+ // Overload: std::string
670
+ inline auto __iter__(const std::string& x) {
671
+ return native_iterator<std::string::const_iterator, char>{x.begin(), x.end()};
672
+ }
673
+
674
+ // Overload: std::string_view
675
+ inline auto __iter__(std::string_view x) {
676
+ return native_iterator<std::string_view::const_iterator, char>{x.begin(), x.end()};
677
+ }
678
+
679
+ // Overload: const char* (string literals)
680
+ inline auto __iter__(const char* x) {
681
+ return __iter__(std::string_view(x));
682
+ }
683
+
684
+ // Generic overload: any C++ range type not covered above (e.g., tpy::Range<T>)
685
+ // Constrained to types without __iter__() to avoid ambiguity with user types.
686
+ template<typename T>
687
+ requires std::ranges::input_range<const T>
688
+ && (!requires(const T& t) { t.__iter__(); })
689
+ auto __iter__(const T& x) {
690
+ using ElemT = std::remove_cvref_t<decltype(*x.begin())>;
691
+ return native_iterator<decltype(x.begin()), ElemT>{x.begin(), x.end()};
692
+ }
693
+
694
+ // Default template: user types that define __iter__() method
695
+ // decltype(auto) preserves reference returns (e.g. OwnIterSet& __iter__())
696
+ // to avoid copying move-only iterator types.
697
+ template<typename T>
698
+ requires requires(T& t) { t.__iter__(); }
699
+ decltype(auto) __iter__(T& x) {
700
+ return x.__iter__();
701
+ }
702
+
703
+ // Const overload for user types
704
+ template<typename T>
705
+ requires requires(const T& t) { t.__iter__(); }
706
+ decltype(auto) __iter__(const T& x) {
707
+ return x.__iter__();
708
+ }
709
+
710
+ } // namespace tpy
711
+
712
+ // std::hash specialization for bytes (needed by std::unordered_map/set)
713
+ template<>
714
+ struct std::hash<std::vector<uint8_t>> {
715
+ size_t operator()(const std::vector<uint8_t>& v) const noexcept {
716
+ return std::hash<std::string_view>{}(
717
+ std::string_view(reinterpret_cast<const char*>(v.data()), v.size()));
718
+ }
719
+ };
720
+
721
+ // std::hash + std::equal_to specializations for BytesView (std::span<const uint8_t>).
722
+ // std::span has no built-in operator==, so unordered_map/set need an explicit
723
+ // equality comparator alongside the hash.
724
+ template<>
725
+ struct std::hash<std::span<const uint8_t>> {
726
+ size_t operator()(std::span<const uint8_t> v) const noexcept {
727
+ // Empty span may hold (nullptr, 0); string_view's hash on a null
728
+ // pointer is implementation-defined. Match equal_to's empty short-circuit.
729
+ if (v.empty()) return 0;
730
+ return std::hash<std::string_view>{}(
731
+ std::string_view(reinterpret_cast<const char*>(v.data()), v.size()));
732
+ }
733
+ };
734
+ template<>
735
+ struct std::equal_to<std::span<const uint8_t>> {
736
+ bool operator()(std::span<const uint8_t> a, std::span<const uint8_t> b) const noexcept {
737
+ if (a.size() != b.size()) return false;
738
+ // memcmp on null pointers is UB even with size 0; std::span is
739
+ // allowed to hold (nullptr, 0) for an empty span.
740
+ return a.empty() || std::memcmp(a.data(), b.data(), a.size()) == 0;
741
+ }
742
+ };
743
+
744
+ // std::hash specialization for tuples (needed by std::unordered_map/set)
745
+ template<typename... Ts>
746
+ struct std::hash<std::tuple<Ts...>> {
747
+ size_t operator()(const std::tuple<Ts...>& t) const noexcept {
748
+ return static_cast<size_t>(tpy::__hash__(t));
749
+ }
750
+ };