File size: 1,313 Bytes
9f075f3
 
 
 
 
1eb60d5
9f075f3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1eb60d5
9f075f3
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
"""用 3.8 的语法版本解析全仓 .py,判断「Python 3.8 兼容」是真声明还是口号。

只查语法(ast.parse 的 feature_version),不查运行时 API:3.8 上被移除/新增的标准库
行为差异(如 dict 顺序、zoneinfo)无法靠语法发现,那一层仍要靠真机 CI。
"""
from pathlib import Path
import ast
import os
import sys

ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
SKIP_DIRS = {".git", "__pycache__", ".venv", "venv", "build", "dist", "_shots"}
TARGET = (3, 8)


def main():
    bad = []
    total = 0
    for base, dirs, files in os.walk(ROOT):
        dirs[:] = [d for d in dirs if d not in SKIP_DIRS]
        for name in files:
            if not name.endswith(".py"):
                continue
            path = os.path.join(base, name)
            total += 1
            try:
                src = Path(path).read_text(encoding="utf-8")
                ast.parse(src, filename=path, feature_version=TARGET)
            except SyntaxError as exc:
                bad.append((os.path.relpath(path, ROOT), exc.lineno, exc.msg))
    print("parsed=%d  py38_syntax_failures=%d" % (total, len(bad)))
    for row in bad[:20]:
        print("  FAIL %s:%s %s" % row)
    return 1 if bad else 0


if __name__ == "__main__":
    sys.exit(main())