Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ca36426

Browse files
authored
[3.12] gh-111366: Correctly show custom syntax error messages in the codeop module functions (GH-111384). (#111517)
1 parent 7ac2c53 commit ca36426

File tree

3 files changed

+31
-6
lines changed

3 files changed

+31
-6
lines changed

Lib/codeop.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ def _maybe_compile(compiler, source, filename, symbol):
7070
return None
7171
# fallthrough
7272

73-
return compiler(source, filename, symbol)
74-
73+
return compiler(source, filename, symbol, incomplete_input=False)
7574

7675
def _is_syntax_error(err1, err2):
7776
rep1 = repr(err1)
@@ -82,8 +81,13 @@ def _is_syntax_error(err1, err2):
8281
return True
8382
return False
8483

85-
def _compile(source, filename, symbol):
86-
return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT)
84+
def _compile(source, filename, symbol, incomplete_input=True):
85+
flags = 0
86+
if incomplete_input:
87+
flags |= PyCF_ALLOW_INCOMPLETE_INPUT
88+
flags |= PyCF_DONT_IMPLY_DEDENT
89+
return compile(source, filename, symbol, flags)
90+
8791

8892
def compile_command(source, filename="<input>", symbol="single"):
8993
r"""Compile a command and determine whether it is incomplete.
@@ -114,8 +118,12 @@ class Compile:
114118
def __init__(self):
115119
self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT
116120

117-
def __call__(self, source, filename, symbol):
118-
codeob = compile(source, filename, symbol, self.flags, True)
121+
def __call__(self, source, filename, symbol, **kwargs):
122+
flags = self.flags
123+
if kwargs.get('incomplete_input', True) is False:
124+
flags &= ~PyCF_DONT_IMPLY_DEDENT
125+
flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT
126+
codeob = compile(source, filename, symbol, flags, True)
119127
for feature in _features:
120128
if codeob.co_flags & feature.compiler_flag:
121129
self.flags |= feature.compiler_flag

Lib/test/test_codeop.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import unittest
66
import warnings
77
from test.support import warnings_helper
8+
from textwrap import dedent
89

910
from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
1011

@@ -308,6 +309,19 @@ def test_invalid_warning(self):
308309
self.assertRegex(str(w[0].message), 'invalid escape sequence')
309310
self.assertEqual(w[0].filename, '<input>')
310311

312+
def assertSyntaxErrorMatches(self, code, message):
313+
with self.subTest(code):
314+
with self.assertRaisesRegex(SyntaxError, message):
315+
compile_command(code, symbol='exec')
316+
317+
def test_syntax_errors(self):
318+
self.assertSyntaxErrorMatches(
319+
dedent("""\
320+
def foo(x,x):
321+
pass
322+
"""), "duplicate argument 'x' in function definition")
323+
324+
311325

312326
if __name__ == "__main__":
313327
unittest.main()
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix an issue in the :mod:`codeop` that was causing :exc:`SyntaxError`
2+
exceptions raised in the presence of invalid syntax to not contain precise
3+
error messages. Patch by Pablo Galindo

0 commit comments

Comments
 (0)