Update py_compile from CPython 3.10.6

This commit is contained in:
CPython Developers
2022-08-15 01:22:42 +09:00
committed by Jeong YunWon
parent adbed02ff2
commit 07be72d4b4
3 changed files with 119 additions and 44 deletions

84
Lib/py_compile.py vendored
View File

@@ -77,7 +77,7 @@ def _get_default_invalidation_mode():
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.
: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
level of the current interpreter, as given by -O command line options.
: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.
@@ -143,11 +145,12 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1,
_optimize=optimize)
except Exception as err:
py_exc = PyCompileError(err.__class__, err, dfile or file)
if doraise:
raise py_exc
else:
sys.stderr.write(py_exc.msg + '\n')
return
if quiet < 2:
if doraise:
raise py_exc
else:
sys.stderr.write(py_exc.msg + '\n')
return
try:
dirname = os.path.dirname(cfile)
if dirname:
@@ -170,43 +173,40 @@ def compile(file, cfile=None, dfile=None, doraise=False, optimize=-1,
return cfile
def main(args=None):
"""Compile several source files.
def main():
import argparse
The files named in 'args' (or on the command line, if 'args' is
not specified) are compiled and the resulting bytecode is cached
in the normal manner. This function does not search a directory
structure to locate source files; it only compiles files named
explicitly. If '-' is the only parameter in args, the list of
files is taken from standard input.
"""
if args is None:
args = sys.argv[1:]
rv = 0
if args == ['-']:
while True:
filename = sys.stdin.readline()
if not filename:
break
filename = filename.rstrip('\n')
try:
compile(filename, doraise=True)
except PyCompileError as error:
rv = 1
sys.stderr.write("%s\n" % error.msg)
except OSError as error:
rv = 1
sys.stderr.write("%s\n" % error)
description = 'A simple command-line interface for py_compile module.'
parser = argparse.ArgumentParser(description=description)
parser.add_argument(
'-q', '--quiet',
action='store_true',
help='Suppress error output',
)
parser.add_argument(
'filenames',
nargs='+',
help='Files to compile',
)
args = parser.parse_args()
if args.filenames == ['-']:
filenames = [filename.rstrip('\n') for filename in sys.stdin.readlines()]
else:
for filename in args:
try:
compile(filename, doraise=True)
except PyCompileError as error:
# return value to indicate at least one failure
rv = 1
sys.stderr.write("%s\n" % error.msg)
return rv
filenames = args.filenames
for filename in filenames:
try:
compile(filename, doraise=True)
except PyCompileError as error:
if args.quiet:
parser.exit(1)
else:
parser.exit(1, error.msg)
except OSError as error:
if args.quiet:
parser.exit(1)
else:
parser.exit(1, str(error))
if __name__ == "__main__":
sys.exit(main())
main()

2
Lib/test/badsyntax_3131.py vendored Normal file
View File

@@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
= 2

View File

@@ -4,12 +4,13 @@ import os
import py_compile
import shutil
import stat
import subprocess
import sys
import tempfile
import unittest
from test import support
from test.support import os_helper
from test.support import os_helper, script_helper
def without_source_date_epoch(fxn):
@@ -52,7 +53,7 @@ class SourceDateEpochTestMeta(type(unittest.TestCase)):
class PyCompileTestsBase:
def setUp(self):
self.directory = tempfile.mkdtemp()
self.directory = tempfile.mkdtemp(dir=os.getcwd())
self.source_path = os.path.join(self.directory, '_test.py')
self.pyc_path = self.source_path + 'c'
self.cache_path = importlib.util.cache_from_source(self.source_path)
@@ -255,5 +256,77 @@ class PyCompileTestsWithoutSourceEpoch(PyCompileTestsBase,
pass
class PyCompileCLITestCase(unittest.TestCase):
def setUp(self):
self.directory = tempfile.mkdtemp()
self.source_path = os.path.join(self.directory, '_test.py')
self.cache_path = importlib.util.cache_from_source(self.source_path)
with open(self.source_path, 'w') as file:
file.write('x = 123\n')
def tearDown(self):
os_helper.rmtree(self.directory)
def pycompilecmd(self, *args, **kwargs):
# assert_python_* helpers don't return proc object. We'll just use
# subprocess.run() instead of spawn_python() and its friends to test
# stdin support of the CLI.
if args and args[0] == '-' and 'input' in kwargs:
return subprocess.run([sys.executable, '-m', 'py_compile', '-'],
input=kwargs['input'].encode(),
capture_output=True)
return script_helper.assert_python_ok('-m', 'py_compile', *args, **kwargs)
def pycompilecmd_failure(self, *args):
return script_helper.assert_python_failure('-m', 'py_compile', *args)
def test_stdin(self):
result = self.pycompilecmd('-', input=self.source_path)
self.assertEqual(result.returncode, 0)
self.assertEqual(result.stdout, b'')
self.assertEqual(result.stderr, b'')
self.assertTrue(os.path.exists(self.cache_path))
def test_with_files(self):
rc, stdout, stderr = self.pycompilecmd(self.source_path, self.source_path)
self.assertEqual(rc, 0)
self.assertEqual(stdout, b'')
self.assertEqual(stderr, b'')
self.assertTrue(os.path.exists(self.cache_path))
def test_bad_syntax(self):
bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py')
rc, stdout, stderr = self.pycompilecmd_failure(bad_syntax)
self.assertEqual(rc, 1)
self.assertEqual(stdout, b'')
self.assertIn(b'SyntaxError', stderr)
def test_bad_syntax_with_quiet(self):
bad_syntax = os.path.join(os.path.dirname(__file__), 'badsyntax_3131.py')
rc, stdout, stderr = self.pycompilecmd_failure('-q', bad_syntax)
self.assertEqual(rc, 1)
self.assertEqual(stdout, b'')
self.assertEqual(stderr, b'')
def test_file_not_exists(self):
should_not_exists = os.path.join(os.path.dirname(__file__), 'should_not_exists.py')
rc, stdout, stderr = self.pycompilecmd_failure(self.source_path, should_not_exists)
self.assertEqual(rc, 1)
self.assertEqual(stdout, b'')
self.assertIn(b'no such file or directory', stderr.lower())
# TODO: RUSTPYTHON
if sys.platform == "win32":
test_file_not_exists = unittest.expectedFailure(test_file_not_exists)
def test_file_not_exists_with_quiet(self):
should_not_exists = os.path.join(os.path.dirname(__file__), 'should_not_exists.py')
rc, stdout, stderr = self.pycompilecmd_failure('-q', self.source_path, should_not_exists)
self.assertEqual(rc, 1)
self.assertEqual(stdout, b'')
self.assertEqual(stderr, b'')
if __name__ == "__main__":
unittest.main()