更新bug
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
"""把当前源码编译结果与最后一版正确源码的 .pyc 逐个 code 对象比对。
|
||||
|
||||
这是修复正确性的最终判据:注释吞掉语句、误拆行等问题都会在字节码上暴露。
|
||||
行号允许不同(注释多一行少一行不影响语义),比对的是 co_code、常量与名字。
|
||||
"""
|
||||
|
||||
import marshal
|
||||
import os
|
||||
import types
|
||||
|
||||
_HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
_ROOT = os.path.dirname(_HERE)
|
||||
|
||||
|
||||
def index_code(root, prefix=""):
|
||||
table = {}
|
||||
|
||||
def walk(c, path):
|
||||
key = path
|
||||
suffix = 0
|
||||
while key in table:
|
||||
suffix += 1
|
||||
key = f"{path}#{suffix}"
|
||||
table[key] = c
|
||||
for const in c.co_consts:
|
||||
if isinstance(const, types.CodeType):
|
||||
walk(const, f"{path}/{const.co_name}")
|
||||
|
||||
walk(root, prefix or root.co_name)
|
||||
return table
|
||||
|
||||
|
||||
def scalars(c):
|
||||
return tuple(
|
||||
x for x in c.co_consts if not isinstance(x, types.CodeType)
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
source = open(os.path.join(_ROOT, "wechat_bot.py"), encoding="utf-8").read()
|
||||
current = compile(source, "wechat_bot.py", "exec")
|
||||
good = marshal.loads(
|
||||
open(os.path.join(_HERE, "wechat_bot.lastgood.pyc"), "rb").read()[16:]
|
||||
)
|
||||
|
||||
left = index_code(current)
|
||||
right = index_code(good)
|
||||
|
||||
only_current = sorted(set(left) - set(right))
|
||||
only_good = sorted(set(right) - set(left))
|
||||
print(f"当前 code 对象 {len(left)} 个,正确版 {len(right)} 个")
|
||||
if only_good:
|
||||
print(f"缺失的 code 对象 {len(only_good)} 个(说明有语句被吞进注释):")
|
||||
for name in only_good[:20]:
|
||||
print(" ", name)
|
||||
if only_current:
|
||||
print(f"多出来的 code 对象 {len(only_current)} 个:")
|
||||
for name in only_current[:20]:
|
||||
print(" ", name)
|
||||
|
||||
differing = []
|
||||
for name in sorted(set(left) & set(right)):
|
||||
a, b = left[name], right[name]
|
||||
if a.co_code != b.co_code:
|
||||
differing.append((name, "字节码"))
|
||||
elif scalars(a) != scalars(b):
|
||||
differing.append((name, "常量"))
|
||||
elif a.co_names != b.co_names or a.co_varnames != b.co_varnames:
|
||||
differing.append((name, "名字表"))
|
||||
|
||||
if differing:
|
||||
print(f"\n有差异的 code 对象 {len(differing)} 个:")
|
||||
for name, kind in differing[:25]:
|
||||
print(f" [{kind}] {name}")
|
||||
if kind == "常量":
|
||||
a, b = scalars(left[name]), scalars(right[name])
|
||||
for x, y in zip(a, b):
|
||||
if x != y:
|
||||
print(f" 当前={x!r}")
|
||||
print(f" 应为={y!r}")
|
||||
break
|
||||
else:
|
||||
print("\n所有 code 对象逐字节一致:代码语义与最后一版正确源码完全相同。")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user