将 .py 和 .pyi 后缀名改为了 .vp 和 .vpi 后缀名

This commit is contained in:
2026-07-30 16:34:50 +08:00
parent 32af3f93fa
commit d227bee139
74 changed files with 42 additions and 25 deletions

View File

@@ -1267,13 +1267,13 @@ def _lookup_cross_module_cdefine(pool: memhub.MemBuddy | t.CPtr,
if temp_dir is None:
return -1
# 6. 构建 pyi 文件路径
# 6. 构建 vpi 文件路径
td_len: t.CSizeT = string.strlen(temp_dir)
pyi_path: str = StubMerger._sliced_path(temp_dir, td_len, sha1, "pyi")
pyi_path: str = StubMerger._sliced_path(temp_dir, td_len, sha1, "vpi")
if pyi_path is None:
return -1
# 7. 读取 pyi 文件;若不存在或内容过短(空 stub则回退读取源 .py 文件
# 7. 读取 vpi 文件;若不存在或内容过短(空 stub则回退读取源 .py 文件
PYI_READ_BUF_SIZE: t.CSizeT = 65536
pyi_buf: bytes = stdlib.malloc(PYI_READ_BUF_SIZE)
if pyi_buf is None:
@@ -1283,12 +1283,12 @@ def _lookup_cross_module_cdefine(pool: memhub.MemBuddy | t.CPtr,
need_py_fallback: int = 0
bytes_read: LONG = 0
if pf.closed:
# .pyi 文件不存在:回退读取源 .py 文件
# .vpi 文件不存在:回退读取源 .py 文件
need_py_fallback = 1
else:
bytes_read = pf.read_all(pyi_buf, PYI_READ_BUF_SIZE)
pf.close()
# pyi 内容过短(< 10 字节)视为空 stub回退 .py
# vpi 内容过短(< 10 字节)视为空 stub回退 .py
if bytes_read < 10:
need_py_fallback = 1
else:

View File

@@ -101,9 +101,9 @@ def add_file_entry(result: ScanResult | t.CPtr,
ch: t.CChar = mod_buf[i]
if ch == '/' or ch == '\\':
mod_buf[i] = '.'
# 去掉 .py 扩展名
# 去掉 .vp 或 .py 扩展名(.vp 为 Viper 源,.py 向后兼容)
if rel_len >= 3:
if mod_buf[rel_len - 3] == '.' and mod_buf[rel_len - 2] == 'p' and mod_buf[rel_len - 1] == 'y':
if (mod_buf[rel_len - 3] == '.' and mod_buf[rel_len - 2] == 'v' and mod_buf[rel_len - 1] == 'p') or (mod_buf[rel_len - 3] == '.' and mod_buf[rel_len - 2] == 'p' and mod_buf[rel_len - 1] == 'y'):
mod_buf[rel_len - 3] = '\0'
# 获取条目地址
@@ -295,10 +295,10 @@ def scan_directory_recursive(pool: memhub.MemBuddy | t.CPtr,
# 递归扫描子目录
scan_directory_recursive(pool, full_path, rel_path, result)
else:
# 检查是否为 .py 文件
# 检查是否为 .vp 或 .py 文件(.vp 为 Viper 源,.py 向后兼容)
is_py: int = 0
if fname_len >= 3:
if fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'p' and fname[fname_len - 1] == 'y':
if (fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'v' and fname[fname_len - 1] == 'p') or (fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'p' and fname[fname_len - 1] == 'y'):
is_py = 1
if is_py != 0:

View File

@@ -1082,12 +1082,12 @@ def RunPhase1(mb: memhub.MemBuddy | t.CPtr, includes_dir: str, temp_dir: str,
failed += 1
continue
# 生成 .pyi 存根文件(直接遍历 AST不依赖 PythonToStubConverter
# 生成 .vpi 存根文件(直接遍历 AST不依赖 PythonToStubConverter
pyi_buf: bytes = stdlib.malloc(PYI_BUF_SIZE)
if pyi_buf is not None:
pyi_pos: t.CSizeT = StubConverter._GeneratePyiFromAst(mb, tree, entry.RelPath, pyi_buf, PYI_BUF_SIZE)
if pyi_pos > 0:
pyi_path: str = StubMerger._sliced_path(temp_dir, dir_len, sha1, "pyi")
pyi_path: str = StubMerger._sliced_path(temp_dir, dir_len, sha1, "vpi")
if pyi_path is not None:
pf: fileio.File | t.CPtr = fileio.File(pyi_path, fileio.MODE.W)
if not pf.closed:

View File

@@ -117,9 +117,9 @@ def _ScanDirForPyFiles(mb: memhub.MemBuddy | t.CPtr,
file_count = _ScanDirForPyFiles(mb, sub_dir, entries, entry_size, file_count, max_files)
stdlib.free(sub_dir)
else:
# 检查是否是 .py 文件
# 检查是否是 .vp 或 .py 文件(.vp 为 Viper 源,.py 向后兼容)
if fname_len > 3:
if fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'p' and fname[fname_len - 1] == 'y':
if (fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'v' and fname[fname_len - 1] == 'p') or (fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'p' and fname[fname_len - 1] == 'y'):
if file_count < max_files:
full_path: bytes = stdlib.malloc(dir_len + fname_len + 2)
if full_path is not None:
@@ -556,12 +556,12 @@ def RunMultiFileProject(mb: memhub.MemBuddy | t.CPtr,
if fb_comp is not None:
viperlib.snprintf(fb_comp, 1024, "[%d/%d] 编译完成: %s", i + 1, file_count, ent.Path)
VLogger.info(fb_comp, "PhaseB")
# 构造 .obj 路径,检测是否是 main 模块test_main.py 或 main.py
# 构造 .obj 路径,检测是否是 main 模块test_main.vp/.py 或 main.vp/.py
od_len: t.CSizeT = string.strlen(output_dir)
is_main_mod: int = 0
if string.strstr(ent.Path, "test_main.py") is not None:
if string.strstr(ent.Path, "test_main.vp") is not None or string.strstr(ent.Path, "test_main.py") is not None:
is_main_mod = 1
elif string.strstr(ent.Path, "main.py") is not None:
elif string.strstr(ent.Path, "main.vp") is not None or string.strstr(ent.Path, "main.py") is not None:
is_main_mod = 1
# 切片路径: output_dir/{sha1前缀}/{sha1}.obj

View File

@@ -1219,8 +1219,9 @@ def _PathToModuleName(path: str) -> str:
if psep_ch == '/' or psep_ch == '\\':
path_start = prefix_len
plen = plen - prefix_len
# 去掉 .py 后缀
if plen > 3 and path[path_start + plen - 3] == '.' and path[path_start + plen - 2] == 'p' and path[path_start + plen - 1] == 'y':
# 去掉 .vp 或 .py 后缀(.vp 为 Viper 源,.py 向后兼容)
if plen > 3:
if (path[path_start + plen - 3] == '.' and path[path_start + plen - 2] == 'v' and path[path_start + plen - 1] == 'p') or (path[path_start + plen - 3] == '.' and path[path_start + plen - 2] == 'p' and path[path_start + plen - 1] == 'y'):
plen -= 3
if plen == 0:
return None
@@ -1446,7 +1447,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
stdlib.free(mod_arr)
stdlib.free(worklist)
return -1
viperlib.snprintf(pattern, dir_len + 8, "%s/*.py", source_dir)
viperlib.snprintf(pattern, dir_len + 8, "%s/*", source_dir)
find_data_size: t.CSizeT = win32file.WIN32_FIND_DATAA.__sizeof__()
find_data: win32file.WIN32_FIND_DATAA | t.CPtr = stdlib.malloc(find_data_size + 16)
@@ -1462,7 +1463,7 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
if handle == win32base.INVALID_HANDLE_VALUE:
fb_fd: t.CChar | t.CPtr = VLogger.fmt_buf()
if fb_fd is not None:
viperlib.snprintf(fb_fd, 1024, "未找到 .py 文件: %s", pattern)
viperlib.snprintf(fb_fd, 1024, "未找到源文件(.vp/.py): %s", pattern)
VLogger.warning(fb_fd, "Reachable")
stdlib.free(pattern)
stdlib.free(find_data)
@@ -1477,7 +1478,8 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
fname_len: t.CSizeT = string.strlen(fname)
if fname_len > 3:
is_py: int = 0
if fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'p' and fname[fname_len - 1] == 'y':
# 检查 .vp 或 .py 扩展名(.vp 为 Viper 源,.py 向后兼容)
if (fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'v' and fname[fname_len - 1] == 'p') or (fname[fname_len - 3] == '.' and fname[fname_len - 2] == 'p' and fname[fname_len - 1] == 'y'):
is_py = 1
if is_py != 0:
full_path: bytes = stdlib.malloc(dir_len + fname_len + 2)
@@ -1677,11 +1679,19 @@ def _BuildReachableSha1Set(mb: memhub.MemBuddy | t.CPtr, source_dir: str,
app_mod_path: bytes = stdlib.malloc(sd_len_ff + mb_len_ff + 6)
is_app_src: int = 0
if app_mod_path is not None:
viperlib.snprintf(app_mod_path, sd_len_ff + mb_len_ff + 6, "%s/%s.py", source_dir, mod_buf)
# 优先尝试 .vp向后兼容 .py
viperlib.snprintf(app_mod_path, sd_len_ff + mb_len_ff + 6, "%s/%s.vp", source_dir, mod_buf)
af: fileio.File | t.CPtr = fileio.File(app_mod_path, fileio.MODE.R)
if not af.closed:
is_app_src = 1
af.close()
else:
# .vp 不存在,回退 .py
viperlib.snprintf(app_mod_path, sd_len_ff + mb_len_ff + 6, "%s/%s.py", source_dir, mod_buf)
af = fileio.File(app_mod_path, fileio.MODE.R)
if not af.closed:
is_app_src = 1
af.close()
stdlib.free(app_mod_path)
if is_app_src != 0:
# App 源文件,跳过(不 fast-fail

View File

@@ -315,11 +315,18 @@ def main() -> int:
# === 单文件模式:--src 指定时使用指定文件;--project 但无 SourceDir 时回退 ===
if src_path is None and project is not None:
if Config.SourceDir is not None:
# 构造入口路径: SourceDir/main.py
# 构造入口路径: 优先 SourceDir/main.vp回退 SourceDir/main.py
sd_len: t.CSizeT = string.strlen(Config.SourceDir)
path_buf: bytes = stdlib.malloc(sd_len + 16)
if path_buf is not None:
# 优先尝试 main.vp
viperlib.snprintf(path_buf, sd_len + 16, "%s/main.vp", Config.SourceDir)
ef: fileio.File | t.CPtr = fileio.File(path_buf, fileio.MODE.R)
if ef.closed:
# .vp 不存在,回退 main.py
viperlib.snprintf(path_buf, sd_len + 16, "%s/main.py", Config.SourceDir)
else:
ef.close()
src_path = path_buf
if log is not None:
fb4: t.CChar | t.CPtr = VLogger.fmt_buf()