summaryrefslogtreecommitdiff
path: root/debian/scripts/pypycompile
diff options
context:
space:
mode:
Diffstat (limited to 'debian/scripts/pypycompile')
-rwxr-xr-xdebian/scripts/pypycompile129
1 files changed, 129 insertions, 0 deletions
diff --git a/debian/scripts/pypycompile b/debian/scripts/pypycompile
new file mode 100755
index 0000000..31abe2d
--- /dev/null
+++ b/debian/scripts/pypycompile
@@ -0,0 +1,129 @@
+#!/usr/bin/pypy
+
+import argparse
+import itertools
+import os
+import re
+import py_compile
+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 installed 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'):
+ if fn.startswith('/usr/share/doc/'):
+ continue
+ 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 generate_namespace_init(package, verbose):
+ '''Iterate through a package's ns file.
+ Create all necessary__init__.pys, and yield them.
+ '''
+ ns_file = os.path.join('/usr/share/pypy/ns', package)
+ if not os.path.exists(ns_file):
+ return
+ with open(ns_file) as f:
+ contents = f.read().decode('utf-8').strip()
+ namespaces = [line.strip() for line in contents.splitlines()]
+
+ for namespace in namespaces:
+ init = os.path.join('/usr/lib/pypy/dist-packages',
+ namespace.replace('.', '/'),
+ '__init__.py')
+ if verbose:
+ print 'Ensuring %s exists' % init
+ with open(init, 'w') as f:
+ pass
+ yield init
+
+
+def main():
+ parser = argparse.ArgumentParser(
+ description='Byte-compile Python source files in a package, for PyPy')
+ 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('-X', '--exclude', metavar='REGEXPR',
+ action='append', default=[], type=re.compile,
+ help='Exclude items that match given REGEXPR '
+ '(may be specified multiple times)')
+ parser.add_argument('-v', '--verbose', action='store_true',
+ help='Be more verbose')
+ parser.add_argument('-q', '--quiet', action='store_true',
+ help='Be quiet')
+ parser.add_argument('-V', metavar='VRANGE', dest='vrange',
+ help=argparse.SUPPRESS)
+ parser.add_argument('-O', action='store_true', dest='pyo',
+ help=argparse.SUPPRESS)
+ 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')
+
+ if args.vrange:
+ print >> sys.stderr, '-V is ignored in pypycompile'
+ if args.pyo:
+ print >> sys.stderr, '-O is ignored in pypycompile'
+
+ 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
+ else:
+ modules = modules_d | modules_p
+
+ for package in args.package:
+ modules |= set(generate_namespace_init(package, verbose=args.verbose))
+
+ modules = filter(lambda module: not any(pattern.match(module)
+ for pattern in args.exclude),
+ modules)
+
+ for module in modules:
+ if args.verbose:
+ print 'Byte-compiling %s' % module
+ try:
+ py_compile.compile(module, doraise=True)
+ except py_compile.PyCompileError as e:
+ if not args.quiet:
+ print >> sys.stderr, ('Failed to byte-compile %s: %s'
+ % (module, e.msg))
+
+if __name__ == '__main__':
+ main()
+
+# vim: ft=python