-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathmetarun.py
More file actions
124 lines (112 loc) · 3.28 KB
/
Copy pathmetarun.py
File metadata and controls
124 lines (112 loc) · 3.28 KB
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import re
import sys
import subprocess
import libcst as cst
VERSIONS = [
# "python2.3",
# "python2.4",
# "python2.5",
# "python2.6",
# "python2.7",
# "python3.0",
# "python3.1",
# "python3.2",
# "python3.3",
# "python3.4",
# "python3.5",
# "python3.6",
# "python3.7",
"python3.8",
"python3.9",
"python3.10",
"python3.11",
"python3.12",
"python3.13",
"python3.14",
"python3.15",
]
LIBCST_VERSIONS = [
# "2.3",
# "2.4",
# "2.6",
# "2.7",
# "3.0",
# "3.1",
# "3.3",
# "3.5",
# "3.6",
# "3.7",
# "3.8",
# "3.9",
# "3.10",
# "3.11",
# "3.12",
# "3.13",
]
VER_RE = re.compile(r'examples/py(\d+)-(\d+)')
def ver_match(s):
m = VER_RE.match(s)
maj = m.group(1)[:1]
min = m.group(1)[1:]
return (int(maj), int(min), int(m.group(2)), s)
def main(filters=()):
# dict[filename][version]
results = {}
for v in VERSIONS:
# TODO as there get to be many more of these, should run them in
# parallel, or at least streaming.
output = subprocess.check_output([v, "run.py"], encoding="utf-8")
for line in output.splitlines():
filename, result = line.split()
results.setdefault(filename, {})[v] = result == "YES"
# Now print a pretty table. TODO should write json or something consumable
# as well.
max_filename = max(len(f) for f in results)
# TODO mark versions that will be libcst-checked too
buf = [" " * max_filename]
for v in VERSIONS:
short_version = v[-3:]
if short_version in LIBCST_VERSIONS:
buf.append(f" \x1b[32m{short_version.replace('.', '')}\x1b[0m")
else:
buf.append(f" {short_version.replace('.', '')}")
print("".join(buf))
for f in sorted(results, key=ver_match):
if filters and not any(filt in f for filt in filters):
continue
sys.stdout.write(f.ljust(max_filename + 1))
for v in VERSIONS:
libcst_result = None
if v[-3:] in LIBCST_VERSIONS:
try:
with open(f) as fo:
data = fo.read()
cst.parse_module(
data, cst.PartialParserConfig(python_version=v[-3:])
)
libcst_result = True
except cst.ParserSyntaxError:
libcst_result = False
if libcst_result != results[f][v]:
sys.stdout.write(
"\x1b[31m"
f"{'o' if results[f][v] else '.'}{'o' if libcst_result else '.'} "
"\x1b[0m"
)
else:
sys.stdout.write(
f"{'o' if results[f][v] else '.'}{'o' if libcst_result else '.'} "
)
else:
sys.stdout.write(
f"{'o' if results[f][v] else '.'} "
)
sys.stdout.write("\n")
print("Legend:")
print(" green header means will test with libcst")
print()
print(" first result is python, second [optional] result is libcst")
print(" o parses")
print(" . does not parse")
if __name__ == "__main__":
main(sys.argv[1:])