1#! /usr/bin/env python3 2# Check that all ".pyc" files exist and are up-to-date 3# Uses module 'os' 4 5import sys 6import os 7from stat import ST_MTIME 8import importlib.util 9 10# PEP 3147 compatibility (PYC Repository Directories) 11cache_from_source = (importlib.util.cache_from_source if sys.implementation.cache_tag 12 else lambda path: path + 'c') 13 14 15def main(): 16 if len(sys.argv) > 1: 17 verbose = (sys.argv[1] == '-v') 18 silent = (sys.argv[1] == '-s') 19 else: 20 verbose = silent = False 21 MAGIC = importlib.util.MAGIC_NUMBER 22 if not silent: 23 print('Using MAGIC word', repr(MAGIC)) 24 for dirname in sys.path: 25 try: 26 names = os.listdir(dirname) 27 except OSError: 28 print('Cannot list directory', repr(dirname)) 29 continue 30 if not silent: 31 print('Checking ', repr(dirname), '...') 32 for name in sorted(names): 33 if name.endswith('.py'): 34 name = os.path.join(dirname, name) 35 try: 36 st = os.stat(name) 37 except OSError: 38 print('Cannot stat', repr(name)) 39 continue 40 if verbose: 41 print('Check', repr(name), '...') 42 name_c = cache_from_source(name) 43 try: 44 with open(name_c, 'rb') as f: 45 magic_str = f.read(4) 46 mtime_str = f.read(4) 47 except IOError: 48 print('Cannot open', repr(name_c)) 49 continue 50 if magic_str != MAGIC: 51 print('Bad MAGIC word in ".pyc" file', end=' ') 52 print(repr(name_c)) 53 continue 54 mtime = get_long(mtime_str) 55 if mtime in {0, -1}: 56 print('Bad ".pyc" file', repr(name_c)) 57 elif mtime != st[ST_MTIME]: 58 print('Out-of-date ".pyc" file', end=' ') 59 print(repr(name_c)) 60 61 62def get_long(s): 63 if len(s) != 4: 64 return -1 65 return s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24) 66 67 68if __name__ == '__main__': 69 main() 70