fix(tpc): import fail-fast 判据误报修复——文件系统找不到不等于模块不存在

- TPV 自举工程 includes 为合并形态,源码模块(lib.Stub.StubMerger 包)不提供裸 .vp 文件,声明由 ModuleSha1Map 定位 sha1 -> temp/*.stub.ll 加载(_LoadDeclarationsFromStubLlvm,与 FullModulePath 无关)
- 原判据只看 FullModulePath 文件系统存在性 -> TPV 构建所有 import 误报 ImportError
- 改为:文件系统找不到时查 _source_module_sig_files / Gen.ModuleSha1Map(TPV 工程由 Phase2Translator._ModuleSha1Map 同步而来),模块有 sha1 注册即视为可解析
- 单文件编译两表皆空,NegativeTest 假 import 用例仍 fail-fast
This commit is contained in:
TermiNexus committed 2026-08-22 04:04:30 +08:00
1 parent 0ce4a4d073
commit 3117ab3dec
1 file changed
+22 -7
+22 -7
View File
@@ -659,14 +659,29 @@ class ImportHandle(BaseHandle):
break
if FullModulePath:
break
# fail-fast:模块在所有来源(includes/LibraryPaths/工程目录/递归 walk)都
# 找不到时立即报错,暴露 import 路径错误(如目录重组后未更新的旧路径)。
# 之前静默容忍导致引用方跨模块 mangled 前缀 fallback 当前模块 sha1,
# 链接期才暴露 undefined symbol(ClassGenGeneric 根因)。
# fail-fast:模块在所有来源都"完全未知"时立即报错,暴露 import 路径错误
# (如目录重组后未更新的旧路径)。之前静默容忍导致引用方跨模块 mangled
# 前缀 fallback 当前模块 sha1,链接期才暴露 undefined symbol。
# 注意:文件系统找不到 ≠ 模块不存在——TPV 自举工程 includes 为合并形态,
# 源码模块(如 lib.Stub.StubMerger 包)不提供裸 .vp 文件,声明由
# ModuleSha1Map/_source_module_sig_files 定位 sha1 → temp/*.stub.ll 加载,
# 属正常路径;只有模块在编译上下文完全未注册(无 sha1)才算真正不存在。
if not FullModulePath or not os.path.isfile(FullModulePath):
raise ImportError(
f"无法解析 import 模块 '{module_name}': "
f"在 includes/LibraryPaths/工程目录均未找到对应 .vp/.py/.vpi/.pyi 文件")
_known_sha1: str | None = None
_sig_files = getattr(self.Trans, '_source_module_sig_files', None)
if _sig_files:
for _key, _val in _sig_files.items():
if _key == module_name or _key.endswith('.' + module_name):
_known_sha1 = os.path.basename(_val).replace('.vpi', '').replace('.pyi', '')
break
if not _known_sha1:
_sha_map: dict[str, str] = getattr(Gen, 'ModuleSha1Map', None) or {}
_known_sha1 = _sha_map.get(module_name)
if not _known_sha1:
raise ImportError(
f"无法解析 import 模块 '{module_name}': "
f"在 includes/LibraryPaths/工程目录均未找到对应 .vp/.py/.vpi/.pyi 文件,"
f"且编译上下文无该模块的 sha1 注册(模块完全未知)")
# 注册跨模块 __doc__ docstring(module_name 是被导入模块名)
if FullModulePath:
self._RegisterCrossModuleDocstrings(FullModulePath, Gen, module_name)