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,221 @@
1
+ # tpy: cpp_namespace("tpystd::json")
2
+ # CPython-compatible json module.
3
+ #
4
+ # Pure-TPy wrapper over tplib.json's JsonReader/JsonWriter. Mirrors the
5
+ # CPython API surface (loads, dumps, JSONDecodeError) for untyped JSON
6
+ # values represented as a recursive union.
7
+ #
8
+ # For typed deserialization into user records, use `tplib.json` with the
9
+ # `@model` decorator -- it's faster and statically typed.
10
+ #
11
+ # Consuming a `loads` result:
12
+ #
13
+ # loads(s) returns `Own[JsonValue]`. JsonValue is a recursive union, so
14
+ # `d["k"]` at the use site is rejected -- not every member supports str
15
+ # subscript, and CPython only gets away with it because its `loads`
16
+ # returns `Any`. Each level of access needs to be narrowed:
17
+ #
18
+ # def show(v: JsonValue) -> None:
19
+ # match v:
20
+ # case dict() as obj:
21
+ # print(obj["users"])
22
+ # case _:
23
+ # print("not a dict")
24
+ #
25
+ # d = json.loads(s) # d: Own[JsonValue]
26
+ # show(d) # auto-moves into v: JsonValue
27
+ #
28
+ # For deeply-nested known-shape JSON, prefer `tplib.json` with the
29
+ # `@model` decorator -- you declare a record class for the shape and
30
+ # parse directly into it, with no per-level narrowing.
31
+ #
32
+ # Followup (BUGS.md): once `isinstance` accepts type aliases / generic
33
+ # types, exposing `JsonObject = dict[str, JsonValue]` and `JsonList =
34
+ # list[JsonValue]` here will make the natural pattern --
35
+ # `if isinstance(d, JsonObject): d["k"]` -- work without writing a
36
+ # helper or using `match`. Until then the helper-with-match pattern
37
+ # above is the cleanest.
38
+ #
39
+ # Not yet supported (deferred):
40
+ # - load(fp) / dump(obj, fp): blocked on `io` module
41
+ # - JSONEncoder / JSONDecoder classes (extension hooks)
42
+ # - dumps kwargs: ensure_ascii (always behaves as if False -- non-ASCII
43
+ # is emitted as raw UTF-8), separators (uses CPython defaults),
44
+ # allow_nan, default, cls, skipkeys
45
+ # - loads kwargs: object_hook, object_pairs_hook, parse_float, parse_int,
46
+ # parse_constant
47
+ from tpy import Int32, Own, error_return
48
+ from tplib.json import JsonError, JsonReader, JsonToken, JsonWriter
49
+
50
+
51
+ type JsonValue = (
52
+ None
53
+ | bool
54
+ | int
55
+ | float
56
+ | str
57
+ | list[JsonValue]
58
+ | dict[str, JsonValue]
59
+ )
60
+
61
+
62
+ class JSONDecodeError(ValueError):
63
+ """CPython-compatible JSON decode error.
64
+
65
+ Thrown via normal try/except so callers don't need `@error_return`
66
+ decoration. Carries CPython-named attributes (msg, doc, pos, lineno,
67
+ colno). Subclasses ValueError to match CPython's hierarchy --
68
+ `except ValueError` catches it.
69
+ """
70
+ msg: str
71
+ doc: str
72
+ pos: Int32
73
+ lineno: Int32
74
+ colno: Int32
75
+
76
+ def __init__(self, msg: str, doc: str, pos: Int32) -> None:
77
+ # `message` is BaseException's runtime field (used by __str__);
78
+ # `msg` is CPython's documented attribute on JSONDecodeError.
79
+ # Always equal -- both names are exposed for compatibility.
80
+ self.message = msg
81
+ self.msg = msg
82
+ self.doc = doc
83
+ self.pos = pos
84
+ # 1-based to match CPython's JSONDecodeError.lineno/colno contract.
85
+ line: Int32 = 1
86
+ col: Int32 = 1
87
+ i: Int32 = 0
88
+ end = pos
89
+ if end > len(doc):
90
+ end = len(doc)
91
+ while i < end:
92
+ if doc[i] == "\n":
93
+ line += 1
94
+ col = 1
95
+ else:
96
+ col += 1
97
+ i += 1
98
+ self.lineno = line
99
+ self.colno = col
100
+
101
+
102
+ # ----------------------------------------------------------------------
103
+ # loads
104
+ # ----------------------------------------------------------------------
105
+
106
+ # Internal recursion uses JsonError directly; loads() converts to
107
+ # JSONDecodeError at the boundary. Avoids per-call try/except wrappers
108
+ # around every JsonReader operation. Own[JsonValue] return is required:
109
+ # recursive unions containing reference-type members (list/dict) need
110
+ # explicit ownership transfer to return freshly built values.
111
+ @error_return(JsonError)
112
+ def _read_value(reader: JsonReader) -> Own[JsonValue]:
113
+ tok = reader.peek()
114
+ if tok == JsonToken.OBJECT_START:
115
+ d: dict[str, JsonValue] = {}
116
+ reader.read_object_start()
117
+ while reader.has_next():
118
+ key = reader.read_key()
119
+ # Intermediate local: dict subscript assignment doesn't accept
120
+ # an Own[T] rvalue directly today. Revisit if the compiler
121
+ # learns to auto-move Own into subscript slots.
122
+ val = _read_value(reader)
123
+ d[key] = val
124
+ reader.read_object_end()
125
+ return d
126
+ if tok == JsonToken.ARRAY_START:
127
+ a: list[JsonValue] = []
128
+ reader.read_array_start()
129
+ while reader.has_next():
130
+ item = _read_value(reader)
131
+ a.append(item)
132
+ reader.read_array_end()
133
+ return a
134
+ if tok == JsonToken.STRING:
135
+ return reader.read_str()
136
+ if tok == JsonToken.NUMBER:
137
+ raw = reader.read_number_raw()
138
+ # Preserve BigInt precision: parse via int() unless the lexeme has
139
+ # float syntax. CPython treats `1` and `1.0` as int and float.
140
+ is_float = False
141
+ i: Int32 = 0
142
+ n = len(raw)
143
+ while i < n:
144
+ c = raw[i]
145
+ if c == "." or c == "e" or c == "E":
146
+ is_float = True
147
+ break
148
+ i += 1
149
+ if is_float:
150
+ return float(raw)
151
+ return int(raw)
152
+ if tok == JsonToken.TRUE:
153
+ reader.read_bool()
154
+ return True
155
+ if tok == JsonToken.FALSE:
156
+ reader.read_bool()
157
+ return False
158
+ if tok == JsonToken.NONE:
159
+ reader.read_null()
160
+ return None
161
+ raise JsonError("Expecting value", reader.position())
162
+
163
+
164
+ def loads(s: str) -> Own[JsonValue]:
165
+ """Deserialize a JSON document string into a JsonValue.
166
+
167
+ Returns one of: None, bool, int (BigInt), float, str, list[JsonValue],
168
+ dict[str, JsonValue]. Raises JSONDecodeError on malformed input or
169
+ trailing data after the top-level value.
170
+ """
171
+ reader = JsonReader(s)
172
+ try:
173
+ value = _read_value(reader)
174
+ except JsonError as e:
175
+ raise JSONDecodeError(e.message, s, e.pos)
176
+ # CPython rejects trailing non-whitespace; peek() skips whitespace and
177
+ # returns END at EOF.
178
+ if reader.peek() != JsonToken.END:
179
+ raise JSONDecodeError("Extra data", s, reader.position())
180
+ return value
181
+
182
+
183
+ # ----------------------------------------------------------------------
184
+ # dumps
185
+ # ----------------------------------------------------------------------
186
+
187
+ def _write_value(v: JsonValue, w: JsonWriter, sort_keys: bool) -> None:
188
+ match v:
189
+ case None:
190
+ w.write_null()
191
+ case bool() as b:
192
+ w.write_bool(b)
193
+ case int() as n:
194
+ w.write_bigint(n)
195
+ case float() as f:
196
+ w.write_float(f)
197
+ case str() as s:
198
+ w.write_str(s)
199
+ case list() as items:
200
+ w.array_start()
201
+ for item in items:
202
+ _write_value(item, w, sort_keys)
203
+ w.array_end()
204
+ case dict() as d:
205
+ w.object_start()
206
+ keys = sorted(d.keys()) if sort_keys else list(d.keys())
207
+ for k in keys:
208
+ w.key(k)
209
+ _write_value(d[k], w, sort_keys)
210
+ w.object_end()
211
+
212
+
213
+ def dumps(obj: JsonValue, indent: Int32 = 0, sort_keys: bool = False) -> str:
214
+ """Serialize a JsonValue to a JSON-formatted str.
215
+
216
+ indent: non-zero turns on pretty-printing with that many spaces per level.
217
+ sort_keys: when True, dict keys are emitted in sorted order.
218
+ """
219
+ w = JsonWriter(indent)
220
+ _write_value(obj, w, sort_keys)
221
+ return w.finish()
@@ -0,0 +1,406 @@
1
+ # tpy: cpp_namespace("tpystd::math")
2
+ # tpy: include("<tpy/stdlib/math.hpp>")
3
+ #
4
+ # Pending items to reach full CPython `math` parity. Each is blocked on a
5
+ # specific compiler gap tracked in TODO.md / BUGS.md; once fixed, update
6
+ # this module.
7
+ #
8
+ # - Tuple inputs to `prod`, `fsum`, `sumprod`, `dist`. CPython accepts
9
+ # tuples for all four (`math.prod((1.0, 2.0, 3.0))`). Currently fails
10
+ # conformance to `Iterable[float]`. Blocked on the "Tuple iteration +
11
+ # Iterable conformance bundle" TODO.md entry -- needs coordinated sema,
12
+ # codegen, and runtime work (std::tuple has no begin/end).
13
+ # - Generic over int type for `gcd`, `isqrt` (result bounded by input, so
14
+ # generic is safe). Currently `int`-only forces BigInt allocation for
15
+ # small-int callers under --default-int=Int32. Pure-TPy generic is
16
+ # blocked on two language gaps: the missing `AnyInt` protocol (BigInt +
17
+ # AnyFixedInt) and the ban on `-x` / `abs(x)` / param reassignment
18
+ # inside unbounded-generic bodies. See TODO.md "No `AnyInt` protocol
19
+ # covering BigInt + all `AnyFixedInt`". `lcm`, `factorial`, `perm`,
20
+ # `comb` should probably stay `int`-only even once that lands -- their
21
+ # results can exceed fixed-int range (e.g. factorial(13) > Int32::max).
22
+ #
23
+ # Algorithmic follow-ups (correctness under our implementation, but not
24
+ # bit-exact or optimal vs CPython):
25
+ #
26
+ # - `fsum`: currently Neumaier compensated summation. Significantly better
27
+ # than naive but not bit-exact. CPython uses Shewchuk's partials
28
+ # algorithm (maintains a growing list of non-overlapping partials,
29
+ # guarantees the sum rounds correctly to a single double). Worth
30
+ # adopting if users depend on fsum for bit-exact precision.
31
+ # - `sumprod`: naive fold. CPython uses compensated arithmetic (similar
32
+ # to fsum) for precision. Large vectors can lose low bits in our impl.
33
+ # - `log(x, base)`: always `log(x) / log(base)`. CPython special-cases
34
+ # `base == 2` to dispatch to `log2` (one fewer transcendental call).
35
+ # Minor; consider if benchmarks warrant.
36
+
37
+ from typing import Final, Iterable, overload
38
+ from tpy import Int32
39
+ from tpy.extern import native, cpp_template, type_param_default, DefaultInt
40
+
41
+ pi: Final[float] = 3.141592653589793
42
+ tau: Final[float] = 6.283185307179586
43
+ e: Final[float] = 2.718281828459045
44
+ inf: Final[float] = 1e309
45
+ nan: Final[float] = float("nan")
46
+
47
+ @overload
48
+ @native("std::log")
49
+ def log(x: float) -> float: ...
50
+
51
+ @overload
52
+ def log(x: float, base: float) -> float:
53
+ return log(x) / log(base)
54
+
55
+ @native("std::log10")
56
+ def log10(x: float) -> float: ...
57
+
58
+ @native("std::log2")
59
+ def log2(x: float) -> float: ...
60
+
61
+ @native("std::sqrt")
62
+ def sqrt(x: float) -> float: ...
63
+
64
+ @native("std::cbrt")
65
+ def cbrt(x: float) -> float: ...
66
+
67
+ @native("std::pow")
68
+ def pow(x: float, y: float) -> float: ...
69
+
70
+ @native("std::exp")
71
+ def exp(x: float) -> float: ...
72
+
73
+ @native("std::exp2")
74
+ def exp2(x: float) -> float: ...
75
+
76
+ @native("std::expm1")
77
+ def expm1(x: float) -> float: ...
78
+
79
+ @native("std::log1p")
80
+ def log1p(x: float) -> float: ...
81
+
82
+ @native("std::tgamma")
83
+ def gamma(x: float) -> float: ...
84
+
85
+ @native("std::lgamma")
86
+ def lgamma(x: float) -> float: ...
87
+
88
+ @native("std::erf")
89
+ def erf(x: float) -> float: ...
90
+
91
+ @native("std::erfc")
92
+ def erfc(x: float) -> float: ...
93
+
94
+ @native("std::nextafter")
95
+ def nextafter(x: float, y: float) -> float: ...
96
+
97
+ @native("std::ldexp")
98
+ def ldexp(x: float, i: Int32) -> float: ...
99
+
100
+ @native("std::fma")
101
+ def fma(x: float, y: float, z: float) -> float: ...
102
+
103
+ @native("tpy::stdlib::math::modf")
104
+ def modf(x: float) -> tuple[float, float]: ...
105
+
106
+ # Exponent always fits in a 16+ bit signed int (actual range
107
+ # [-1073, 1024] for IEEE 754 double; see tpy/stdlib/math.hpp for why).
108
+ # Defaults to DefaultInt (respects --default-int); user can pick Int32,
109
+ # Int64, BigInt, etc. explicitly. Zero-allocation for fixed-width T;
110
+ # BigInt allocates.
111
+ @type_param_default(T=DefaultInt)
112
+ @cpp_template("::tpy::stdlib::math::frexp<{T}>({0})")
113
+ def frexp[T](x: float) -> tuple[float, T]: ...
114
+
115
+ @native("tpy::stdlib::math::ulp")
116
+ def ulp(x: float) -> float: ...
117
+
118
+ @native("tpy::BigInt::from_floor")
119
+ def floor(x: float) -> int: ...
120
+
121
+ @native("tpy::BigInt::from_ceil")
122
+ def ceil(x: float) -> int: ...
123
+
124
+ @native("std::sin")
125
+ def sin(x: float) -> float: ...
126
+
127
+ @native("std::cos")
128
+ def cos(x: float) -> float: ...
129
+
130
+ @native("std::tan")
131
+ def tan(x: float) -> float: ...
132
+
133
+ @native("std::fabs")
134
+ def fabs(x: float) -> float: ...
135
+
136
+ @native("std::hypot")
137
+ def _hypot2(x: float, y: float) -> float: ...
138
+
139
+ def hypot(*coords: float) -> float:
140
+ if len(coords) == 0:
141
+ return 0.0
142
+ # Hypot-fold is overflow-safe: hypot(hypot(a, b), c) == sqrt(a^2 + b^2 + c^2).
143
+ result = fabs(coords[0])
144
+ for c in coords[1:]:
145
+ result = _hypot2(result, c)
146
+ return result
147
+
148
+ @native("std::atan2")
149
+ def atan2(y: float, x: float) -> float: ...
150
+
151
+ @native("std::asin")
152
+ def asin(x: float) -> float: ...
153
+
154
+ @native("std::acos")
155
+ def acos(x: float) -> float: ...
156
+
157
+ @native("std::atan")
158
+ def atan(x: float) -> float: ...
159
+
160
+ @native("std::sinh")
161
+ def sinh(x: float) -> float: ...
162
+
163
+ @native("std::cosh")
164
+ def cosh(x: float) -> float: ...
165
+
166
+ @native("std::tanh")
167
+ def tanh(x: float) -> float: ...
168
+
169
+ @native("std::asinh")
170
+ def asinh(x: float) -> float: ...
171
+
172
+ @native("std::acosh")
173
+ def acosh(x: float) -> float: ...
174
+
175
+ @native("std::atanh")
176
+ def atanh(x: float) -> float: ...
177
+
178
+ @native("std::isnan")
179
+ def isnan(x: float) -> bool: ...
180
+
181
+ @native("std::isinf")
182
+ def isinf(x: float) -> bool: ...
183
+
184
+ @native("std::isfinite")
185
+ def isfinite(x: float) -> bool: ...
186
+
187
+ @native("std::copysign")
188
+ def copysign(x: float, y: float) -> float: ...
189
+
190
+ @native("std::fmod")
191
+ def fmod(x: float, y: float) -> float: ...
192
+
193
+ @native("std::remainder")
194
+ def remainder(x: float, y: float) -> float: ...
195
+
196
+ def radians(x: float) -> float:
197
+ return x * (pi / 180.0)
198
+
199
+ def degrees(x: float) -> float:
200
+ return x * (180.0 / pi)
201
+
202
+ def _gcd2(a: int, b: int) -> int:
203
+ if a < 0:
204
+ a = -a
205
+ if b < 0:
206
+ b = -b
207
+ while b != 0:
208
+ t: int = b
209
+ b = a % b
210
+ a = t
211
+ return a
212
+
213
+ def gcd(*ints: int) -> int:
214
+ if len(ints) == 0:
215
+ return 0
216
+ result = ints[0]
217
+ if result < 0:
218
+ result = -result
219
+ for x in ints[1:]:
220
+ if result == 1:
221
+ return 1
222
+ result = _gcd2(result, x)
223
+ return result
224
+
225
+ def lcm(*ints: int) -> int:
226
+ if len(ints) == 0:
227
+ return 1
228
+ result = ints[0]
229
+ if result < 0:
230
+ result = -result
231
+ for x in ints[1:]:
232
+ if result == 0 or x == 0:
233
+ return 0
234
+ # (a // gcd(a, b)) * b keeps the intermediate bounded by max(|a|, |b|);
235
+ # the naive a*b first would blow up for large BigInts.
236
+ result = (result // _gcd2(result, x)) * x
237
+ if result < 0:
238
+ result = -result
239
+ return result
240
+
241
+ def factorial(n: int) -> int:
242
+ if n < 0:
243
+ raise ValueError("factorial() not defined for negative values")
244
+ result: int = 1
245
+ i: int = 2
246
+ while i <= n:
247
+ result = result * i
248
+ i = i + 1
249
+ return result
250
+
251
+ def isqrt(n: int) -> int:
252
+ if n < 0:
253
+ raise ValueError("isqrt() argument must be nonnegative")
254
+ if n == 0:
255
+ return 0
256
+ # Newton's method from a bit-length-derived initial guess: for an
257
+ # n-bit input, sqrt(n) has ~n/2 bits, so 1 << ((bits + 1) // 2) is
258
+ # already an upper bound within a factor of 2 of the answer (factor
259
+ # is sqrt(2) for even bit_length, exactly 2 for odd). Convergence
260
+ # drops from O(log n) iterations (when starting at n) to O(log log n).
261
+ # The `int(1)` LHS forces BigInt arithmetic so the shift can exceed
262
+ # Int32 width without overflow-checking.
263
+ x: int = int(1) << ((n.bit_length() + 1) // 2)
264
+ y: int = (x + n // x) // 2
265
+ while y < x:
266
+ x = y
267
+ y = (x + n // x) // 2
268
+ return x
269
+
270
+ @overload
271
+ def perm(n: int) -> int:
272
+ return factorial(n)
273
+
274
+ @overload
275
+ def perm(n: int, k: int) -> int:
276
+ if n < 0 or k < 0:
277
+ raise ValueError("perm() arguments must be non-negative")
278
+ if k > n:
279
+ return 0
280
+ result: int = 1
281
+ i: int = 0
282
+ while i < k:
283
+ result = result * (n - i)
284
+ i = i + 1
285
+ return result
286
+
287
+ def comb(n: int, k: int) -> int:
288
+ if n < 0 or k < 0:
289
+ raise ValueError("comb() arguments must be non-negative")
290
+ if k > n:
291
+ return 0
292
+ if k > n - k:
293
+ k = n - k
294
+ result: int = 1
295
+ i: int = 0
296
+ while i < k:
297
+ result = result * (n - i) // (i + 1)
298
+ i = i + 1
299
+ return result
300
+
301
+ def isclose(a: float, b: float, *, rel_tol: float = 1e-09, abs_tol: float = 0.0) -> bool:
302
+ if a == b:
303
+ return True
304
+ if isinf(a) or isinf(b):
305
+ return False
306
+ diff: float = fabs(a - b)
307
+ max_ab: float = fabs(a)
308
+ if fabs(b) > max_ab:
309
+ max_ab = fabs(b)
310
+ return diff <= abs_tol or diff <= rel_tol * max_ab
311
+
312
+ @overload
313
+ def prod(iterable: Iterable[Int32], *, start: Int32 = Int32(1)) -> Int32:
314
+ result: Int32 = start
315
+ for x in iterable:
316
+ result = result * x
317
+ return result
318
+
319
+ @overload
320
+ def prod(iterable: Iterable[int], *, start: int = 1) -> int:
321
+ result: int = start
322
+ for x in iterable:
323
+ result = result * x
324
+ return result
325
+
326
+ @overload
327
+ def prod(iterable: Iterable[float], *, start: float = 1.0) -> float:
328
+ result: float = start
329
+ for x in iterable:
330
+ result = result * x
331
+ return result
332
+
333
+ def fsum(iterable: Iterable[float]) -> float:
334
+ # Neumaier summation: more accurate than naive + compensated for large swings.
335
+ s: float = 0.0
336
+ c: float = 0.0
337
+ for x in iterable:
338
+ t: float = s + x
339
+ if fabs(s) >= fabs(x):
340
+ c = c + ((s - t) + x)
341
+ else:
342
+ c = c + ((x - t) + s)
343
+ s = t
344
+ return s + c
345
+
346
+ def sumprod(p: Iterable[float], q: Iterable[float]) -> float:
347
+ # Manual two-iterator drive with length-mismatch detection; CPython uses
348
+ # zip(p, q, strict=True) internally. We don't have strict=True yet, so
349
+ # open-code it.
350
+ s: float = 0.0
351
+ ip = iter(p)
352
+ iq = iter(q)
353
+ while True:
354
+ try:
355
+ a = next(ip)
356
+ except StopIteration:
357
+ try:
358
+ next(iq)
359
+ except StopIteration:
360
+ return s
361
+ raise ValueError("sumprod(): input lengths differ")
362
+ try:
363
+ b = next(iq)
364
+ except StopIteration:
365
+ raise ValueError("sumprod(): input lengths differ")
366
+ s = s + a * b
367
+
368
+ def dist(p: Iterable[float], q: Iterable[float]) -> float:
369
+ # Fold via hypot to avoid overflow when coordinates are large: the naive
370
+ # sqrt(sum((pi - qi)**2)) overflows when any (pi - qi)**2 exceeds DBL_MAX.
371
+ # std::hypot(a, b) is IEEE overflow-safe, and hypot-folding is
372
+ # mathematically equivalent: hypot(hypot(d0, d1), d2) == sqrt(d0^2 + d1^2 + d2^2).
373
+ ip = iter(p)
374
+ iq = iter(q)
375
+ # Seed with first pair (or return 0.0 for empty inputs).
376
+ try:
377
+ p0 = next(ip)
378
+ except StopIteration:
379
+ try:
380
+ next(iq)
381
+ except StopIteration:
382
+ return 0.0
383
+ raise ValueError("dist(): input lengths differ")
384
+ try:
385
+ q0 = next(iq)
386
+ except StopIteration:
387
+ raise ValueError("dist(): input lengths differ")
388
+ result: float = fabs(p0 - q0)
389
+ while True:
390
+ try:
391
+ pi = next(ip)
392
+ except StopIteration:
393
+ try:
394
+ next(iq)
395
+ except StopIteration:
396
+ return result
397
+ raise ValueError("dist(): input lengths differ")
398
+ try:
399
+ qi = next(iq)
400
+ except StopIteration:
401
+ raise ValueError("dist(): input lengths differ")
402
+ result = _hypot2(result, pi - qi)
403
+
404
+ @type_param_default(T=DefaultInt)
405
+ @cpp_template("::tpy::from_float_check<{T}>({0})")
406
+ def trunc[T](x: float) -> T: ...