mirror of
				https://github.com/python/cpython.git
				synced 2025-10-29 20:51:26 +00:00 
			
		
		
		
	- Issue #8140: extend compileall to compile single files. Add -i option.
This commit is contained in:
		
							parent
							
								
									dc36472472
								
							
						
					
					
						commit
						b13d04c991
					
				
					 3 changed files with 116 additions and 42 deletions
				
			
		|  | @ -17,7 +17,7 @@ | |||
| import struct | ||||
| import imp | ||||
| 
 | ||||
| __all__ = ["compile_dir","compile_path"] | ||||
| __all__ = ["compile_dir","compile_files","compile_path"] | ||||
| 
 | ||||
| def compile_dir(dir, maxlevels=10, ddir=None, | ||||
|                 force=0, rx=None, quiet=0): | ||||
|  | @ -44,6 +44,34 @@ def compile_dir(dir, maxlevels=10, ddir=None, | |||
|     success = 1 | ||||
|     for name in names: | ||||
|         fullname = os.path.join(dir, name) | ||||
|         if ddir is not None: | ||||
|             dfile = os.path.join(ddir, name) | ||||
|         else: | ||||
|             dfile = None | ||||
|         if not os.path.isdir(fullname): | ||||
|             if not compile_file(fullname, ddir, force, rx, quiet): | ||||
|                 success = 0 | ||||
|         elif maxlevels > 0 and \ | ||||
|              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): | ||||
|                 success = 0 | ||||
|     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: | ||||
|  | @ -51,7 +79,7 @@ def compile_dir(dir, maxlevels=10, ddir=None, | |||
|     if rx is not None: | ||||
|         mo = rx.search(fullname) | ||||
|         if mo: | ||||
|                 continue | ||||
|             return success | ||||
|     if os.path.isfile(fullname): | ||||
|         head, tail = name[:-3], name[-3:] | ||||
|         if tail == '.py': | ||||
|  | @ -63,7 +91,7 @@ def compile_dir(dir, maxlevels=10, ddir=None, | |||
|                     with open(cfile, 'rb') as chandle: | ||||
|                         actual = chandle.read(8) | ||||
|                     if expect == actual: | ||||
|                             continue | ||||
|                         return success | ||||
|                 except IOError: | ||||
|                     pass | ||||
|             if not quiet: | ||||
|  | @ -81,13 +109,6 @@ def compile_dir(dir, maxlevels=10, ddir=None, | |||
|             else: | ||||
|                 if ok == 0: | ||||
|                     success = 0 | ||||
|         elif maxlevels > 0 and \ | ||||
|              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): | ||||
|                 success = 0 | ||||
|     return success | ||||
| 
 | ||||
| def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0): | ||||
|  | @ -110,15 +131,34 @@ def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0): | |||
|                                               force, quiet=quiet) | ||||
|     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(): | ||||
|     """Script main program.""" | ||||
|     import getopt | ||||
|     try: | ||||
|         opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:') | ||||
|         opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:i:') | ||||
|     except getopt.error, msg: | ||||
|         print msg | ||||
|         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 "-f: force rebuild even if timestamps are up-to-date" | ||||
|         print "-q: quiet operation" | ||||
|  | @ -126,12 +166,14 @@ def main(): | |||
|         print "   if no directory arguments, -l sys.path is assumed" | ||||
|         print "-x regexp: skip files matching the regular expression regexp" | ||||
|         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) | ||||
|     maxlevels = 10 | ||||
|     ddir = None | ||||
|     force = 0 | ||||
|     quiet = 0 | ||||
|     rx = None | ||||
|     flist = None | ||||
|     for o, a in opts: | ||||
|         if o == '-l': maxlevels = 0 | ||||
|         if o == '-d': ddir = a | ||||
|  | @ -140,17 +182,28 @@ def main(): | |||
|         if o == '-x': | ||||
|             import re | ||||
|             rx = re.compile(a) | ||||
|         if o == '-i': flist = a | ||||
|     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" | ||||
|             sys.exit(2) | ||||
|     success = 1 | ||||
|     try: | ||||
|         if args: | ||||
|             for dir in args: | ||||
|                 if not compile_dir(dir, maxlevels, ddir, | ||||
|         if args or flist: | ||||
|             try: | ||||
|                 if flist: | ||||
|                     args = expand_args(args, flist) | ||||
|             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: | ||||
|             success = compile_path() | ||||
|     except KeyboardInterrupt: | ||||
|  |  | |||
|  | @ -17,6 +17,9 @@ def setUp(self): | |||
|         self.bc_path = self.source_path + ('c' if __debug__ else 'o') | ||||
|         with open(self.source_path, 'w') as file: | ||||
|             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): | ||||
|         shutil.rmtree(self.directory) | ||||
|  | @ -52,6 +55,22 @@ def test_magic_number(self): | |||
|         # Test a change in mtime leads to a new .pyc. | ||||
|         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(): | ||||
|     test_support.run_unittest(CompileallTests) | ||||
|  |  | |||
|  | @ -20,6 +20,8 @@ Core and Builtins | |||
| Library | ||||
| ------- | ||||
| 
 | ||||
| - Issue #8140: extend compileall to compile single files. Add -i option. | ||||
| 
 | ||||
| - Issue #7356: ctypes.util: Make parsing of ldconfig output independent of | ||||
|   the locale. | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Matthias Klose
						Matthias Klose