Issue #21338: Add silent mode for compileall. · pythoncapi/cpython@6554b86 · GitHub
Skip to content

Commit 6554b86

Browse files
committed
Issue python#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.
1 parent 41d3196 commit 6554b86

4 files changed

Lines changed: 59 additions & 25 deletions

File tree

Doc/library/compileall.rst

Lines changed: 20 additions & 8 deletions

Lib/compileall.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@
2424

2525
__all__ = ["compile_dir","compile_file","compile_path"]
2626

27-
def _walk_dir(dir, ddir=None, maxlevels=10, quiet=False):
27+
def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0):
2828
if not quiet:
2929
print('Listing {!r}...'.format(dir))
3030
try:
3131
names = os.listdir(dir)
3232
except OSError:
33-
print("Can't list {!r}".format(dir))
33+
if quiet < 2:
34+
print("Can't list {!r}".format(dir))
3435
names = []
3536
names.sort()
3637
for name in names:
@@ -49,7 +50,7 @@ def _walk_dir(dir, ddir=None, maxlevels=10, quiet=False):
4950
maxlevels=maxlevels - 1, quiet=quiet)
5051

5152
def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None,
52-
quiet=False, legacy=False, optimize=-1, workers=1):
53+
quiet=0, legacy=False, optimize=-1, workers=1):
5354
"""Byte-compile all modules in the given directory tree.
5455
5556
Arguments (only dir is required):
@@ -59,7 +60,8 @@ def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None,
5960
ddir: the directory that will be prepended to the path to the
6061
file as it is compiled into each byte-code file.
6162
force: if True, force compilation, even if timestamps are up-to-date
62-
quiet: if True, be quiet during compilation
63+
quiet: full output with False or 0, errors only with 1,
64+
no output with 2
6365
legacy: if True, produce legacy pyc paths instead of PEP 3147 paths
6466
optimize: optimization level or -1 for level of the interpreter
6567
workers: maximum number of parallel workers
@@ -89,7 +91,7 @@ def compile_dir(dir, maxlevels=10, ddir=None, force=False, rx=None,
8991
success = 0
9092
return success
9193

92-
def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False,
94+
def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0,
9395
legacy=False, optimize=-1):
9496
"""Byte-compile one file.
9597
@@ -99,7 +101,8 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False,
99101
ddir: if given, the directory name compiled in to the
100102
byte-code file.
101103
force: if True, force compilation, even if timestamps are up-to-date
102-
quiet: if True, be quiet during compilation
104+
quiet: full output with False or 0, errors only with 1,
105+
no output with 2
103106
legacy: if True, produce legacy pyc paths instead of PEP 3147 paths
104107
optimize: optimization level or -1 for level of the interpreter
105108
"""
@@ -142,7 +145,10 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False,
142145
ok = py_compile.compile(fullname, cfile, dfile, True,
143146
optimize=optimize)
144147
except py_compile.PyCompileError as err:
145-
if quiet:
148+
success = 0
149+
if quiet >= 2:
150+
return success
151+
elif quiet:
146152
print('*** Error compiling {!r}...'.format(fullname))
147153
else:
148154
print('*** ', end='')
@@ -151,20 +157,21 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=False,
151157
errors='backslashreplace')
152158
msg = msg.decode(sys.stdout.encoding)
153159
print(msg)
154-
success = 0
155160
except (SyntaxError, UnicodeError, OSError) as e:
156-
if quiet:
161+
success = 0
162+
if quiet >= 2:
163+
return success
164+
elif quiet:
157165
print('*** Error compiling {!r}...'.format(fullname))
158166
else:
159167
print('*** ', end='')
160168
print(e.__class__.__name__ + ':', e)
161-
success = 0
162169
else:
163170
if ok == 0:
164171
success = 0
165172
return success
166173

167-
def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False,
174+
def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=0,
168175
legacy=False, optimize=-1):
169176
"""Byte-compile all module on sys.path.
170177
@@ -173,14 +180,15 @@ def compile_path(skip_curdir=1, maxlevels=0, force=False, quiet=False,
173180
skip_curdir: if true, skip current directory (default True)
174181
maxlevels: max recursion level (default 0)
175182
force: as for compile_dir() (default False)
176-
quiet: as for compile_dir() (default False)
183+
quiet: as for compile_dir() (default 0)
177184
legacy: as for compile_dir() (default False)
178185
optimize: as for compile_dir() (default -1)
179186
"""
180187
success = 1
181188
for dir in sys.path:
182189
if (not dir or dir == os.curdir) and skip_curdir:
183-
print('Skipping current directory')
190+
if quiet < 2:
191+
print('Skipping current directory')
184192
else:
185193
success = success and compile_dir(dir, maxlevels, None,
186194
force, quiet=quiet,
@@ -203,8 +211,9 @@ def main():
203211
'then `-r` takes precedence.'))
204212
parser.add_argument('-f', action='store_true', dest='force',
205213
help='force rebuild even if timestamps are up to date')
206-
parser.add_argument('-q', action='store_true', dest='quiet',
207-
help='output only error messages')
214+
parser.add_argument('-q', action='count', dest='quiet', default=0,
215+
help='output only error messages; -qq will suppress '
216+
'the error messages as well.')
208217
parser.add_argument('-b', action='store_true', dest='legacy',
209218
help='use legacy (pre-PEP3147) compiled file locations')
210219
parser.add_argument('-d', metavar='DESTDIR', dest='ddir', default=None,
@@ -250,7 +259,8 @@ def main():
250259
for line in f:
251260
compile_dests.append(line.strip())
252261
except OSError:
253-
print("Error reading file list {}".format(args.flist))
262+
if args.quiet < 2:
263+
print("Error reading file list {}".format(args.flist))
254264
return False
255265

256266
if args.workers is not None:
@@ -274,7 +284,8 @@ def main():
274284
return compile_path(legacy=args.legacy, force=args.force,
275285
quiet=args.quiet)
276286
except KeyboardInterrupt:
277-
print("\n[interrupted]")
287+
if args.quiet < 2:
288+
print("\n[interrupted]")
278289
return False
279290
return True
280291

Lib/test/test_compileall.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,13 @@ def test_quiet(self):
347347
self.assertNotEqual(b'', noisy)
348348
self.assertEqual(b'', quiet)
349349

350+
def test_silent(self):
351+
script_helper.make_script(self.pkgdir, 'crunchyfrog', 'bad(syntax')
352+
_, quiet, _ = self.assertRunNotOK('-q', self.pkgdir)
353+
_, silent, _ = self.assertRunNotOK('-qq', self.pkgdir)
354+
self.assertNotEqual(b'', quiet)
355+
self.assertEqual(b'', silent)
356+
350357
def test_regexp(self):
351358
self.assertRunOK('-q', '-x', r'ba[^\\/]*$', self.pkgdir)
352359
self.assertNotCompiled(self.barfn)

Misc/NEWS

Lines changed: 4 additions & 0 deletions

0 commit comments

Comments
 (0)