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.
- tpy_lang-0.3.0.dev0.dist-info/METADATA +151 -0
- tpy_lang-0.3.0.dev0.dist-info/RECORD +333 -0
- tpy_lang-0.3.0.dev0.dist-info/WHEEL +4 -0
- tpy_lang-0.3.0.dev0.dist-info/entry_points.txt +3 -0
- tpyc/__init__.py +104 -0
- tpyc/__main__.py +6 -0
- tpyc/_buildinfo.py +1 -0
- tpyc/_data/docs/LANGUAGE_FEATURES.md +6278 -0
- tpyc/_data/docs/STDLIB_ROADMAP.md +1258 -0
- tpyc/_data/docs/TPY_FOR_AGENTS.md +556 -0
- tpyc/_data/lib/tpy/_bindings/__init__.py +6 -0
- tpyc/_data/lib/tpy/_bindings/pcre2.py +173 -0
- tpyc/_data/lib/tpy/_bindings/posix_socket.py +161 -0
- tpyc/_data/lib/tpy/_functools_macros.py +80 -0
- tpyc/_data/lib/tpy/_macro_helpers.py +161 -0
- tpyc/_data/lib/tpy/argparse.py +2062 -0
- tpyc/_data/lib/tpy/asyncio/__init__.py +744 -0
- tpyc/_data/lib/tpy/asyncio/_executor.py +515 -0
- tpyc/_data/lib/tpy/base64.py +410 -0
- tpyc/_data/lib/tpy/bisect.py +39 -0
- tpyc/_data/lib/tpy/builtins.py +38 -0
- tpyc/_data/lib/tpy/dataclasses.py +354 -0
- tpyc/_data/lib/tpy/enum.py +23 -0
- tpyc/_data/lib/tpy/functools.py +33 -0
- tpyc/_data/lib/tpy/hashlib.py +206 -0
- tpyc/_data/lib/tpy/heapq.py +118 -0
- tpyc/_data/lib/tpy/io.py +395 -0
- tpyc/_data/lib/tpy/json.py +221 -0
- tpyc/_data/lib/tpy/math.py +406 -0
- tpyc/_data/lib/tpy/random.py +597 -0
- tpyc/_data/lib/tpy/re.py +467 -0
- tpyc/_data/lib/tpy/socket.py +379 -0
- tpyc/_data/lib/tpy/struct.py +178 -0
- tpyc/_data/lib/tpy/sys.py +40 -0
- tpyc/_data/lib/tpy/time.py +39 -0
- tpyc/_data/lib/tpy/tpy/__init__.py +78 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/__init__.py +10 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_decorators.py +37 -0
- tpyc/_data/lib/tpy/tpy/_bootstrap/_extern.py +64 -0
- tpyc/_data/lib/tpy/tpy/_builtins/__init__.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_bytes.py +378 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_dict.py +151 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_exceptions.py +125 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_funcs.py +681 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_io.py +97 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_list.py +127 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_range.py +52 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_set.py +139 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_super.py +11 -0
- tpyc/_data/lib/tpy/tpy/_builtins/_types.py +661 -0
- tpyc/_data/lib/tpy/tpy/_core/__init__.py +23 -0
- tpyc/_data/lib/tpy/tpy/_core/_bytes_view.py +129 -0
- tpyc/_data/lib/tpy/tpy/_core/_containers.py +137 -0
- tpyc/_data/lib/tpy/tpy/_core/_functions.py +40 -0
- tpyc/_data/lib/tpy/tpy/_core/_types.py +2061 -0
- tpyc/_data/lib/tpy/tpy/_typing/__init__.py +77 -0
- tpyc/_data/lib/tpy/tpy/_version.py +29 -0
- tpyc/_data/lib/tpy/tpy/bits.py +28 -0
- tpyc/_data/lib/tpy/tpy/coro/__init__.py +127 -0
- tpyc/_data/lib/tpy/tpy/extern.py +8 -0
- tpyc/_data/lib/tpy/tpy/mem.py +49 -0
- tpyc/_data/lib/tpy/tpy/unsafe.py +195 -0
- tpyc/_data/lib/tpy/tpy/version.py +21 -0
- tpyc/_data/lib/tpy/typing.py +13 -0
- tpyc/_data/runtime/cpp/include/tpy/any.hpp +461 -0
- tpyc/_data/runtime/cpp/include/tpy/as_ostream.hpp +117 -0
- tpyc/_data/runtime/cpp/include/tpy/async.hpp +76 -0
- tpyc/_data/runtime/cpp/include/tpy/bigint.hpp +1343 -0
- tpyc/_data/runtime/cpp/include/tpy/builtins.hpp +400 -0
- tpyc/_data/runtime/cpp/include/tpy/bytes_ops.hpp +469 -0
- tpyc/_data/runtime/cpp/include/tpy/container_ops.hpp +487 -0
- tpyc/_data/runtime/cpp/include/tpy/copy_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/core.hpp +558 -0
- tpyc/_data/runtime/cpp/include/tpy/dict_ops.hpp +289 -0
- tpyc/_data/runtime/cpp/include/tpy/dunder.hpp +750 -0
- tpyc/_data/runtime/cpp/include/tpy/dynamic.hpp +44 -0
- tpyc/_data/runtime/cpp/include/tpy/enum.hpp +40 -0
- tpyc/_data/runtime/cpp/include/tpy/file.hpp +245 -0
- tpyc/_data/runtime/cpp/include/tpy/fixed_int.hpp +317 -0
- tpyc/_data/runtime/cpp/include/tpy/format.hpp +954 -0
- tpyc/_data/runtime/cpp/include/tpy/frame_slot.hpp +120 -0
- tpyc/_data/runtime/cpp/include/tpy/generator.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/iterable_ops.hpp +122 -0
- tpyc/_data/runtime/cpp/include/tpy/itertools.hpp +749 -0
- tpyc/_data/runtime/cpp/include/tpy/next_iter.hpp +82 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_map.hpp +518 -0
- tpyc/_data/runtime/cpp/include/tpy/ordered_set.hpp +337 -0
- tpyc/_data/runtime/cpp/include/tpy/own_iter.hpp +54 -0
- tpyc/_data/runtime/cpp/include/tpy/pascal_graph_sdl.hpp +192 -0
- tpyc/_data/runtime/cpp/include/tpy/printing.hpp +302 -0
- tpyc/_data/runtime/cpp/include/tpy/protocols.hpp +61 -0
- tpyc/_data/runtime/cpp/include/tpy/range.hpp +115 -0
- tpyc/_data/runtime/cpp/include/tpy/ranges.hpp +212 -0
- tpyc/_data/runtime/cpp/include/tpy/set_ops.hpp +265 -0
- tpyc/_data/runtime/cpp/include/tpy/slice.hpp +47 -0
- tpyc/_data/runtime/cpp/include/tpy/span_iter.hpp +42 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/math.hpp +41 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/pcre2_h.hpp +96 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/random.hpp +25 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/socket_h.hpp +145 -0
- tpyc/_data/runtime/cpp/include/tpy/stdlib/time.hpp +62 -0
- tpyc/_data/runtime/cpp/include/tpy/system.hpp +121 -0
- tpyc/_data/runtime/cpp/include/tpy/throwable.hpp +55 -0
- tpyc/_data/runtime/cpp/include/tpy/tpy.hpp +156 -0
- tpyc/_data/runtime/cpp/include/tpy/type_name.hpp +77 -0
- tpyc/_data/runtime/cpp/include/tpy/type_traits.hpp +240 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_array_storage.hpp +250 -0
- tpyc/_data/runtime/cpp/include/tpy/uninit_heap_storage.hpp +277 -0
- tpyc/_data/runtime/cpp/include/tpy/varargs.hpp +174 -0
- tpyc/_data/runtime/cpp/include/tpy/variant_ref.hpp +118 -0
- tpyc/_data/runtime/cpp/src/stdlib/socket_impl.cpp +104 -0
- tpyc/_data/runtime/cpp/third_party/README.md +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/AUTHORS +36 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/CMakeLists.txt +1233 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/COPYING +5 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/ChangeLog +3097 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/HACKING +853 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/INSTALL +368 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/LICENCE +94 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NEWS +492 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/NON-AUTOTOOLS-BUILD +430 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/README +956 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/COPYING-CMAKE-SCRIPTS +22 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindEditline.cmake +16 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindPackageHandleStandardArgs.cmake +58 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/FindReadline.cmake +29 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config-version.cmake.in +15 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/cmake/pcre2-config.cmake.in +148 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/config-cmake.h.in +56 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-16.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-32.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-8.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/libpcre2-posix.pc.in +13 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/pcre2-config.in +121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.generic +483 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/config.h.in +460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.generic +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2.h.in +1010 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_auto_possess.c +1371 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chartables.c.dist +196 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_chkdint.c +96 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_compile.c +11001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_config.c +252 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_context.c +510 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_convert.c +1189 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dfa_match.c +4119 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_dftables.c +297 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_error.c +345 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_extuni.c +162 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_find_bracket.c +219 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_fuzzsupport.c +792 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_internal.h +2084 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_intmodedep.h +940 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_compile.c +14972 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_match.c +200 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_misc.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_neon_inc.h +354 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_simd_inc.h +2355 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_jit_test.c +2528 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_maketables.c +165 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match.c +7777 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_match_data.c +185 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_newline.c +243 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ord2utf.c +120 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_pattern_info.c +432 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_printint.c +886 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_script_run.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_serialize.c +286 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_string_utils.c +237 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_study.c +1915 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substitute.c +1009 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_substring.c +550 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_tables.c +234 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucd.c +5460 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucp.h +396 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_ucptables.c +1533 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_valid_utf.c +398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2_xclass.c +308 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2demo.c +497 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2grep.c +4606 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.c +425 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix.h +187 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2posix_test.c +209 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/pcre2test.c +9708 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorApple.c +137 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorCore.c +327 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorFreeBSD.c +89 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorPosix.c +62 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitExecAllocatorWindows.c +40 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorNetBSD.c +72 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitProtExecAllocatorPosix.c +172 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorPosix.c +141 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/allocator_src/sljitWXExecAllocatorWindows.c +102 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfig.h +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigCPU.h +188 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitConfigInternal.h +907 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.c +3561 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitLir.h +2466 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_32.c +4636 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_64.c +3491 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeARM_T2_32.c +4302 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeLOONGARCH_64.c +3765 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_32.c +472 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_64.c +387 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeMIPS_common.c +4259 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_32.c +485 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_64.c +719 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativePPC_common.c +3161 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_32.c +142 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_64.c +222 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeRISCV_common.c +3121 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeS390X.c +4526 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_32.c +1685 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_64.c +1398 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitNativeX86_common.c +5001 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitSerialize.c +516 -0
- tpyc/_data/runtime/cpp/third_party/pcre2/src/sljit/sljitUtils.c +344 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.sources.txt +54 -0
- tpyc/_data/runtime/cpp/third_party/pcre2.vendor.json +7 -0
- tpyc/build/__init__.py +7 -0
- tpyc/build/pcre2.py +122 -0
- tpyc/build/third_party.py +413 -0
- tpyc/cli.py +822 -0
- tpyc/codegen_cpp/__init__.py +18 -0
- tpyc/codegen_cpp/builtins.py +484 -0
- tpyc/codegen_cpp/context.py +2064 -0
- tpyc/codegen_cpp/expressions.py +5940 -0
- tpyc/codegen_cpp/functions.py +1913 -0
- tpyc/codegen_cpp/gen_async.py +3258 -0
- tpyc/codegen_cpp/gen_generators.py +657 -0
- tpyc/codegen_cpp/generator.py +2258 -0
- tpyc/codegen_cpp/match.py +1997 -0
- tpyc/codegen_cpp/param_const.py +172 -0
- tpyc/codegen_cpp/protocols.py +907 -0
- tpyc/codegen_cpp/records.py +1654 -0
- tpyc/codegen_cpp/resumable_cfg.py +1651 -0
- tpyc/codegen_cpp/statements.py +4963 -0
- tpyc/codegen_cpp/string_dispatch.py +76 -0
- tpyc/codegen_cpp/test_context.py +46 -0
- tpyc/codegen_cpp/test_param_const.py +113 -0
- tpyc/codegen_cpp/test_resumable_cfg.py +182 -0
- tpyc/codegen_cpp/type_resolution.py +53 -0
- tpyc/codegen_cpp/types.py +436 -0
- tpyc/codegen_cpp/variant_access.py +135 -0
- tpyc/coercions.py +749 -0
- tpyc/compilation_context.py +57 -0
- tpyc/compiler.py +3945 -0
- tpyc/cycle_detection.py +358 -0
- tpyc/diagnostics.py +135 -0
- tpyc/dump_types.py +353 -0
- tpyc/frontend_diagnostics.py +47 -0
- tpyc/frontend_ir/__init__.py +140 -0
- tpyc/frontend_ir/lower.py +1098 -0
- tpyc/frontend_ir/nodes.py +718 -0
- tpyc/frontend_ir/resolver_adapter.py +151 -0
- tpyc/frontend_plugin.py +209 -0
- tpyc/install_docs.py +81 -0
- tpyc/liveness.py +756 -0
- tpyc/macro_api.py +1724 -0
- tpyc/macro_loader.py +497 -0
- tpyc/module_names.py +64 -0
- tpyc/modules/__init__.py +31 -0
- tpyc/modules/defs.py +89 -0
- tpyc/modules/registry.py +36 -0
- tpyc/modules/resolver.py +192 -0
- tpyc/modules/type_resolution.py +629 -0
- tpyc/namespace.py +172 -0
- tpyc/parse/__init__.py +84 -0
- tpyc/parse/imports.py +490 -0
- tpyc/parse/nodes.py +1732 -0
- tpyc/parse/parser.py +4043 -0
- tpyc/parse/resolve_refs.py +466 -0
- tpyc/parse/type_resolver.py +1060 -0
- tpyc/prescan.py +254 -0
- tpyc/qnames.py +149 -0
- tpyc/repl.py +529 -0
- tpyc/repl_backends.py +848 -0
- tpyc/sema/__init__.py +21 -0
- tpyc/sema/analyzer.py +3625 -0
- tpyc/sema/bound_check.py +72 -0
- tpyc/sema/builder_trace.py +684 -0
- tpyc/sema/calls.py +5406 -0
- tpyc/sema/compatibility.py +2107 -0
- tpyc/sema/context.py +1243 -0
- tpyc/sema/expressions.py +3737 -0
- tpyc/sema/flow_facts.py +199 -0
- tpyc/sema/init_tracker.py +150 -0
- tpyc/sema/list_literals.py +69 -0
- tpyc/sema/literal_utils.py +27 -0
- tpyc/sema/local_deduction.py +1088 -0
- tpyc/sema/macros.py +179 -0
- tpyc/sema/match.py +1177 -0
- tpyc/sema/method_expansion.py +347 -0
- tpyc/sema/methods.py +2197 -0
- tpyc/sema/mutation_propagation.py +268 -0
- tpyc/sema/narrowing.py +857 -0
- tpyc/sema/numeric_lattice.py +160 -0
- tpyc/sema/operators.py +402 -0
- tpyc/sema/overloads.py +841 -0
- tpyc/sema/protocols.py +1209 -0
- tpyc/sema/reach_analysis.py +202 -0
- tpyc/sema/registration.py +3156 -0
- tpyc/sema/scope_tracker.py +193 -0
- tpyc/sema/statements.py +4426 -0
- tpyc/sema/type_ops.py +1879 -0
- tpyc/sema/value_range.py +181 -0
- tpyc/symbol_binding.py +259 -0
- tpyc/test_c3_mro.py +208 -0
- tpyc/test_cli_argv.py +52 -0
- tpyc/test_compiler.py +559 -0
- tpyc/test_contains_type_param.py +101 -0
- tpyc/test_cycle_detection.py +221 -0
- tpyc/test_dump_types.py +225 -0
- tpyc/test_install_docs.py +65 -0
- tpyc/test_local_cpp_form.py +135 -0
- tpyc/test_macro_loader.py +76 -0
- tpyc/test_method_expansion.py +254 -0
- tpyc/test_nominal_identity.py +182 -0
- tpyc/test_overloads.py +410 -0
- tpyc/test_parse.py +303 -0
- tpyc/test_parse_type_ref.py +506 -0
- tpyc/test_parse_version_info.py +58 -0
- tpyc/test_reach_analysis.py +72 -0
- tpyc/test_ref_type.py +216 -0
- tpyc/test_send_sync_substitution.py +276 -0
- tpyc/test_tuple_mutation_propagation.py +206 -0
- tpyc/test_type_def_registry.py +1729 -0
- tpyc/test_union_types.py +195 -0
- tpyc/type_def_registry.py +975 -0
- tpyc/typesys.py +5104 -0
tpyc/test_overloads.py
ADDED
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
"""Unit tests for tier-ranked overload resolution helpers.
|
|
2
|
+
|
|
3
|
+
Covers the pure building blocks in ``tpyc.sema.overloads`` that don't
|
|
4
|
+
need a full ``SemanticContext``:
|
|
5
|
+
|
|
6
|
+
* ``MatchTier`` ordering (the invariant that drives ranking).
|
|
7
|
+
* ``_scalar_widening_cost`` / ``_type_args_widening_cost`` (cost model).
|
|
8
|
+
* ``_score`` (aggregate ranking key).
|
|
9
|
+
* ``_classify_strict_match`` for non-protocol shapes.
|
|
10
|
+
* ``_bool_checker_to_classifier`` adapter semantics.
|
|
11
|
+
* ``OverloadAmbiguityError`` payload.
|
|
12
|
+
|
|
13
|
+
End-to-end overload dispatch is covered by the snippet tests under
|
|
14
|
+
``tests/cases/``; this file locks down the algebra they depend on.
|
|
15
|
+
"""
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import pytest
|
|
19
|
+
|
|
20
|
+
from tpyc.sema.overloads import (
|
|
21
|
+
MatchTier,
|
|
22
|
+
OverloadAmbiguityError,
|
|
23
|
+
_bool_checker_to_classifier,
|
|
24
|
+
_classify_strict_match,
|
|
25
|
+
_scalar_widening_cost,
|
|
26
|
+
_score,
|
|
27
|
+
_type_args_widening_cost,
|
|
28
|
+
)
|
|
29
|
+
from tpyc.sema.protocols import ProtocolConformanceKind
|
|
30
|
+
from tpyc.typesys import (
|
|
31
|
+
BIGINT,
|
|
32
|
+
BOOL,
|
|
33
|
+
CHAR,
|
|
34
|
+
FLOAT,
|
|
35
|
+
FLOAT32,
|
|
36
|
+
INT8,
|
|
37
|
+
INT16,
|
|
38
|
+
INT32,
|
|
39
|
+
INT64,
|
|
40
|
+
NONE,
|
|
41
|
+
NominalType,
|
|
42
|
+
PendingListType,
|
|
43
|
+
STR,
|
|
44
|
+
TupleType,
|
|
45
|
+
UINT8,
|
|
46
|
+
UINT32,
|
|
47
|
+
UINT64,
|
|
48
|
+
UNKNOWN_ELEMENT,
|
|
49
|
+
VOID,
|
|
50
|
+
IntLiteralType,
|
|
51
|
+
OptionalType,
|
|
52
|
+
TypeParamRef,
|
|
53
|
+
FunctionInfo,
|
|
54
|
+
ParamInfo,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
# --------------------------------------------------------------------------
|
|
59
|
+
# MatchTier ordering
|
|
60
|
+
# --------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_match_tier_is_total_ordered_lowest_most_specific():
|
|
64
|
+
# Declaration order must match increasing .value so that the counts-array
|
|
65
|
+
# index lines up with the "lower is more specific" ranking.
|
|
66
|
+
tiers = [
|
|
67
|
+
MatchTier.EXACT_CONCRETE,
|
|
68
|
+
MatchTier.EXACT_GENERIC_SHAPE,
|
|
69
|
+
MatchTier.PROTOCOL_EXPLICIT,
|
|
70
|
+
MatchTier.PROTOCOL_STRUCTURAL,
|
|
71
|
+
MatchTier.GENERIC_PROTOCOL_EXPLICIT,
|
|
72
|
+
MatchTier.GENERIC_PROTOCOL_STRUCTURAL,
|
|
73
|
+
MatchTier.GENERIC_WILDCARD,
|
|
74
|
+
]
|
|
75
|
+
values = [t.value for t in tiers]
|
|
76
|
+
assert values == sorted(values)
|
|
77
|
+
assert all(a < b for a, b in zip(values, values[1:]))
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_match_tier_values_start_at_one():
|
|
81
|
+
# Score vector is 1-indexed; if this ever changes the _score helper
|
|
82
|
+
# must be reconciled with the new base.
|
|
83
|
+
assert MatchTier.EXACT_CONCRETE.value == 1
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# --------------------------------------------------------------------------
|
|
87
|
+
# _scalar_widening_cost
|
|
88
|
+
# --------------------------------------------------------------------------
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_scalar_widening_cost_equal_zero():
|
|
92
|
+
assert _scalar_widening_cost(INT32, INT32) == 0
|
|
93
|
+
assert _scalar_widening_cost(FLOAT, FLOAT) == 0
|
|
94
|
+
assert _scalar_widening_cost(STR, STR) == 0
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_scalar_widening_cost_int_to_wider_int_uses_bit_gap():
|
|
98
|
+
# bit gap / 8: Int32 -> Int64 = (64-32)/8 = 4
|
|
99
|
+
assert _scalar_widening_cost(INT32, INT64) == 4
|
|
100
|
+
# Int16 -> Int32 = (32-16)/8 = 2
|
|
101
|
+
assert _scalar_widening_cost(INT16, INT32) == 2
|
|
102
|
+
# Int8 -> Int64 = 7; max(1, 7) + 0 sign penalty
|
|
103
|
+
assert _scalar_widening_cost(INT8, INT64) == 7
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_scalar_widening_cost_cross_sign_adds_penalty():
|
|
107
|
+
# Int32 -> UInt32: gap 0, sign penalty 1, max(1, 0)+1 = 2.
|
|
108
|
+
assert _scalar_widening_cost(INT32, UINT32) == 2
|
|
109
|
+
# Int32 -> UInt64: gap 4, sign penalty 1 -> 5.
|
|
110
|
+
assert _scalar_widening_cost(INT32, UINT64) == 5
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def test_scalar_widening_cost_same_width_same_sign_is_minimum_one():
|
|
114
|
+
# Different types with identical traits (bits+signedness) shouldn't
|
|
115
|
+
# free-ride to 0 just because neither wider nor signed-different; the
|
|
116
|
+
# max(1, gap) clamp ensures a positive cost.
|
|
117
|
+
assert _scalar_widening_cost(INT8, UINT8) == 2 # sign flip only
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def test_scalar_widening_cost_fixed_to_bigint():
|
|
121
|
+
assert _scalar_widening_cost(INT32, BIGINT) == 8
|
|
122
|
+
assert _scalar_widening_cost(INT64, BIGINT) == 8
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_scalar_widening_cost_fixed_to_float_is_highest():
|
|
126
|
+
# Float lives at a different semantic level; the higher cost reflects
|
|
127
|
+
# that int-literal calls should prefer an int overload over a float one.
|
|
128
|
+
assert _scalar_widening_cost(INT32, FLOAT) == 16
|
|
129
|
+
assert _scalar_widening_cost(INT64, FLOAT32) == 16
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def test_scalar_widening_cost_float_to_float_widening():
|
|
133
|
+
# Float32 -> float (f64): generic "1" since both are floats.
|
|
134
|
+
assert _scalar_widening_cost(FLOAT32, FLOAT) == 1
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_scalar_widening_cost_int_literal_with_default_zero_cost():
|
|
138
|
+
il = IntLiteralType(value=1)
|
|
139
|
+
assert _scalar_widening_cost(il, INT32, default_int_type=INT32) == 0
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def test_scalar_widening_cost_int_literal_uses_default_as_proxy():
|
|
143
|
+
il = IntLiteralType(value=1)
|
|
144
|
+
# IntLiteral -> Int64 under default=Int32 scores like Int32 -> Int64.
|
|
145
|
+
assert _scalar_widening_cost(il, INT64, default_int_type=INT32) == 4
|
|
146
|
+
assert _scalar_widening_cost(il, BIGINT, default_int_type=INT32) == 8
|
|
147
|
+
assert _scalar_widening_cost(il, FLOAT, default_int_type=INT32) == 16
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_scalar_widening_cost_int_literal_without_default_is_generic():
|
|
151
|
+
il = IntLiteralType(value=1)
|
|
152
|
+
assert _scalar_widening_cost(il, INT32) == 1
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_scalar_widening_cost_unknown_element_biases_to_default_int():
|
|
156
|
+
# Empty-list element type. Matches CPython's ``sum([]) == 0`` policy.
|
|
157
|
+
assert _scalar_widening_cost(UNKNOWN_ELEMENT, INT32, default_int_type=INT32) == 0
|
|
158
|
+
assert _scalar_widening_cost(UNKNOWN_ELEMENT, INT64, default_int_type=INT32) == 4
|
|
159
|
+
assert _scalar_widening_cost(UNKNOWN_ELEMENT, FLOAT, default_int_type=INT32) == 16
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def test_scalar_widening_cost_unknown_shape_falls_back_to_one():
|
|
163
|
+
# Cost of "I can't tell" is conservative, not 0.
|
|
164
|
+
assert _scalar_widening_cost(STR, CHAR) == 1
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# --------------------------------------------------------------------------
|
|
168
|
+
# _type_args_widening_cost
|
|
169
|
+
# --------------------------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def _list(elem):
|
|
173
|
+
return NominalType("list", (elem,), _module_qname="builtins.list")
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def _iterable(elem):
|
|
177
|
+
return NominalType("Iterable", (elem,), is_protocol=True, _module_qname="tpy.Iterable")
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def test_type_args_cost_matching_element_is_zero():
|
|
181
|
+
assert _type_args_widening_cost(_list(INT32), _iterable(INT32)) == 0
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def test_type_args_cost_widening_element_is_positive():
|
|
185
|
+
assert _type_args_widening_cost(_list(INT32), _iterable(INT64)) == 4
|
|
186
|
+
assert _type_args_widening_cost(_list(INT32), _iterable(BIGINT)) == 8
|
|
187
|
+
assert _type_args_widening_cost(_list(INT32), _iterable(FLOAT)) == 16
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def test_type_args_cost_pending_list_uses_element_type():
|
|
191
|
+
pl = PendingListType(element_type=IntLiteralType(value=1), size=0, literal_id=0)
|
|
192
|
+
# PendingListType.get_element_type() returns element_type, which flows
|
|
193
|
+
# through the single-element fallback.
|
|
194
|
+
assert _type_args_widening_cost(pl, _iterable(INT32), default_int_type=INT32) == 0
|
|
195
|
+
assert _type_args_widening_cost(pl, _iterable(INT64), default_int_type=INT32) == 4
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def test_type_args_cost_empty_pending_list_biases_to_default_int():
|
|
199
|
+
pl = PendingListType(element_type=UNKNOWN_ELEMENT, size=0, literal_id=0)
|
|
200
|
+
assert _type_args_widening_cost(pl, _iterable(INT32), default_int_type=INT32) == 0
|
|
201
|
+
assert _type_args_widening_cost(pl, _iterable(INT64), default_int_type=INT32) == 4
|
|
202
|
+
assert _type_args_widening_cost(pl, _iterable(FLOAT), default_int_type=INT32) == 16
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def test_type_args_cost_tuple_all_same_uses_that_element():
|
|
206
|
+
t = TupleType((INT32, INT32, INT32))
|
|
207
|
+
assert _type_args_widening_cost(t, _iterable(INT32)) == 0
|
|
208
|
+
assert _type_args_widening_cost(t, _iterable(INT64)) == 4
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
def test_type_args_cost_tuple_mixed_elements_returns_zero():
|
|
212
|
+
# Mixed-element tuples have no well-defined "the element type"; the
|
|
213
|
+
# cost model gives up rather than pick arbitrarily.
|
|
214
|
+
t = TupleType((INT32, FLOAT))
|
|
215
|
+
assert _type_args_widening_cost(t, _iterable(INT32)) == 0
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def test_type_args_cost_mismatched_arity_returns_zero():
|
|
219
|
+
# dict[K, V] vs Sequence[T] -- the cost model only scores when shapes
|
|
220
|
+
# align. Downstream relies on the protocol match itself filtering.
|
|
221
|
+
pair = NominalType("dict", (INT32, STR), _module_qname="builtins.dict")
|
|
222
|
+
seq = NominalType("Sequence", (INT32,), is_protocol=True, _module_qname="tpy.Sequence")
|
|
223
|
+
assert _type_args_widening_cost(pair, seq) == 0
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def test_type_args_cost_empty_protocol_type_args_zero():
|
|
227
|
+
marker = NominalType("Sized", (), is_protocol=True, _module_qname="tpy.Sized")
|
|
228
|
+
assert _type_args_widening_cost(_list(INT32), marker) == 0
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
# --------------------------------------------------------------------------
|
|
232
|
+
# _score
|
|
233
|
+
# --------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def test_score_higher_tier_count_wins_primary_key():
|
|
237
|
+
exact = ((MatchTier.EXACT_CONCRETE, 0),)
|
|
238
|
+
structural = ((MatchTier.PROTOCOL_STRUCTURAL, 0),)
|
|
239
|
+
# Ascending sort on score: exact must come first.
|
|
240
|
+
assert _score(exact) < _score(structural)
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
def test_score_mixed_tier_vector_orders_by_counts_lex():
|
|
244
|
+
# A = (exact, structural), B = (structural, structural).
|
|
245
|
+
# A has 1 EXACT_CONCRETE count > B's 0. A wins primary.
|
|
246
|
+
a = ((MatchTier.EXACT_CONCRETE, 0), (MatchTier.PROTOCOL_STRUCTURAL, 0))
|
|
247
|
+
b = ((MatchTier.PROTOCOL_STRUCTURAL, 0), (MatchTier.PROTOCOL_STRUCTURAL, 0))
|
|
248
|
+
assert _score(a) < _score(b)
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def test_score_secondary_key_is_total_widening_cost():
|
|
252
|
+
a = ((MatchTier.PROTOCOL_EXPLICIT, 0),)
|
|
253
|
+
b = ((MatchTier.PROTOCOL_EXPLICIT, 4),)
|
|
254
|
+
# Same primary key, smaller total cost wins.
|
|
255
|
+
assert _score(a) < _score(b)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
def test_score_primary_beats_secondary():
|
|
259
|
+
# Structural with cost=0 still loses to Explicit with cost=100 because
|
|
260
|
+
# primary key (tier counts) dominates.
|
|
261
|
+
explicit_expensive = ((MatchTier.PROTOCOL_EXPLICIT, 100),)
|
|
262
|
+
structural_cheap = ((MatchTier.PROTOCOL_STRUCTURAL, 0),)
|
|
263
|
+
assert _score(explicit_expensive) < _score(structural_cheap)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
def test_score_exact_generic_shape_beats_protocol_explicit():
|
|
267
|
+
# Key invariant for concrete-vs-generic dispatch.
|
|
268
|
+
generic_shape = ((MatchTier.EXACT_GENERIC_SHAPE, 0),)
|
|
269
|
+
protocol = ((MatchTier.PROTOCOL_EXPLICIT, 0),)
|
|
270
|
+
assert _score(generic_shape) < _score(protocol)
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def test_score_concrete_beats_generic_protocol():
|
|
274
|
+
concrete = ((MatchTier.PROTOCOL_EXPLICIT, 0),)
|
|
275
|
+
generic = ((MatchTier.GENERIC_PROTOCOL_EXPLICIT, 0),)
|
|
276
|
+
assert _score(concrete) < _score(generic)
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def test_score_equal_inputs_equal_outputs():
|
|
280
|
+
a = ((MatchTier.PROTOCOL_EXPLICIT, 2), (MatchTier.EXACT_CONCRETE, 0))
|
|
281
|
+
b = ((MatchTier.EXACT_CONCRETE, 0), (MatchTier.PROTOCOL_EXPLICIT, 2))
|
|
282
|
+
# Aggregate counts + total cost are equal; score is too (matches the
|
|
283
|
+
# dedup-then-ambiguity semantics in resolve_overload).
|
|
284
|
+
assert _score(a) == _score(b)
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# --------------------------------------------------------------------------
|
|
288
|
+
# _classify_strict_match (non-protocol paths; protocol paths require a
|
|
289
|
+
# classifier callable and are exercised end-to-end via snippet tests)
|
|
290
|
+
# --------------------------------------------------------------------------
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def test_classify_strict_exact_concrete_match():
|
|
294
|
+
assert _classify_strict_match(INT32, INT32) == (MatchTier.EXACT_CONCRETE, 0)
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
def test_classify_strict_no_match_returns_none():
|
|
298
|
+
assert _classify_strict_match(INT32, FLOAT) is None
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
def test_classify_strict_int_literal_fits_fixed_int():
|
|
302
|
+
il = IntLiteralType(value=1)
|
|
303
|
+
# Cost 0 for exact-default match, larger for narrower/wider widths so
|
|
304
|
+
# str(IntLiteralType) picks the int32_t overload over int8_t.
|
|
305
|
+
assert _classify_strict_match(il, INT32, default_int_type=INT32) == (MatchTier.EXACT_CONCRETE, 0)
|
|
306
|
+
int8_cost = _classify_strict_match(il, INT8, default_int_type=INT32)
|
|
307
|
+
assert int8_cost is not None and int8_cost[0] == MatchTier.EXACT_CONCRETE and int8_cost[1] > 0
|
|
308
|
+
# Value out of range for Int8 -> not a match.
|
|
309
|
+
big = IntLiteralType(value=1000)
|
|
310
|
+
assert _classify_strict_match(big, INT8) is None
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def test_classify_strict_int_literal_unknown_value_matches_any_fixed_int():
|
|
314
|
+
# value=None: compiler can't range-check, accept.
|
|
315
|
+
il = IntLiteralType(value=None)
|
|
316
|
+
assert _classify_strict_match(il, INT8, default_int_type=INT32) == (MatchTier.EXACT_CONCRETE, 1)
|
|
317
|
+
assert _classify_strict_match(il, INT32, default_int_type=INT32) == (MatchTier.EXACT_CONCRETE, 0)
|
|
318
|
+
assert _classify_strict_match(il, UINT64, default_int_type=INT32)[0] == MatchTier.EXACT_CONCRETE
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
def test_classify_strict_none_matches_void():
|
|
322
|
+
assert _classify_strict_match(NONE, VOID) == (MatchTier.EXACT_CONCRETE, 0)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
def test_classify_strict_optional_unwrap_delegates():
|
|
326
|
+
opt = OptionalType(INT32)
|
|
327
|
+
# None -> Optional[T].
|
|
328
|
+
assert _classify_strict_match(NONE, opt) == (MatchTier.EXACT_CONCRETE, 0)
|
|
329
|
+
# T -> Optional[T] via recursion.
|
|
330
|
+
assert _classify_strict_match(INT32, opt) == (MatchTier.EXACT_CONCRETE, 0)
|
|
331
|
+
# Mismatch inside Optional also propagates.
|
|
332
|
+
assert _classify_strict_match(FLOAT, opt) is None
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def test_classify_strict_protocol_classifies_explicit_via_classifier():
|
|
336
|
+
def cls(a, p):
|
|
337
|
+
return ProtocolConformanceKind.EXPLICIT
|
|
338
|
+
proto = NominalType("Iterable", (INT32,), is_protocol=True, _module_qname="tpy.Iterable")
|
|
339
|
+
tier, _ = _classify_strict_match(_list(INT32), proto, cls)
|
|
340
|
+
assert tier == MatchTier.PROTOCOL_EXPLICIT
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
def test_classify_strict_protocol_classifies_structural_via_classifier():
|
|
344
|
+
def cls(a, p):
|
|
345
|
+
return ProtocolConformanceKind.STRUCTURAL
|
|
346
|
+
proto = NominalType("Iterable", (INT32,), is_protocol=True, _module_qname="tpy.Iterable")
|
|
347
|
+
tier, cost = _classify_strict_match(_list(INT32), proto, cls)
|
|
348
|
+
assert tier == MatchTier.PROTOCOL_STRUCTURAL
|
|
349
|
+
# Structural is opaque: widening info is not computed.
|
|
350
|
+
assert cost == 0
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def test_classify_strict_protocol_no_match_without_classifier():
|
|
354
|
+
# Protocol param with no classifier callable -> can't confirm
|
|
355
|
+
# conformance, no match.
|
|
356
|
+
proto = NominalType("Iterable", (INT32,), is_protocol=True, _module_qname="tpy.Iterable")
|
|
357
|
+
assert _classify_strict_match(_list(INT32), proto) is None
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
def test_classify_strict_propagates_widening_cost_from_type_args():
|
|
361
|
+
def cls(a, p):
|
|
362
|
+
return ProtocolConformanceKind.EXPLICIT
|
|
363
|
+
proto = NominalType("Iterable", (INT64,), is_protocol=True, _module_qname="tpy.Iterable")
|
|
364
|
+
tier, cost = _classify_strict_match(_list(INT32), proto, cls, default_int_type=INT32)
|
|
365
|
+
assert tier == MatchTier.PROTOCOL_EXPLICIT
|
|
366
|
+
assert cost == 4 # Int32 -> Int64 widening
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
# --------------------------------------------------------------------------
|
|
370
|
+
# _bool_checker_to_classifier
|
|
371
|
+
# --------------------------------------------------------------------------
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
def test_bool_checker_to_classifier_none_passes_through():
|
|
375
|
+
assert _bool_checker_to_classifier(None) is None
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
def test_bool_checker_to_classifier_true_means_structural():
|
|
379
|
+
# The adapter has to fabricate a tier; it picks STRUCTURAL so it never
|
|
380
|
+
# silently upgrades an unverified hit to EXPLICIT.
|
|
381
|
+
cls = _bool_checker_to_classifier(lambda a, p: True)
|
|
382
|
+
assert cls(INT32, FLOAT) == ProtocolConformanceKind.STRUCTURAL
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def test_bool_checker_to_classifier_false_means_none():
|
|
386
|
+
cls = _bool_checker_to_classifier(lambda a, p: False)
|
|
387
|
+
assert cls(INT32, FLOAT) is None
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
# --------------------------------------------------------------------------
|
|
391
|
+
# OverloadAmbiguityError
|
|
392
|
+
# --------------------------------------------------------------------------
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def _fn(name: str, *param_types) -> FunctionInfo:
|
|
396
|
+
return FunctionInfo(
|
|
397
|
+
name=name,
|
|
398
|
+
params=tuple(ParamInfo(f"p{i}", t) for i, t in enumerate(param_types)),
|
|
399
|
+
return_type=VOID,
|
|
400
|
+
)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
def test_overload_ambiguity_error_carries_candidates():
|
|
404
|
+
a = _fn("f", INT32)
|
|
405
|
+
b = _fn("f", INT64)
|
|
406
|
+
err = OverloadAmbiguityError((a, b))
|
|
407
|
+
assert err.candidates == (a, b)
|
|
408
|
+
msg = str(err)
|
|
409
|
+
assert "f(Int32)" in msg
|
|
410
|
+
assert "f(Int64)" in msg
|