]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-111366: Correctly show custom syntax error messages in the codeop module...
authorPablo Galindo Salgado <Pablogsal@gmail.com>
Tue, 31 Oct 2023 14:41:20 +0000 (14:41 +0000)
committerGitHub <noreply@github.com>
Tue, 31 Oct 2023 14:41:20 +0000 (14:41 +0000)
(cherry picked from commit cd6e0a04a16535d8bc727c84f73730c53267184e)

Lib/codeop.py
Lib/test/test_codeop.py
Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst [new file with mode: 0644]

index 2213b69f231f92fb9ddc68a822ed06212370ef7b..e64911ee5ad4170e69a93b5510f0a077623744a0 100644 (file)
@@ -70,8 +70,7 @@ def _maybe_compile(compiler, source, filename, symbol):
                     return None
                 # fallthrough
 
-    return compiler(source, filename, symbol)
-
+    return compiler(source, filename, symbol, incomplete_input=False)
 
 def _is_syntax_error(err1, err2):
     rep1 = repr(err1)
@@ -82,8 +81,12 @@ def _is_syntax_error(err1, err2):
         return True
     return False
 
-def _compile(source, filename, symbol):
-    return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT)
+def _compile(source, filename, symbol, incomplete_input=True):
+    flags = 0
+    if incomplete_input:
+        flags |= PyCF_ALLOW_INCOMPLETE_INPUT
+        flags |= PyCF_DONT_IMPLY_DEDENT
+    return compile(source, filename, symbol, flags)
 
 def compile_command(source, filename="<input>", symbol="single"):
     r"""Compile a command and determine whether it is incomplete.
@@ -114,8 +117,12 @@ class Compile:
     def __init__(self):
         self.flags = PyCF_DONT_IMPLY_DEDENT | PyCF_ALLOW_INCOMPLETE_INPUT
 
-    def __call__(self, source, filename, symbol):
-        codeob = compile(source, filename, symbol, self.flags, True)
+    def __call__(self, source, filename, symbol, **kwargs):
+        flags = self.flags
+        if kwargs.get('incomplete_input', True) is False:
+            flags &= ~PyCF_DONT_IMPLY_DEDENT
+            flags &= ~PyCF_ALLOW_INCOMPLETE_INPUT
+        codeob = compile(source, filename, symbol, flags, True)
         for feature in _features:
             if codeob.co_flags & feature.compiler_flag:
                 self.flags |= feature.compiler_flag
index 133096d25a44bc24468994a162e9ef9008ff6190..94ea06f79d3618bcd7a6bbe1226b7c3900df46f9 100644 (file)
@@ -7,6 +7,7 @@ import unittest
 import warnings
 from test import support
 from test.support import warnings_helper
+from textwrap import dedent
 
 from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT
 import io
@@ -341,6 +342,19 @@ class CodeopTests(unittest.TestCase):
         self.assertRegex(str(w[0].message), 'invalid escape sequence')
         self.assertEqual(w[0].filename, '<input>')
 
+    def assertSyntaxErrorMatches(self, code, message):
+        with self.subTest(code):
+            with self.assertRaisesRegex(SyntaxError, message):
+                compile_command(code, symbol='exec')
+
+    def test_syntax_errors(self):
+        self.assertSyntaxErrorMatches(
+            dedent("""\
+                def foo(x,x):
+                   pass
+            """), "duplicate argument 'x' in function definition")
+
+
 
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-27-12-17-49.gh-issue-111366._TSknV.rst
new file mode 100644 (file)
index 0000000..7e76ce9
--- /dev/null
@@ -0,0 +1,3 @@
+Fix an issue in the :mod:`codeop` that was causing :exc:`SyntaxError`
+exceptions raised in the presence of invalid syntax to not contain precise
+error messages. Patch by Pablo Galindo