Allow pypy3clean to target a specific tag
Stefano Rivera
5 years ago
3 | 3 | import collections |
4 | 4 | import itertools |
5 | 5 | import os |
6 | import shutil | |
7 | 6 | import subprocess |
8 | 7 | import sys |
9 | 8 | |
40 | 39 | yield os.path.join(dirpath, fn) |
41 | 40 | |
42 | 41 | |
43 | def clean_modules(modules, verbose): | |
44 | """Remove all .pyc files for every module specified""" | |
42 | def clean_modules(modules, verbose, tag): | |
43 | """Remove all tag.pyc files for every module specified""" | |
45 | 44 | clean = collections.defaultdict(list) |
46 | 45 | for module in modules: |
47 | 46 | dir_, basename = os.path.split(module) |
54 | 53 | |
55 | 54 | empty = True |
56 | 55 | for fn in os.listdir(pycache): |
57 | if fn.endswith('.pyc') and fn.rsplit('.', 2)[0] in basenames: | |
56 | parts = fn.rsplit('.', 2) | |
57 | if parts[0] in basenames and parts[1] == tag and parts[2] == 'pyc': | |
58 | 58 | if verbose: |
59 | 59 | print('Removing %s' % os.path.join(pycache, fn)) |
60 | 60 | os.unlink(os.path.join(pycache, fn)) |
67 | 67 | os.rmdir(pycache) |
68 | 68 | |
69 | 69 | |
70 | def clean_directories(directories, verbose): | |
71 | """Indiscriminately remove __pycache__ directories""" | |
70 | def clean_directories(directories, verbose, tag): | |
71 | """Remove the specified tag.pyc files.""" | |
72 | suffix = '.{}.pyc'.format(tag) | |
72 | 73 | for root in directories: |
73 | 74 | for dirpath, dirnames, filenames in os.walk(root): |
74 | for dir_ in dirnames: | |
75 | if dir_ == '__pycache__': | |
75 | if dirpath.endswith('/__pycache__'): | |
76 | empty = True | |
77 | for file_ in filenames: | |
78 | if file_.endswith(suffix): | |
79 | if verbose: | |
80 | print('Removing %s' % os.path.join(dirpath, file_)) | |
81 | os.unlink(os.path.join(dirpath, file_)) | |
82 | else: | |
83 | empty = False | |
84 | ||
85 | if empty: | |
76 | 86 | if verbose: |
77 | print('Removing %s' % os.path.join(dirpath, dir_)) | |
78 | shutil.rmtree(os.path.join(dirpath, dir_)) | |
87 | print('Pruning %s' % dirpath) | |
88 | os.rmdir(dirpath) | |
89 | ||
90 | ||
91 | def pypy3_tag(version): | |
92 | """Return the tag used by the given PyPy3 version""" | |
93 | parts = version.split('.') | |
94 | if len(parts) != 2: | |
95 | raise argparse.ArgumentTypeError('Version must be MAJOR.MINOR') | |
96 | return 'pypy3-{}{}'.format(*parts) | |
79 | 97 | |
80 | 98 | |
81 | 99 | def main(): |
91 | 109 | help='Be more verbose') |
92 | 110 | parser.add_argument('-q', '--quiet', action='store_true', |
93 | 111 | help='Be quiet') |
112 | parser.add_argument('--version', metavar='VERSION', | |
113 | default='{}.{}'.format(*sys.pypy_version_info[:2]), | |
114 | dest='tag', type=pypy3_tag, | |
115 | help='Clean up .pyc files left by the specified ' | |
116 | 'pypy3 version') | |
94 | 117 | args = parser.parse_args() |
95 | 118 | |
96 | 119 | if not (args.package or args.directory): |
117 | 140 | modules.add(fn) |
118 | 141 | else: |
119 | 142 | directories.add(fn) |
120 | clean_directories(directories, args.verbose) | |
143 | clean_directories(directories, args.verbose, args.tag) | |
121 | 144 | |
122 | clean_modules(modules, args.verbose) | |
145 | clean_modules(modules, args.verbose, args.tag) | |
123 | 146 | |
124 | 147 | |
125 | 148 | if __name__ == '__main__': |