fix(tpv): vpi 相对导入补回包前缀(D26)

- vpi 只存 module=base(前导点记在 level),from-import 映射写字面 base 时,解析端按精确 LookupSha1ByModName 查不到 ast.base ⇒ 裸类名(AST 等)解析失败 ⇒ rowptr[AST] 等注解 fail-fast(TPV→TPV 自举 includes/ast/parser.vp parse 根因)

- 按 stub 自身相对路径还原包名(ast/parser.vp → ast),level==1 拼成 ast.base 再登记;_stub_add_imported 与 _stub_add_from 两处同步
This commit is contained in:
TermiNexus committed 2026-09-12 15:59:37 +08:00
1 parent 3c45895878
commit 626f79cbd1
1 file changed
+25 -2
+25 -2
View File
@@ -1590,9 +1590,32 @@ def _ParseVpiIntoModuleImpl(pool: rowptr[memhub.MemBuddy],
elif sk == ast.ASTKind.ImportFrom:
sifr: ast.ImportFrom | t.CPtr = (ast.ImportFrom | t.CPtr)(schild)
sifr_mod: str = sifr.module
# [D26 相对导入补包前缀] vpi 里 `from .base import X` 只存 module="base"
# (前导点记在 level)。若 from-import 映射里写字面 "base",解析端按
# **精确** LookupSha1ByModName("base") 查不到 "ast.base" ⇒ 裸类名(AST 等)
# 解析失败 ⇒ rowptr[AST] 等注解 fail-fast(TPV→TPV 自举
# includes/ast/parser.vp `parse -> rowptr[AST]` 根因)。
# 这里按 stub 自身的相对路径还原包名(ast/parser.vp → "ast"),
# level==1 时拼成完整模块名 "ast.base" 再登记(level>1 保持原样,
# 避免在未确认路径形态时做过深上溯)。
sifr_mod_q: str = sifr_mod
if sifr_mod is not None and sifr_mod[0] != '\0' and sifr.level == 1:
rel_p_r: str = StubMergerStore.LookupSha1RelPath(src_sha1)
if rel_p_r is not None:
slash_r: str = string.strrchr(rel_p_r, '/')
if slash_r is not None:
pkg_len_r: sizet = string.strlen(rel_p_r) - string.strlen(slash_r)
if pkg_len_r > 0:
qtotal_r: sizet = pkg_len_r + 1 + string.strlen(sifr_mod) + 1
qbuf_r: str = pool.alloc(qtotal_r)
if qbuf_r is not None:
string.strncpy(qbuf_r, rel_p_r, pkg_len_r)
qbuf_r[pkg_len_r] = '.'
string.strcpy(qbuf_r + pkg_len_r + 1, sifr_mod)
sifr_mod_q = qbuf_r
if sifr_mod is not None:
stub_imported_modules = _stub_add_imported(
pool, stub_imported_modules, sifr_mod)
pool, stub_imported_modules, sifr_mod_q)
# 方案A:包 __init__.vpi 的重导出类以包 sha1 注册别名 entry
# (ast.Attribute 定义在 ast.exprs 但归属 ast 包;查找端按包
# sha1 匹配,注册端按定义文件 sha1 → name+sha1 错位 fail-fast。
@@ -1634,7 +1657,7 @@ def _ParseVpiIntoModuleImpl(pool: rowptr[memhub.MemBuddy],
slocal = sial.asname
sorig = sial.name
stub_from_imports = _stub_add_from(
pool, stub_from_imports, slocal, sifr_mod, sorig)
pool, stub_from_imports, slocal, sifr_mod_q, sorig)
# 重导出类以包 sha1 注册(asname 时按别名注册)
if is_pkg_init_rt != 0 and sub_sha1_rt is not None:
_inject_reexport_class_declare(