[Python-checkins] cpython: Issue #21338: Add silent mode for compileall.

berker.peksag python-checkins at python.org
Wed Oct 15 10:10:21 CEST 2014


https://hg.python.org/cpython/rev/34436ae65523
changeset:   93065:34436ae65523
user:        Berker Peksag <berker.peksag at gmail.com>
date:        Wed Oct 15 11:10:57 2014 +0300
summary:
  Issue #21338: Add silent mode for compileall.

quiet parameters of compile_{dir, file, path} functions now have
a multilevel value.

Also, -q option of the CLI now have a multilevel value.

Patch by Thomas Kluyver.

files:
  Doc/library/compileall.rst  |  28 +++++++++++----
  Lib/compileall.py           |  45 +++++++++++++++---------
  Lib/test/test_compileall.py |   7 +++
  Misc/NEWS                   |   4 ++
  4 files changed, 59 insertions(+), 25 deletions(-)


diff --git a/Doc/library/compileall.rst b/Doc/library/compileall.rst
--- a/Doc/library/compileall.rst
+++ b/Doc/library/compileall.rst
@@ -42,7 +42,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
 
@@ -89,6 +90,9 @@
 .. versionchanged:: 3.5
    Added the  ``-j`` and ``-r`` options.
 
+.. versionchanged:: 3.5
+   ``-q`` option was changed to a multilevel value.
+
 
 There is no command-line option to control the optimization level used by the
 :func:`compile` function, because the Python interpreter itself already
@@ -97,7 +101,7 @@
 Public functions
 ----------------
 
-.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=False, legacy=False, optimize=-1, workers=1)
+.. function:: compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1, workers=1)
 
    Recursively descend the directory tree named by *dir*, compiling all :file:`.py`
    files along the way.
@@ -118,8 +122,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 ``False`` or ``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
@@ -142,8 +147,10 @@
    .. versionchanged:: 3.5
       Added the *workers* parameter.
 
+   .. versionchanged:: 3.5
+      *quiet* parameter was changed to a multilevel value.
 
-.. 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*.
 
@@ -157,8 +164,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 ``False`` or ``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
@@ -171,8 +179,10 @@
 
    .. versionadded:: 3.2
 
+   .. versionchanged:: 3.5
+      *quiet* parameter was changed to a multilevel value.
 
-.. 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
@@ -183,6 +193,8 @@
    .. versionchanged:: 3.2
       Added the *legacy* and *optimize* parameter.
 
+   .. versionchanged:: 3.5
+      *quiet* parameter was changed to a multilevel value.
 
 To force a recompile of all the :file:`.py` files in the :file:`Lib/`
 subdirectory and all its subdirectories::
diff --git a/Lib/compileall.py b/Lib/compileall.py
--- a/Lib/compileall.py
+++ b/Lib/compileall.py
@@ -24,13 +24,14 @@
 
 __all__ = ["compile_dir","compile_file","compile_path"]
 
-def _walk_dir(dir, ddir=None, maxlevels=10, quiet=False):
+def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0):
     if not quiet:
         print('Listing {!r}...'.format(dir))
     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()
     for name in names:
@@ -49,7 +50,7 @@
                                  maxlevels=maxlevels - 1, quiet=quiet)
 
 def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None,
-                quiet=False, legacy=False, optimize=-1, workers=1):
+                quiet=0, legacy=False, optimize=-1, workers=1):
     """Byte-compile all modules in the given directory tree.
 
     Arguments (only dir is required):
@@ -59,7 +60,8 @@
     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 False or 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
     workers:   maximum number of parallel workers
@@ -89,7 +91,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.
 
@@ -99,7 +101,8 @@
     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 False or 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
     """
@@ -142,7 +145,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='')
@@ -151,20 +157,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.
 
@@ -173,14 +180,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,
@@ -203,8 +211,9 @@
                               'then `-r` takes precedence.'))
     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,
@@ -250,7 +259,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
 
     if args.workers is not None:
@@ -274,7 +284,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 --git a/Lib/test/test_compileall.py b/Lib/test/test_compileall.py
--- a/Lib/test/test_compileall.py
+++ b/Lib/test/test_compileall.py
@@ -347,6 +347,13 @@
         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)
         self.assertNotCompiled(self.barfn)
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -175,6 +175,10 @@
 Library
 -------
 
+- Issue #21338: Add silent mode for compileall. quiet parameters of
+  compile_{dir, file, path} functions now have a multilevel value. Also,
+  -q option of the CLI now have a multilevel value. Patch by Thomas Kluyver.
+
 - Issue #20152: Convert the array and cmath modules to Argument Clinic.
 
 - Issue #18643: Add socket.socketpair() on Windows.

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list