compileall.py revision 8989ea6ce1619890adc58778fb5516a36053cadb
1c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum"""Module/script to "compile" all .py files to .pyc (or .pyo) file.
2c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
3c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van RossumWhen called as a script with arguments, this compiles the directories
4c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossumgiven as arguments recursively; the -l option prevents it from
5c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossumrecursing into directories.
6c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
7c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van RossumWithout arguments, if compiles all modules on sys.path, without
8c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossumrecursing into subdirectories.  (Even though it should do so for
9c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossumpackages -- for now, you'll have to deal with packages separately.)
10c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
11c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van RossumSee module py_compile for details of the actual byte-compilation.
12c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
13c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum"""
143bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
153bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumimport os
160b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossumimport stat
173bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumimport sys
183bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumimport py_compile
193bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
20e99d5ea25ba994491c773d9b5872332334ccd1c5Skip Montanaro__all__ = ["compile_dir","compile_path"]
21e99d5ea25ba994491c773d9b5872332334ccd1c5Skip Montanaro
225c137c225113764faae183034e7a85175a699ae2Martin v. Löwisdef compile_dir(dir, maxlevels=10, ddir=None,
235c137c225113764faae183034e7a85175a699ae2Martin v. Löwis                force=0, rx=None, quiet=0):
24c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """Byte-compile all modules in the given directory tree.
25c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
26c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    Arguments (only dir is required):
27c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
28c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    dir:       the directory to byte-compile
29c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    maxlevels: maximum recursion level (default 10)
30c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    ddir:      if given, purported directory name (this is the
31c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum               directory name that will show up in error messages)
320b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum    force:     if 1, force compilation, even if timestamps are up-to-date
335c137c225113764faae183034e7a85175a699ae2Martin v. Löwis    quiet:     if 1, be quiet during compilation
343bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
35c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """
365c137c225113764faae183034e7a85175a699ae2Martin v. Löwis    if not quiet:
375c137c225113764faae183034e7a85175a699ae2Martin v. Löwis        print 'Listing', dir, '...'
38c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    try:
3945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        names = os.listdir(dir)
40c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    except os.error:
4145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "Can't list", dir
4245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        names = []
43c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    names.sort()
449065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    success = 1
45c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    for name in names:
4645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        fullname = os.path.join(dir, name)
478989ea6ce1619890adc58778fb5516a36053cadbRaymond Hettinger        if ddir is not None:
4845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            dfile = os.path.join(ddir, name)
4945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        else:
5045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            dfile = None
518989ea6ce1619890adc58778fb5516a36053cadbRaymond Hettinger        if rx is not None:
5212b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            mo = rx.search(fullname)
5312b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            if mo:
5412b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                continue
5545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if os.path.isfile(fullname):
5645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            head, tail = name[:-3], name[-3:]
5745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            if tail == '.py':
580b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                cfile = fullname + (__debug__ and 'c' or 'o')
590b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                ftime = os.stat(fullname)[stat.ST_MTIME]
600b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                try: ctime = os.stat(cfile)[stat.ST_MTIME]
610b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                except os.error: ctime = 0
620b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                if (ctime > ftime) and not force: continue
635c137c225113764faae183034e7a85175a699ae2Martin v. Löwis                if not quiet:
645c137c225113764faae183034e7a85175a699ae2Martin v. Löwis                    print 'Compiling', fullname, '...'
6545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                try:
6612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    ok = py_compile.compile(fullname, None, dfile)
6745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                except KeyboardInterrupt:
6845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    raise KeyboardInterrupt
6945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                except:
7012b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    # XXX py_compile catches SyntaxErrors
7145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    if type(sys.exc_type) == type(''):
7245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                        exc_type_name = sys.exc_type
7345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    else: exc_type_name = sys.exc_type.__name__
7445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    print 'Sorry:', exc_type_name + ':',
7545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    print sys.exc_value
769065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake                    success = 0
7712b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                else:
7812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    if ok == 0:
7912b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                        success = 0
8045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        elif maxlevels > 0 and \
8145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum             name != os.curdir and name != os.pardir and \
8245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum             os.path.isdir(fullname) and \
8345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum             not os.path.islink(fullname):
845c137c225113764faae183034e7a85175a699ae2Martin v. Löwis            if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, quiet):
8512b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                success = 0
869065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    return success
87c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
885c137c225113764faae183034e7a85175a699ae2Martin v. Löwisdef compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
89c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """Byte-compile all module on sys.path.
90c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
91c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    Arguments (all optional):
92c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
93c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    skip_curdir: if true, skip current directory (default true)
94c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    maxlevels:   max recursion level (default 0)
950b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum    force: as for compile_dir() (default 0)
965c137c225113764faae183034e7a85175a699ae2Martin v. Löwis    quiet: as for compile_dir() (default 0)
97c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
98c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """
999065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    success = 1
100c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    for dir in sys.path:
10145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if (not dir or dir == os.curdir) and skip_curdir:
10245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            print 'Skipping current directory'
10345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        else:
1045c137c225113764faae183034e7a85175a699ae2Martin v. Löwis            success = success and compile_dir(dir, maxlevels, None,
1055c137c225113764faae183034e7a85175a699ae2Martin v. Löwis                                              force, quiet=quiet)
1069065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    return success
1073bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
1083bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumdef main():
109c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """Script main program."""
110c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    import getopt
111c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    try:
1125c137c225113764faae183034e7a85175a699ae2Martin v. Löwis        opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:')
113c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    except getopt.error, msg:
11445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print msg
1155c137c225113764faae183034e7a85175a699ae2Martin v. Löwis        print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
11612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton              "[-s regexp] [directory ...]"
11745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "-l: don't recurse down"
1180b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum        print "-f: force rebuild even if timestamps are up-to-date"
1195c137c225113764faae183034e7a85175a699ae2Martin v. Löwis        print "-q: quiet operation"
12045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "-d destdir: purported directory name for error messages"
12112b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "   if no directory arguments, -l sys.path is assumed"
12212b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "-x regexp: skip files matching the regular expression regexp"
12312b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "   the regexp is search for in the full path of the file"
12445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        sys.exit(2)
125c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    maxlevels = 10
126c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    ddir = None
1270b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum    force = 0
1285c137c225113764faae183034e7a85175a699ae2Martin v. Löwis    quiet = 0
12912b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton    rx = None
130c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    for o, a in opts:
13145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if o == '-l': maxlevels = 0
13245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if o == '-d': ddir = a
1330b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum        if o == '-f': force = 1
1345c137c225113764faae183034e7a85175a699ae2Martin v. Löwis        if o == '-q': quiet = 1
13512b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        if o == '-x':
13612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            import re
13712b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            rx = re.compile(a)
138c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    if ddir:
13945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if len(args) != 1:
14045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            print "-d destdir require exactly one directory argument"
14145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            sys.exit(2)
1429065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    success = 1
143c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    try:
14445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if args:
14545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            for dir in args:
1465c137c225113764faae183034e7a85175a699ae2Martin v. Löwis                if not compile_dir(dir, maxlevels, ddir,
1475c137c225113764faae183034e7a85175a699ae2Martin v. Löwis                                   force, rx, quiet):
14812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    success = 0
14945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        else:
1509065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake            success = compile_path()
151c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    except KeyboardInterrupt:
15245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "\n[interrupt]"
1539065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake        success = 0
1549065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    return success
1553bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
1563bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumif __name__ == '__main__':
15712b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton    exit_status = not main()
15812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton    sys.exit(exit_status)
159