compileall.py revision 12b6457e24924ff60cf89fd19a584185a5d6c256
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
2212b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hyltondef compile_dir(dir, maxlevels=10, ddir=None, force=0, rx=None):
23c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """Byte-compile all modules in the given directory tree.
24c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
25c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    Arguments (only dir is required):
26c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
27c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    dir:       the directory to byte-compile
28c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    maxlevels: maximum recursion level (default 10)
29c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    ddir:      if given, purported directory name (this is the
30c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum               directory name that will show up in error messages)
310b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum    force:     if 1, force compilation, even if timestamps are up-to-date
323bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
33c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """
34c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    print 'Listing', dir, '...'
35c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    try:
3645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        names = os.listdir(dir)
37c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    except os.error:
3845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "Can't list", dir
3945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        names = []
40c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    names.sort()
419065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    success = 1
42c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    for name in names:
4345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        fullname = os.path.join(dir, name)
4445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if ddir:
4545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            dfile = os.path.join(ddir, name)
4645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        else:
4745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            dfile = None
4812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        if rx:
4912b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            mo = rx.search(fullname)
5012b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            if mo:
5112b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                continue
5245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if os.path.isfile(fullname):
5345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            head, tail = name[:-3], name[-3:]
5445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            if tail == '.py':
550b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                cfile = fullname + (__debug__ and 'c' or 'o')
560b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                ftime = os.stat(fullname)[stat.ST_MTIME]
570b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                try: ctime = os.stat(cfile)[stat.ST_MTIME]
580b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                except os.error: ctime = 0
590b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum                if (ctime > ftime) and not force: continue
6045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                print 'Compiling', fullname, '...'
6145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                try:
6212b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    ok = py_compile.compile(fullname, None, dfile)
6345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                except KeyboardInterrupt:
6445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    raise KeyboardInterrupt
6545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                except:
6612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    # XXX py_compile catches SyntaxErrors
6745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    if type(sys.exc_type) == type(''):
6845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                        exc_type_name = sys.exc_type
6945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    else: exc_type_name = sys.exc_type.__name__
7045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    print 'Sorry:', exc_type_name + ':',
7145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum                    print sys.exc_value
729065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake                    success = 0
7312b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                else:
7412b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    if ok == 0:
7512b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                        success = 0
7645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        elif maxlevels > 0 and \
7745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum             name != os.curdir and name != os.pardir and \
7845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum             os.path.isdir(fullname) and \
7945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum             not os.path.islink(fullname):
8012b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            if not compile_dir(fullname, maxlevels - 1, dfile, force, rx):
8112b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                success = 0
829065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    return success
83c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
840b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossumdef compile_path(skip_curdir=1, maxlevels=0, force=0):
85c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """Byte-compile all module on sys.path.
86c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
87c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    Arguments (all optional):
88c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
89c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    skip_curdir: if true, skip current directory (default true)
90c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    maxlevels:   max recursion level (default 0)
910b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum    force: as for compile_dir() (default 0)
92c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum
93c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """
949065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    success = 1
95c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    for dir in sys.path:
9645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if (not dir or dir == os.curdir) and skip_curdir:
9745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            print 'Skipping current directory'
9845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        else:
999065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake            success = success and compile_dir(dir, maxlevels, None, force)
1009065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    return success
1013bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
1023bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumdef main():
103c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    """Script main program."""
104c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    import getopt
105c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    try:
10612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        opts, args = getopt.getopt(sys.argv[1:], 'lfd:x:')
107c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    except getopt.error, msg:
10845e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print msg
10912b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "usage: python compileall.py [-l] [-f] [-d destdir] " \
11012b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton              "[-s regexp] [directory ...]"
11145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "-l: don't recurse down"
1120b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum        print "-f: force rebuild even if timestamps are up-to-date"
11345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "-d destdir: purported directory name for error messages"
11412b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "   if no directory arguments, -l sys.path is assumed"
11512b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "-x regexp: skip files matching the regular expression regexp"
11612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        print "   the regexp is search for in the full path of the file"
11745e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        sys.exit(2)
118c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    maxlevels = 10
119c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    ddir = None
1200b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum    force = 0
12112b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton    rx = None
122c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    for o, a in opts:
12345e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if o == '-l': maxlevels = 0
12445e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if o == '-d': ddir = a
1250b56a3e9a78f3e49a6c4c17842e18c59bcf75cb4Guido van Rossum        if o == '-f': force = 1
12612b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton        if o == '-x':
12712b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            import re
12812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton            rx = re.compile(a)
129c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    if ddir:
13045e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if len(args) != 1:
13145e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            print "-d destdir require exactly one directory argument"
13245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            sys.exit(2)
1339065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    success = 1
134c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    try:
13545e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        if args:
13645e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum            for dir in args:
13712b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                if not compile_dir(dir, maxlevels, ddir, force, rx):
13812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton                    success = 0
13945e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        else:
1409065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake            success = compile_path()
141c567b8176a51a9ebd8bdeaa4d8f0771cf05f7c7aGuido van Rossum    except KeyboardInterrupt:
14245e2fbc2e70ef28b1f0327207f33dab3a4e825c5Guido van Rossum        print "\n[interrupt]"
1439065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake        success = 0
1449065ea36deb5812654c1959413a92cfb18ad3b5aFred Drake    return success
1453bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossum
1463bb54487675cd28166fc7271b5788b185bcc1b63Guido van Rossumif __name__ == '__main__':
14712b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton    exit_status = not main()
14812b6457e24924ff60cf89fd19a584185a5d6c256Jeremy Hylton    sys.exit(exit_status)
149