diff -r 4ff37fbcd4e8 Doc/library/compileall.rst --- a/Doc/library/compileall.rst Wed Apr 23 15:37:37 2014 -0500 +++ b/Doc/library/compileall.rst Wed Apr 23 18:28:22 2014 -0700 @@ -38,7 +38,8 @@ .. cmdoption:: -q - Do not print the list of files compiled, print only error messages. + Do not print the list of files compiled. If passed once, error messages will + still be printed. If passed twice (``-qq``), all output is suppressed. .. cmdoption:: -d destdir @@ -76,7 +77,7 @@ Public functions ---------------- -.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) +.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1) Recursively descend the directory tree named by *dir*, compiling all :file:`.py` files along the way. @@ -97,8 +98,9 @@ file considered for compilation, and if it returns a true value, the file is skipped. - If *quiet* is true, nothing is printed to the standard output unless errors - occur. + If *quiet* is 0 (the default), the filenames and other information are + printed to standard out. Set to 1, only errors are printed. Set to 2, all + output is suppressed. If *legacy* is true, byte-code files are written to their legacy locations and names, which may overwrite byte-code files created by another version of @@ -112,8 +114,10 @@ .. versionchanged:: 3.2 Added the *legacy* and *optimize* parameter. + .. versionchanged:: 3.5 + Added level 2 (no output) option to *quiet*. -.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1) +.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1) Compile the file with path *fullname*. @@ -127,8 +131,9 @@ file being compiled, and if it returns a true value, the file is not compiled and ``True`` is returned. - If *quiet* is true, nothing is printed to the standard output unless errors - occur. + If *quiet* is 0 (the default), the filenames and other information are + printed to standard out. Set to 1, only errors are printed. Set to 2, all + output is suppressed. If *legacy* is true, byte-code files are written to their legacy locations and names, which may overwrite byte-code files created by another version of @@ -141,8 +146,10 @@ .. versionadded:: 3.2 + .. versionchanged:: 3.5 + Added level 2 (no output) option to *quiet*. -.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, legacy=False, optimize=-1) +.. function:: compile_path(skip_curdir=True, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1) Byte-compile all the :file:`.py` files found along ``sys.path``. If *skip_curdir* is true (the default), the current directory is not included @@ -153,6 +160,8 @@ .. versionchanged:: 3.2 Added the *legacy* and *optimize* parameter. + .. versionchanged:: 3.5 + Added level 2 (no output) option to *quiet*. To force a recompile of all the :file:`.py` files in the :file:`Lib/` subdirectory and all its subdirectories:: diff -r 4ff37fbcd4e8 Lib/compileall.py --- a/Lib/compileall.py Wed Apr 23 15:37:37 2014 -0500 +++ b/Lib/compileall.py Wed Apr 23 18:28:22 2014 -0700 @@ -19,7 +19,7 @@ __all__ = ["compile_dir","compile_file","compile_path"] def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, - quiet=False, legacy=False, optimize=-1): + quiet=0, legacy=False, optimize=-1): """Byte-compile all modules in the given directory tree. Arguments (only dir is required): @@ -29,7 +29,7 @@ ddir: the directory that will be prepended to the path to the file as it is compiled into each byte-code file. force: if True, force compilation, even if timestamps are up-to-date - quiet: if True, be quiet during compilation + quiet: full output with 0, errors only with 1, no output with 2 legacy: if True, produce legacy pyc paths instead of PEP 3147 paths optimize: optimization level or -1 for level of the interpreter """ @@ -38,7 +38,8 @@ try: names = os.listdir(dir) except OSError: - print("Can't list {!r}".format(dir)) + if quiet < 2: + print("Can't list {!r}".format(dir)) names = [] names.sort() success = 1 @@ -61,7 +62,7 @@ success = 0 return success -def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False, +def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1): """Byte-compile one file. @@ -71,7 +72,7 @@ ddir: if given, the directory name compiled in to the byte-code file. force: if True, force compilation, even if timestamps are up-to-date - quiet: if True, be quiet during compilation + quiet: full output with 0, errors only with 1, no output with 2 legacy: if True, produce legacy pyc paths instead of PEP 3147 paths optimize: optimization level or -1 for level of the interpreter """ @@ -114,7 +115,10 @@ ok = py_compile.compile(fullname, cfile, dfile, True, optimize=optimize) except py_compile.PyCompileError as err: - if quiet: + success = 0 + if quiet >= 2: + return success + elif quiet: print('*** Error compiling {!r}...'.format(fullname)) else: print('*** ', end='') @@ -123,20 +127,21 @@ errors='backslashreplace') msg = msg.decode(sys.stdout.encoding) print(msg) + except (SyntaxError, UnicodeError, OSError) as e: success = 0 - except (SyntaxError, UnicodeError, OSError) as e: - if quiet: + if quiet >= 2: + return success + elif quiet: print('*** Error compiling {!r}...'.format(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=False, quiet=False, +def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=0, legacy=False, optimize=-1): """Byte-compile all module on sys.path. @@ -145,14 +150,15 @@ skip_curdir: if true, skip current directory (default True) maxlevels: max recursion level (default 0) force: as for compile_dir() (default False) - quiet: as for compile_dir() (default False) + quiet: as for compile_dir() (default 0) legacy: as for compile_dir() (default False) optimize: as for compile_dir() (default -1) """ success = 1 for dir in sys.path: if (not dir or dir == os.curdir) and skip_curdir: - print('Skipping current directory') + if quiet < 2: + print('Skipping current directory') else: success = success and compile_dir(dir, maxlevels, None, force, quiet=quiet, @@ -171,8 +177,9 @@ help="don't recurse into subdirectories") parser.add_argument('-f', action='store_true', dest='force', help='force rebuild even if timestamps are up to date') - parser.add_argument('-q', action='store_true', dest='quiet', - help='output only error messages') + parser.add_argument('-q', action='count', dest='quiet', default=0, + help='output only error messages; -qq will suppress ' + 'the error messages as well.') parser.add_argument('-b', action='store_true', dest='legacy', help='use legacy (pre-PEP3147) compiled file locations') parser.add_argument('-d', metavar='DESTDIR', dest='ddir', default=None, @@ -210,7 +217,8 @@ for line in f: compile_dests.append(line.strip()) except OSError: - print("Error reading file list {}".format(args.flist)) + if args.quiet < 2: + print("Error reading file list {}".format(args.flist)) return False success = True @@ -231,7 +239,8 @@ return compile_path(legacy=args.legacy, force=args.force, quiet=args.quiet) except KeyboardInterrupt: - print("\n[interrupted]") + if args.quiet < 2: + print("\n[interrupted]") return False return True diff -r 4ff37fbcd4e8 Lib/test/test_compileall.py --- a/Lib/test/test_compileall.py Wed Apr 23 15:37:37 2014 -0500 +++ b/Lib/test/test_compileall.py Wed Apr 23 18:28:22 2014 -0700 @@ -278,6 +278,13 @@ quiet = self.assertRunOK('-q', self.pkgdir) self.assertNotEqual(b'', noisy) self.assertEqual(b'', quiet) + + def test_silent(self): + script_helper.make_script(self.pkgdir, 'crunchyfrog', 'bad(syntax') + _, quiet, _ = self.assertRunNotOK('-q', self.pkgdir) + _, silent, _ = self.assertRunNotOK('-qq', self.pkgdir) + self.assertNotEqual(b'', quiet) + self.assertEqual(b'', silent) def test_regexp(self): self.assertRunOK('-q', '-x', r'ba[^\\/]*$', self.pkgdir)