/usr/bin/pypyclean is in pypy 5.10.0+dfsg-3build2.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
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 125 126 127 | #!/usr/bin/pypy
import argparse
import collections
import itertools
import os
import shutil
import subprocess
import sys
def abort(message):
print >> sys.stderr, message
sys.exit(1)
def package_modules(package):
'''Iterate through all python modules in an install Debian package'''
p = subprocess.Popen(('dpkg', '-L', package), stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
files, stderr = p.communicate()
if p.returncode != 0:
abort('Unable to list files in %s. Is it installed?' % package)
for fn in files.splitlines():
if fn.endswith('.py'):
yield fn
def find_modules(root):
'''Iterate through all python modules in directory tree root'''
if os.path.isfile(root):
yield root
return
for dirpath, dirnames, filenames in os.walk(root):
for fn in filenames:
if fn.endswith('.py'):
yield os.path.join(dirpath, fn)
def clean_modules(modules, verbose):
'''Remove all .pyc files for every module specified'''
clean = collections.defaultdict(list)
for module in modules:
dir_, basename = os.path.split(module)
clean[dir_].append(os.path.splitext(basename)[0])
for dir_, basenames in clean.iteritems():
pycache = os.path.join(dir_, '__pycache__')
if not os.path.exists(pycache):
continue
empty = True
for fn in os.listdir(pycache):
if fn.endswith('.pyc') and fn.rsplit('.', 2)[0] in basenames:
if verbose:
print "Removing %s" % os.path.join(pycache, fn)
os.unlink(os.path.join(pycache, fn))
else:
empty = False
if empty:
if verbose:
print "Pruning %s" % pycache
os.rmdir(pycache)
def clean_directories(directories, verbose):
'''Indiscriminately remove __pycache__ directories'''
for root in directories:
for dirpath, dirnames, filenames in os.walk(root):
for dir_ in dirnames:
if dir_ == '__pycache__':
if verbose:
print "Removing %s" % os.path.join(dirpath, dir_)
shutil.rmtree(os.path.join(dirpath, dir_))
def main():
parser = argparse.ArgumentParser(
description='Remove byte-compiled files for a package')
parser.add_argument('-p', '--package', metavar='PACKAGE',
action='append', default=[],
help='Debian package to byte-compile '
'(may be specified multiple times)')
parser.add_argument('directory', nargs='*',
help='Directory tree (or file) to byte-compile')
parser.add_argument('-v', '--verbose', action='store_true',
help='Be more verbose')
parser.add_argument('-q', '--quiet', action='store_true',
help='Be quiet')
args = parser.parse_args()
if not (args.package or args.directory):
parser.error('Either a package or a directory must be specified')
if args.quiet and args.verbose:
parser.error('--quiet and --verbose cannot both be specified')
modules_p = set(itertools.chain(*(
package_modules(package) for package in args.package)))
modules_d = set(itertools.chain(*(
find_modules(dir_) for dir_ in args.directory)))
if args.package and args.directory:
modules = modules_d & modules_p
elif args.package:
modules = modules_p
else:
# Split files from directories, so that we can completely clean any
# specified directories.
modules = set()
directories = set()
for fn in args.directory:
if os.path.isfile(fn) and fn.endswith('.py'):
modules.add(fn)
else:
directories.add(fn)
clean_directories(directories, args.verbose)
clean_modules(modules, args.verbose)
if __name__ == '__main__':
main()
# vim: ft=python
|