bpo-22640: Add silent mode to py_compile.compile() (GH-12976)

This commit is contained in:
Joannah Nanjekye 2019-05-28 13:29:04 -03:00 committed by Berker Peksag
parent 3c8724fc60
commit 2e33ecd7c9
5 changed files with 43 additions and 9 deletions

View File

@ -42,6 +42,13 @@ byte-code cache files in the directory containing the source code.
is raised. This function returns the path to byte-compiled file, i.e. is raised. This function returns the path to byte-compiled file, i.e.
whatever *cfile* value was used. whatever *cfile* value was used.
The *doraise* and *quiet* arguments determine how errors are handled while
compiling file. If *quiet* is 0 or 1, and *doraise* is false, the default
behaviour is enabled: an error string is written to ``sys.stderr``, and the
function returns ``None`` instead of a path. If *doraise* is true,
a :exc:`PyCompileError` is raised instead. However if *quiet* is 2,
no message is written, and *doraise* has no effect.
If the path that *cfile* becomes (either explicitly specified or computed) If the path that *cfile* becomes (either explicitly specified or computed)
is a symlink or non-regular file, :exc:`FileExistsError` will be raised. is a symlink or non-regular file, :exc:`FileExistsError` will be raised.
This is to act as a warning that import will turn those paths into regular This is to act as a warning that import will turn those paths into regular
@ -82,6 +89,9 @@ byte-code cache files in the directory containing the source code.
overrides the value of the *invalidation_mode* argument, and determines overrides the value of the *invalidation_mode* argument, and determines
its default value instead. its default value instead.
.. versionchanged:: 3.8
The *quiet* parameter was added.
.. class:: PycInvalidationMode .. class:: PycInvalidationMode

View File

@ -537,6 +537,13 @@ NSKeyedArchiver-encoded binary plists.
(Contributed by Jon Janzen in :issue:`26707`.) (Contributed by Jon Janzen in :issue:`26707`.)
py_compile
----------
:func:`py_compile.compile` now supports silent mode.
(Contributed by Joannah Nanjekye in :issue:`22640`.)
socket socket
------ ------

View File

@ -77,7 +77,7 @@ def _get_default_invalidation_mode():
def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1, def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1,
invalidation_mode=None): invalidation_mode=None, quiet=0):
"""Byte-compile one Python source file to Python bytecode. """Byte-compile one Python source file to Python bytecode.
:param file: The source file name. :param file: The source file name.
@ -95,6 +95,8 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1,
are -1, 0, 1 and 2. A value of -1 means to use the optimization are -1, 0, 1 and 2. A value of -1 means to use the optimization
level of the current interpreter, as given by -O command line options. level of the current interpreter, as given by -O command line options.
:param invalidation_mode: :param invalidation_mode:
:param quiet: Return full output with False or 0, errors only with 1,
and no output with 2.
:return: Path to the resulting byte compiled file. :return: Path to the resulting byte compiled file.
@ -143,11 +145,12 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1,
_optimize=optimize) _optimize=optimize)
except Exception as err: except Exception as err:
py_exc = PyCompileError(err.__class__, err, dfile or file) py_exc = PyCompileError(err.__class__, err, dfile or file)
if doraise: if quiet < 2:
raise py_exc if doraise:
else: raise py_exc
sys.stderr.write(py_exc.msg + '\n') else:
return sys.stderr.write(py_exc.msg + '\n')
return
try: try:
dirname = os.path.dirname(cfile) dirname = os.path.dirname(cfile)
if dirname: if dirname:
@ -194,10 +197,12 @@ def main(args=None):
compile(filename, doraise=True) compile(filename, doraise=True)
except PyCompileError as error: except PyCompileError as error:
rv = 1 rv = 1
sys.stderr.write("%s\n" % error.msg) if quiet < 2:
sys.stderr.write("%s\n" % error.msg)
except OSError as error: except OSError as error:
rv = 1 rv = 1
sys.stderr.write("%s\n" % error) if quiet < 2:
sys.stderr.write("%s\n" % error)
else: else:
for filename in args: for filename in args:
try: try:
@ -205,7 +210,8 @@ def main(args=None):
except PyCompileError as error: except PyCompileError as error:
# return value to indicate at least one failure # return value to indicate at least one failure
rv = 1 rv = 1
sys.stderr.write("%s\n" % error.msg) if quiet < 2:
sys.stderr.write("%s\n" % error.msg)
return rv return rv
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -192,6 +192,15 @@ class PyCompileTestsBase:
fp.read(), 'test', {}) fp.read(), 'test', {})
self.assertEqual(flags, 0b1) self.assertEqual(flags, 0b1)
def test_quiet(self):
bad_coding = os.path.join(os.path.dirname(__file__), 'bad_coding2.py')
with support.captured_stderr() as stderr:
self.assertIsNone(py_compile.compile(bad_coding, doraise=False, quiet=2))
self.assertIsNone(py_compile.compile(bad_coding, doraise=True, quiet=2))
self.assertEqual(stderr.getvalue(), '')
with self.assertRaises(py_compile.PyCompileError):
py_compile.compile(bad_coding, doraise=True, quiet=1)
class PyCompileTestsWithSourceEpoch(PyCompileTestsBase, class PyCompileTestsWithSourceEpoch(PyCompileTestsBase,
unittest.TestCase, unittest.TestCase,

View File

@ -0,0 +1,2 @@
:func:`py_compile.compile` now supports silent mode.
Patch by Joannah Nanjekye