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