mirror of
https://github.com/python/cpython.git
synced 2025-09-18 22:50:26 +00:00
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.
This commit is contained in:
parent
2f73ed6913
commit
d31e7730cd
3 changed files with 42 additions and 11 deletions
|
@ -5,6 +5,7 @@ from test.support import check_syntax_error
|
||||||
import inspect
|
import inspect
|
||||||
import unittest
|
import unittest
|
||||||
import sys
|
import sys
|
||||||
|
import warnings
|
||||||
# testing import *
|
# testing import *
|
||||||
from sys import *
|
from sys import *
|
||||||
|
|
||||||
|
@ -1099,6 +1100,14 @@ class GrammarTests(unittest.TestCase):
|
||||||
else:
|
else:
|
||||||
self.fail("AssertionError not raised by 'assert False'")
|
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
|
### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
|
||||||
# Tested below
|
# Tested below
|
||||||
|
|
|
@ -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.
|
|
@ -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_i(struct compiler *, int, Py_ssize_t);
|
||||||
static int compiler_addop_j(struct compiler *, int, basicblock *, int);
|
static int compiler_addop_j(struct compiler *, int, basicblock *, int);
|
||||||
static int compiler_error(struct compiler *, const char *);
|
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 int compiler_nameop(struct compiler *, identifier, expr_context_ty);
|
||||||
|
|
||||||
static PyCodeObject *compiler_mod(struct compiler *, mod_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;
|
static PyObject *assertion_error = NULL;
|
||||||
basicblock *end;
|
basicblock *end;
|
||||||
PyObject* msg;
|
|
||||||
|
|
||||||
if (c->c_optimize)
|
if (c->c_optimize)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -2981,18 +2981,13 @@ compiler_assert(struct compiler *c, stmt_ty s)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (s->v.Assert.test->kind == Tuple_kind &&
|
if (s->v.Assert.test->kind == Tuple_kind &&
|
||||||
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) {
|
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0)
|
||||||
msg = PyUnicode_FromString("assertion is always true, "
|
{
|
||||||
"perhaps remove parentheses?");
|
if (!compiler_warn(c, "assertion is always true, "
|
||||||
if (msg == NULL)
|
"perhaps remove parentheses?"))
|
||||||
return 0;
|
{
|
||||||
if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg,
|
|
||||||
c->c_filename, c->u->u_lineno,
|
|
||||||
NULL, NULL) == -1) {
|
|
||||||
Py_DECREF(msg);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Py_DECREF(msg);
|
|
||||||
}
|
}
|
||||||
end = compiler_new_block(c);
|
end = compiler_new_block(c);
|
||||||
if (end == NULL)
|
if (end == NULL)
|
||||||
|
@ -4793,6 +4788,31 @@ compiler_error(struct compiler *c, const char *errstr)
|
||||||
return 0;
|
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
|
static int
|
||||||
compiler_handle_subscr(struct compiler *c, const char *kind,
|
compiler_handle_subscr(struct compiler *c, const char *kind,
|
||||||
expr_context_ty ctx)
|
expr_context_ty ctx)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue