diff options
author | Brett Cannon <bcannon@gmail.com> | 2009-02-10 02:07:38 (GMT) |
---|---|---|
committer | Brett Cannon <bcannon@gmail.com> | 2009-02-10 02:07:38 (GMT) |
commit | 28d108893c5a6663c1747b1c79d0432ba7794e63 (patch) | |
tree | 5d1379f9d117b038507be68206d60e541898e718 /Lib/compileall.py | |
parent | 322daea7c3ba7fa73b09ebd50a78078d23d318a5 (diff) | |
download | cpython-28d108893c5a6663c1747b1c79d0432ba7794e63.zip cpython-28d108893c5a6663c1747b1c79d0432ba7794e63.tar.gz cpython-28d108893c5a6663c1747b1c79d0432ba7794e63.tar.bz2 |
compileall used the ctime of bytecode and source to determine if the bytecode
should be recreated. This created a timing hole. Fixed by just doing what
import does; check the mtime and magic number.
Diffstat (limited to 'Lib/compileall.py')
-rw-r--r-- | Lib/compileall.py | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/Lib/compileall.py b/Lib/compileall.py index a5c82a3..f99b834 100644 --- a/Lib/compileall.py +++ b/Lib/compileall.py @@ -11,10 +11,11 @@ packages -- for now, you'll have to deal with packages separately.) See module py_compile for details of the actual byte-compilation. """ - import os import sys import py_compile +import struct +import imp __all__ = ["compile_dir","compile_path"] @@ -54,11 +55,17 @@ def compile_dir(dir, maxlevels=10, ddir=None, if os.path.isfile(fullname): head, tail = name[:-3], name[-3:] if tail == '.py': - cfile = fullname + (__debug__ and 'c' or 'o') - ftime = os.stat(fullname).st_mtime - try: ctime = os.stat(cfile).st_mtime - except os.error: ctime = 0 - if (ctime > ftime) and not force: continue + if not force: + try: + mtime = os.stat(fullname).st_mtime + expect = struct.pack('<4sl', imp.get_magic(), mtime) + cfile = fullname + (__debug__ and 'c' or 'o') + with open(cfile, 'rb') as chandle: + actual = chandle.read(8) + if expect == actual: + continue + except IOError: + pass if not quiet: print 'Compiling', fullname, '...' try: @@ -80,7 +87,8 @@ def compile_dir(dir, maxlevels=10, ddir=None, name != os.curdir and name != os.pardir and \ os.path.isdir(fullname) and \ not os.path.islink(fullname): - if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, quiet): + if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, + quiet): success = 0 return success |