diff -r 5176e8a2e258 Doc/library/compileall.rst --- a/Doc/library/compileall.rst Wed Dec 09 19:45:07 2015 +0200 +++ b/Doc/library/compileall.rst Sat Dec 19 17:31:10 2015 -0500 @@ -103,7 +103,8 @@ .. 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. + files along the way. Return 1 if all the files compiled successfully, and 0 + otherwise. The *maxlevels* parameter is used to limit the depth of the recursion; it defaults to ``10``. @@ -155,7 +156,8 @@ .. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, legacy=False, optimize=-1) - Compile the file with path *fullname*. + Compile the file with path *fullname*. Return 1 if the file compiled successfully, + and 0 otherwise. If *ddir* is given, it is prepended to the path to the file being compiled for use in compilation time tracebacks, and is also compiled in to the @@ -191,8 +193,10 @@ .. 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 + Byte-compile all the :file:`.py` files found along ``sys.path``. Return 1 if + all the files compiled successfully, and 0 otherwise. + + If *skip_curdir* is true (the default), the current directory is not included in the search. All other parameters are passed to the :func:`compile_dir` function. Note that unlike the other compile functions, ``maxlevels`` defaults to ``0``. diff -r 5176e8a2e258 Lib/test/test_compileall.py --- a/Lib/test/test_compileall.py Wed Dec 09 19:45:07 2015 +0200 +++ b/Lib/test/test_compileall.py Sat Dec 19 17:31:10 2015 -0500 @@ -1,6 +1,7 @@ import sys import compileall import importlib.util +import test.test_importlib.util import os import pathlib import py_compile @@ -40,6 +41,11 @@ def tearDown(self): shutil.rmtree(self.directory) + def add_bad_source_file(self): + self.bad_source_path = os.path.join(self.directory, '_test_bad.py') + with open(self.bad_source_path, 'w') as file: + file.write('x (\n') + def data(self): with open(self.bc_path, 'rb') as file: data = file.read(8) @@ -78,15 +84,35 @@ os.unlink(fn) except: pass - compileall.compile_file(self.source_path, force=False, quiet=True) + ret = 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)) + self.assertEqual(ret, 1) os.unlink(self.bc_path) - compileall.compile_dir(self.directory, force=False, quiet=True) + ret = compileall.compile_dir(self.directory, force=False, quiet=True) self.assertTrue(os.path.isfile(self.bc_path) and os.path.isfile(self.bc_path2)) + self.assertEqual(ret, 1) os.unlink(self.bc_path) os.unlink(self.bc_path2) + # Test against bad files + self.add_bad_source_file() + ret = compileall.compile_file(self.bad_source_path, + force=False, quiet=2) + self.assertEqual(ret, 0) + ret = compileall.compile_dir(self.directory, + force=False, quiet=2) + self.assertEqual(ret, 0) + + def test_compile_path(self): + ret = compileall.compile_path(quiet=2) + self.assertEqual(ret, 1) + + with test.test_importlib.util.import_state(path=[self.directory]): + self.add_bad_source_file() + ret = compileall.compile_path(skip_curdir=False, force=True, quiet=2) + self.assertEqual(ret, 0) def test_no_pycache_in_non_package(self): # Bug 8563 reported that __pycache__ directories got created by