[Python-checkins] bpo-35029: Replace the SyntaxWarning exception with a SyntaxError. (GH-9999)

Serhiy Storchaka webhook-mailer at python.org
Sun Oct 21 03:09:42 EDT 2018


https://github.com/python/cpython/commit/d31e7730cd5d74efbd7320751dacd51d09cc415d
commit: d31e7730cd5d74efbd7320751dacd51d09cc415d
branch: master
author: Serhiy Storchaka <storchaka at gmail.com>
committer: GitHub <noreply at github.com>
date: 2018-10-21T10:09:39+03:00
summary:

bpo-35029: Replace the SyntaxWarning exception with a SyntaxError. (GH-9999)

If SyntaxWarning was raised as an exception, it will be replaced
with a SyntaxError for better error reporting.

files:
A Misc/NEWS.d/next/Core and Builtins/2018-10-20-10-26-15.bpo-35029.t4tZcQ.rst
M Lib/test/test_grammar.py
M Python/compile.c

diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index 9dd42b4f5dab..3d8b1514f0cd 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -5,6 +5,7 @@
 import inspect
 import unittest
 import sys
+import warnings
 # testing import *
 from sys import *
 
@@ -1099,6 +1100,14 @@ def testAssert2(self):
         else:
             self.fail("AssertionError not raised by 'assert False'")
 
+        with self.assertWarnsRegex(SyntaxWarning, 'assertion is always true'):
+            compile('assert(x, "msg")', '<testcase>', 'exec')
+        with warnings.catch_warnings():
+            warnings.filterwarnings('error', category=SyntaxWarning)
+            with self.assertRaisesRegex(SyntaxError, 'assertion is always true'):
+                compile('assert(x, "msg")', '<testcase>', 'exec')
+            compile('assert x, "msg"', '<testcase>', 'exec')
+
 
     ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
     # Tested below
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-10-20-10-26-15.bpo-35029.t4tZcQ.rst b/Misc/NEWS.d/next/Core and Builtins/2018-10-20-10-26-15.bpo-35029.t4tZcQ.rst
new file mode 100644
index 000000000000..3644c4410fba
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-10-20-10-26-15.bpo-35029.t4tZcQ.rst	
@@ -0,0 +1,2 @@
+:exc:`SyntaxWarning` raised as an exception at code generation time will be
+now replaced with a :exc:`SyntaxError` for better error reporting.
diff --git a/Python/compile.c b/Python/compile.c
index 78b7baf3235f..11958d384175 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -174,6 +174,7 @@ static int compiler_addop(struct compiler *, int);
 static int compiler_addop_i(struct compiler *, int, Py_ssize_t);
 static int compiler_addop_j(struct compiler *, int, basicblock *, int);
 static int compiler_error(struct compiler *, const char *);
+static int compiler_warn(struct compiler *, const char *);
 static int compiler_nameop(struct compiler *, identifier, expr_context_ty);
 
 static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
@@ -2971,7 +2972,6 @@ compiler_assert(struct compiler *c, stmt_ty s)
 {
     static PyObject *assertion_error = NULL;
     basicblock *end;
-    PyObject* msg;
 
     if (c->c_optimize)
         return 1;
@@ -2981,18 +2981,13 @@ compiler_assert(struct compiler *c, stmt_ty s)
             return 0;
     }
     if (s->v.Assert.test->kind == Tuple_kind &&
-        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) {
-        msg = PyUnicode_FromString("assertion is always true, "
-                                   "perhaps remove parentheses?");
-        if (msg == NULL)
-            return 0;
-        if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg,
-                                     c->c_filename, c->u->u_lineno,
-                                     NULL, NULL) == -1) {
-            Py_DECREF(msg);
+        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0)
+    {
+        if (!compiler_warn(c, "assertion is always true, "
+                              "perhaps remove parentheses?"))
+        {
             return 0;
         }
-        Py_DECREF(msg);
     }
     end = compiler_new_block(c);
     if (end == NULL)
@@ -4793,6 +4788,31 @@ compiler_error(struct compiler *c, const char *errstr)
     return 0;
 }
 
+/* Emits a SyntaxWarning and returns 1 on success.
+   If a SyntaxWarning raised as error, replaces it with a SyntaxError
+   and returns 0.
+*/
+static int
+compiler_warn(struct compiler *c, const char *errstr)
+{
+    PyObject *msg = PyUnicode_FromString(errstr);
+    if (msg == NULL) {
+        return 0;
+    }
+    if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
+                                 c->u->u_lineno, NULL, NULL) < 0)
+    {
+        Py_DECREF(msg);
+        if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
+            PyErr_Clear();
+            return compiler_error(c, errstr);
+        }
+        return 0;
+    }
+    Py_DECREF(msg);
+    return 1;
+}
+
 static int
 compiler_handle_subscr(struct compiler *c, const char *kind,
                        expr_context_ty ctx)



More information about the Python-checkins mailing list