Merged revisions 78983,78985 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk ........ r78983 | matthias.klose | 2010-03-15 18:44:12 +0100 (Mo, 15 Mär 2010) | 2 lines - Issue #8140: extend compileall to compile single files. Add -i option. ........ r78985 | matthias.klose | 2010-03-15 19:00:01 +0100 (Mo, 15 Mär 2010) | 2 lines - Fix typo in Lib/compileall.py(__all__). ........
This commit is contained in:
parent
82f60910b7
commit
c33b902ebb
|
@ -17,7 +17,7 @@ import py_compile
|
||||||
import struct
|
import struct
|
||||||
import imp
|
import imp
|
||||||
|
|
||||||
__all__ = ["compile_dir","compile_path"]
|
__all__ = ["compile_dir","compile_file","compile_path"]
|
||||||
|
|
||||||
def compile_dir(dir, maxlevels=10, ddir=None,
|
def compile_dir(dir, maxlevels=10, ddir=None,
|
||||||
force=0, rx=None, quiet=0):
|
force=0, rx=None, quiet=0):
|
||||||
|
@ -48,47 +48,9 @@ def compile_dir(dir, maxlevels=10, ddir=None,
|
||||||
dfile = os.path.join(ddir, name)
|
dfile = os.path.join(ddir, name)
|
||||||
else:
|
else:
|
||||||
dfile = None
|
dfile = None
|
||||||
if rx is not None:
|
if not os.path.isdir(fullname):
|
||||||
mo = rx.search(fullname)
|
if not compile_file(fullname, ddir, force, rx, quiet):
|
||||||
if mo:
|
success = 0
|
||||||
continue
|
|
||||||
if os.path.isfile(fullname):
|
|
||||||
head, tail = name[:-3], name[-3:]
|
|
||||||
if tail == '.py':
|
|
||||||
if not force:
|
|
||||||
try:
|
|
||||||
mtime = int(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:
|
|
||||||
ok = py_compile.compile(fullname, None, dfile, True)
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise KeyboardInterrupt
|
|
||||||
except py_compile.PyCompileError as err:
|
|
||||||
if quiet:
|
|
||||||
print('*** Error compiling', fullname, '...')
|
|
||||||
else:
|
|
||||||
print('*** ', end='')
|
|
||||||
print(err.msg)
|
|
||||||
success = 0
|
|
||||||
except (SyntaxError, UnicodeError, IOError) as e:
|
|
||||||
if quiet:
|
|
||||||
print('*** Error compiling', fullname, '...')
|
|
||||||
else:
|
|
||||||
print('*** ', end='')
|
|
||||||
print(e.__class__.__name__ + ':', e)
|
|
||||||
success = 0
|
|
||||||
else:
|
|
||||||
if ok == 0:
|
|
||||||
success = 0
|
|
||||||
elif maxlevels > 0 and \
|
elif maxlevels > 0 and \
|
||||||
name != os.curdir and name != os.pardir and \
|
name != os.curdir and name != os.pardir and \
|
||||||
os.path.isdir(fullname) and \
|
os.path.isdir(fullname) and \
|
||||||
|
@ -98,6 +60,64 @@ def compile_dir(dir, maxlevels=10, ddir=None,
|
||||||
success = 0
|
success = 0
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
def compile_file(fullname, ddir=None, force=0, rx=None, quiet=0):
|
||||||
|
"""Byte-compile file.
|
||||||
|
file: the file to byte-compile
|
||||||
|
ddir: if given, purported directory name (this is the
|
||||||
|
directory name that will show up in error messages)
|
||||||
|
force: if 1, force compilation, even if timestamps are up-to-date
|
||||||
|
quiet: if 1, be quiet during compilation
|
||||||
|
|
||||||
|
"""
|
||||||
|
success = 1
|
||||||
|
name = os.path.basename(fullname)
|
||||||
|
if ddir is not None:
|
||||||
|
dfile = os.path.join(ddir, name)
|
||||||
|
else:
|
||||||
|
dfile = None
|
||||||
|
if rx is not None:
|
||||||
|
mo = rx.search(fullname)
|
||||||
|
if mo:
|
||||||
|
return success
|
||||||
|
if os.path.isfile(fullname):
|
||||||
|
head, tail = name[:-3], name[-3:]
|
||||||
|
if tail == '.py':
|
||||||
|
if not force:
|
||||||
|
try:
|
||||||
|
mtime = int(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:
|
||||||
|
return success
|
||||||
|
except IOError:
|
||||||
|
pass
|
||||||
|
if not quiet:
|
||||||
|
print('Compiling', fullname, '...')
|
||||||
|
try:
|
||||||
|
ok = py_compile.compile(fullname, None, dfile, True)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise KeyboardInterrupt
|
||||||
|
except py_compile.PyCompileError as err:
|
||||||
|
if quiet:
|
||||||
|
print('*** Error compiling', fullname, '...')
|
||||||
|
else:
|
||||||
|
print('*** ', end='')
|
||||||
|
print(err.msg)
|
||||||
|
success = 0
|
||||||
|
except (SyntaxError, UnicodeError, IOError) as e:
|
||||||
|
if quiet:
|
||||||
|
print('*** Error compiling', fullname, '...')
|
||||||
|
else:
|
||||||
|
print('*** ', end='')
|
||||||
|
print(e.__class__.__name__ + ':', e)
|
||||||
|
success = 0
|
||||||
|
else:
|
||||||
|
if ok == 0:
|
||||||
|
success = 0
|
||||||
|
return success
|
||||||
|
|
||||||
def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
|
def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
|
||||||
"""Byte-compile all module on sys.path.
|
"""Byte-compile all module on sys.path.
|
||||||
|
|
||||||
|
@ -118,15 +138,34 @@ def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
|
||||||
force, quiet=quiet)
|
force, quiet=quiet)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
def expand_args(args, flist):
|
||||||
|
"""read names in flist and append to args"""
|
||||||
|
expanded = args[:]
|
||||||
|
if flist:
|
||||||
|
try:
|
||||||
|
if flist == '-':
|
||||||
|
fd = sys.stdin
|
||||||
|
else:
|
||||||
|
fd = open(flist)
|
||||||
|
while 1:
|
||||||
|
line = fd.readline()
|
||||||
|
if not line:
|
||||||
|
break
|
||||||
|
expanded.append(line[:-1])
|
||||||
|
except IOError:
|
||||||
|
print("Error reading file list %s" % flist)
|
||||||
|
raise
|
||||||
|
return expanded
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
"""Script main program."""
|
"""Script main program."""
|
||||||
import getopt
|
import getopt
|
||||||
try:
|
try:
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:')
|
opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:i:')
|
||||||
except getopt.error as msg:
|
except getopt.error as msg:
|
||||||
print(msg)
|
print(msg)
|
||||||
print("usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
|
print("usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
|
||||||
"[-x regexp] [directory ...]")
|
"[-x regexp] [-i list] [directory|file ...]")
|
||||||
print("-l: don't recurse down")
|
print("-l: don't recurse down")
|
||||||
print("-f: force rebuild even if timestamps are up-to-date")
|
print("-f: force rebuild even if timestamps are up-to-date")
|
||||||
print("-q: quiet operation")
|
print("-q: quiet operation")
|
||||||
|
@ -134,12 +173,14 @@ def main():
|
||||||
print(" if no directory arguments, -l sys.path is assumed")
|
print(" if no directory arguments, -l sys.path is assumed")
|
||||||
print("-x regexp: skip files matching the regular expression regexp")
|
print("-x regexp: skip files matching the regular expression regexp")
|
||||||
print(" the regexp is searched for in the full path of the file")
|
print(" the regexp is searched for in the full path of the file")
|
||||||
|
print("-i list: expand list with its content (file and directory names)")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
maxlevels = 10
|
maxlevels = 10
|
||||||
ddir = None
|
ddir = None
|
||||||
force = 0
|
force = 0
|
||||||
quiet = 0
|
quiet = 0
|
||||||
rx = None
|
rx = None
|
||||||
|
flist = None
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
if o == '-l': maxlevels = 0
|
if o == '-l': maxlevels = 0
|
||||||
if o == '-d': ddir = a
|
if o == '-d': ddir = a
|
||||||
|
@ -148,17 +189,28 @@ def main():
|
||||||
if o == '-x':
|
if o == '-x':
|
||||||
import re
|
import re
|
||||||
rx = re.compile(a)
|
rx = re.compile(a)
|
||||||
|
if o == '-i': flist = a
|
||||||
if ddir:
|
if ddir:
|
||||||
if len(args) != 1:
|
if len(args) != 1 and not os.path.isdir(args[0]):
|
||||||
print("-d destdir require exactly one directory argument")
|
print("-d destdir require exactly one directory argument")
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
success = 1
|
success = 1
|
||||||
try:
|
try:
|
||||||
if args:
|
if args or flist:
|
||||||
for dir in args:
|
try:
|
||||||
if not compile_dir(dir, maxlevels, ddir,
|
if flist:
|
||||||
force, rx, quiet):
|
args = expand_args(args, flist)
|
||||||
success = 0
|
except IOError:
|
||||||
|
success = 0
|
||||||
|
if success:
|
||||||
|
for arg in args:
|
||||||
|
if os.path.isdir(arg):
|
||||||
|
if not compile_dir(arg, maxlevels, ddir,
|
||||||
|
force, rx, quiet):
|
||||||
|
success = 0
|
||||||
|
else:
|
||||||
|
if not compile_file(arg, ddir, force, rx, quiet):
|
||||||
|
success = 0
|
||||||
else:
|
else:
|
||||||
success = compile_path()
|
success = compile_path()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
|
|
|
@ -17,6 +17,9 @@ class CompileallTests(unittest.TestCase):
|
||||||
self.bc_path = self.source_path + ('c' if __debug__ else 'o')
|
self.bc_path = self.source_path + ('c' if __debug__ else 'o')
|
||||||
with open(self.source_path, 'w') as file:
|
with open(self.source_path, 'w') as file:
|
||||||
file.write('x = 123\n')
|
file.write('x = 123\n')
|
||||||
|
self.source_path2 = os.path.join(self.directory, '_test2.py')
|
||||||
|
self.bc_path2 = self.source_path2 + ('c' if __debug__ else 'o')
|
||||||
|
shutil.copyfile(self.source_path, self.source_path2)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
shutil.rmtree(self.directory)
|
shutil.rmtree(self.directory)
|
||||||
|
@ -52,6 +55,22 @@ class CompileallTests(unittest.TestCase):
|
||||||
# Test a change in mtime leads to a new .pyc.
|
# Test a change in mtime leads to a new .pyc.
|
||||||
self.recreation_check(b'\0\0\0\0')
|
self.recreation_check(b'\0\0\0\0')
|
||||||
|
|
||||||
|
def test_compile_files(self):
|
||||||
|
# Test compiling a single file, and complete directory
|
||||||
|
for fn in (self.bc_path, self.bc_path2):
|
||||||
|
try:
|
||||||
|
os.unlink(fn)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
compileall.compile_file(self.source_path, force=False, quiet=True)
|
||||||
|
self.assertTrue(os.path.isfile(self.bc_path) \
|
||||||
|
and not os.path.isfile(self.bc_path2))
|
||||||
|
os.unlink(self.bc_path)
|
||||||
|
compileall.compile_dir(self.directory, force=False, quiet=True)
|
||||||
|
self.assertTrue(os.path.isfile(self.bc_path) \
|
||||||
|
and os.path.isfile(self.bc_path2))
|
||||||
|
os.unlink(self.bc_path)
|
||||||
|
os.unlink(self.bc_path2)
|
||||||
|
|
||||||
def test_main():
|
def test_main():
|
||||||
support.run_unittest(CompileallTests)
|
support.run_unittest(CompileallTests)
|
||||||
|
|
|
@ -283,6 +283,8 @@ C-API
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #8140: extend compileall to compile single files. Add -i option.
|
||||||
|
|
||||||
- Issue #7356: ctypes.util: Make parsing of ldconfig output independent of
|
- Issue #7356: ctypes.util: Make parsing of ldconfig output independent of
|
||||||
the locale.
|
the locale.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue