Commit 812a2b65 authored by Berker Peksag's avatar Berker Peksag

Issue #28226: compileall now supports pathlib

parent b4b55eb5
...@@ -153,6 +153,9 @@ Public functions ...@@ -153,6 +153,9 @@ Public functions
The *legacy* parameter only writes out ``.pyc`` files, not ``.pyo`` files The *legacy* parameter only writes out ``.pyc`` files, not ``.pyo`` files
no matter what the value of *optimize* is. no matter what the value of *optimize* is.
.. versionchanged:: 3.6
Accepts a :term:`path-like object`.
.. function:: compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, 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*. Return a true value if the file Compile the file with path *fullname*. Return a true value if the file
...@@ -221,6 +224,9 @@ subdirectory and all its subdirectories:: ...@@ -221,6 +224,9 @@ subdirectory and all its subdirectories::
import re import re
compileall.compile_dir('Lib/', rx=re.compile(r'[/\\][.]svn'), force=True) compileall.compile_dir('Lib/', rx=re.compile(r'[/\\][.]svn'), force=True)
# pathlib.Path objects can also be used.
import pathlib
compileall.compile_dir(pathlib.Path('Lib/'), force=True)
.. seealso:: .. seealso::
......
...@@ -25,6 +25,8 @@ from functools import partial ...@@ -25,6 +25,8 @@ from functools import partial
__all__ = ["compile_dir","compile_file","compile_path"] __all__ = ["compile_dir","compile_file","compile_path"]
def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0): def _walk_dir(dir, ddir=None, maxlevels=10, quiet=0):
if quiet < 2 and isinstance(dir, os.PathLike):
dir = os.fspath(dir)
if not quiet: if not quiet:
print('Listing {!r}...'.format(dir)) print('Listing {!r}...'.format(dir))
try: try:
...@@ -105,6 +107,8 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0, ...@@ -105,6 +107,8 @@ def compile_file(fullname, ddir=None, force=False, rx=None, quiet=0,
optimize: optimization level or -1 for level of the interpreter optimize: optimization level or -1 for level of the interpreter
""" """
success = True success = True
if quiet < 2 and isinstance(fullname, os.PathLike):
fullname = os.fspath(fullname)
name = os.path.basename(fullname) name = os.path.basename(fullname)
if ddir is not None: if ddir is not None:
dfile = os.path.join(ddir, name) dfile = os.path.join(ddir, name)
......
...@@ -102,6 +102,22 @@ class CompileallTests(unittest.TestCase): ...@@ -102,6 +102,22 @@ class CompileallTests(unittest.TestCase):
self.assertFalse(compileall.compile_dir(self.directory, self.assertFalse(compileall.compile_dir(self.directory,
force=False, quiet=2)) force=False, quiet=2))
def test_compile_file_pathlike(self):
self.assertFalse(os.path.isfile(self.bc_path))
# we should also test the output
with support.captured_stdout() as stdout:
self.assertTrue(compileall.compile_file(pathlib.Path(self.source_path)))
self.assertEqual(stdout.getvalue(),
"Compiling '{}'...\n".format(self.source_path))
self.assertTrue(os.path.isfile(self.bc_path))
def test_compile_file_pathlike_ddir(self):
self.assertFalse(os.path.isfile(self.bc_path))
self.assertTrue(compileall.compile_file(pathlib.Path(self.source_path),
ddir=pathlib.Path('ddir_path'),
quiet=2))
self.assertTrue(os.path.isfile(self.bc_path))
def test_compile_path(self): def test_compile_path(self):
with test.test_importlib.util.import_state(path=[self.directory]): with test.test_importlib.util.import_state(path=[self.directory]):
self.assertTrue(compileall.compile_path(quiet=2)) self.assertTrue(compileall.compile_path(quiet=2))
...@@ -138,6 +154,13 @@ class CompileallTests(unittest.TestCase): ...@@ -138,6 +154,13 @@ class CompileallTests(unittest.TestCase):
optimization=opt) optimization=opt)
self.assertTrue(os.path.isfile(cached3)) self.assertTrue(os.path.isfile(cached3))
def test_compile_dir_pathlike(self):
self.assertFalse(os.path.isfile(self.bc_path))
with support.captured_stdout() as stdout:
compileall.compile_dir(pathlib.Path(self.directory))
self.assertIn("Listing '{}'...".format(self.directory), stdout.getvalue())
self.assertTrue(os.path.isfile(self.bc_path))
@mock.patch('compileall.ProcessPoolExecutor') @mock.patch('compileall.ProcessPoolExecutor')
def test_compile_pool_called(self, pool_mock): def test_compile_pool_called(self, pool_mock):
compileall.compile_dir(self.directory, quiet=True, workers=5) compileall.compile_dir(self.directory, quiet=True, workers=5)
......
...@@ -46,6 +46,8 @@ Core and Builtins ...@@ -46,6 +46,8 @@ Core and Builtins
Library Library
------- -------
- Issue #28226: compileall now supports pathlib.
- Issue #28314: Fix function declaration (C flags) for the getiterator() method - Issue #28314: Fix function declaration (C flags) for the getiterator() method
of xml.etree.ElementTree.Element. of xml.etree.ElementTree.Element.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment