Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2e6adce

Browse files
authored
Run flake8 incrementally (mypyc/mypyc#103)
Don't lint files that have not changed since the previous clean flake8 run. This speeds up typical lint runtimes by about a second or so on my laptop. The savings might not be that big right now, but as we add more code they will add up. This might break some cross-module checks that flake8 might perform, but we can disable these if they turn out to be a problem. Manually removing the .mypyc-flake8-cache.json file will force a full flake8 run.
1 parent 9fec1e5 commit 2e6adce

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ test_capi
1414
/.pytest_cache
1515
/dmypy.json
1616
/.dmypy.json
17+
/.mypyc-flake8-cache.json

mypyc/test/test_external.py

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,48 @@ def test_self_type_check(self) -> None:
5353

5454
def test_flake8(self) -> None:
5555
"""Use flake8 to lint mypyc."""
56-
status = subprocess.call([sys.executable, '-m', 'flake8', 'mypyc'])
56+
status = cached_flake8('mypyc')
5757
if status != 0:
5858
assert False, "Lint failure"
59+
60+
61+
CACHE_FILE = '.mypyc-flake8-cache.json'
62+
63+
64+
def cached_flake8(dir: str) -> int:
65+
"""Run flake8 with cached results from the previous clean run.
66+
67+
Record the hashes of files after a clean run and don't pass the files to
68+
flake8 if they have the same hashes, as they are expected to produce a
69+
clean output.
70+
71+
If flake8 settings or version change, the cache file may need to be manually
72+
removed.
73+
"""
74+
import hashlib
75+
import glob
76+
import json
77+
78+
if os.path.isfile(CACHE_FILE):
79+
with open(CACHE_FILE) as f:
80+
cache = json.load(f)
81+
else:
82+
cache = {}
83+
files = glob.glob('%s/**/*.py' % dir, recursive=True)
84+
hashes = {}
85+
for fn in files:
86+
with open(fn, 'rb') as fb:
87+
data = fb.read()
88+
hashes[fn] = hashlib.sha1(data).hexdigest()
89+
filtered = [fn for fn in files
90+
if hashes[fn] != cache.get(fn)]
91+
if not filtered:
92+
# Nothing has changed since the previous clean run -- must be clean.
93+
return 0
94+
status = subprocess.call([sys.executable, '-m', 'flake8'] + filtered)
95+
if status == 0:
96+
for fn, sha in hashes.items():
97+
cache[fn] = sha
98+
with open(CACHE_FILE, 'w') as f:
99+
json.dump(cache, f, indent=4)
100+
return status

0 commit comments

Comments
 (0)