Skip to content

Commit a8ef457

Browse files
authored
bpo-43497: Emit SyntaxWarnings for assertions with tuple constants. (GH-24867)
* bpo-43497: Emit SyntaxWarnings for assertions with tuple constants. Add a test that shows that a tuple constant (a tuple, where all of its members are also compile-time constants) produces a SyntaxWarning. Then fix this failure. * Make SyntaxWarnings also work when "optimized". * Split tests for SyntaxWarning to SyntaxError conversion SyntaxWarnings emitted by the compiler when configured to be errors are actually raised as SyntaxError exceptions. Move these tests into their own method and add a test to ensure they are raised. Previously we only tested that they were not raised for a "valid" assertion statement.
1 parent 1330338 commit a8ef457

File tree

3 files changed

+37
-6
lines changed

3 files changed

+37
-6
lines changed

Lib/test/test_grammar.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ class GrammarTests(unittest.TestCase):
279279

280280
from test.support import check_syntax_error
281281
from test.support.warnings_helper import check_syntax_warning
282+
from test.support.warnings_helper import check_no_warnings
282283

283284
# single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
284285
# XXX can't test in a script -- this rule is only used when interactive
@@ -1194,7 +1195,7 @@ def test_assert(self):
11941195

11951196
# these tests fail if python is run with -O, so check __debug__
11961197
@unittest.skipUnless(__debug__, "Won't work if __debug__ is False")
1197-
def testAssert2(self):
1198+
def test_assert_failures(self):
11981199
try:
11991200
assert 0, "msg"
12001201
except AssertionError as e:
@@ -1209,11 +1210,36 @@ def testAssert2(self):
12091210
else:
12101211
self.fail("AssertionError not raised by 'assert False'")
12111212

1213+
def test_assert_syntax_warnings(self):
1214+
# Ensure that we warn users if they provide a non-zero length tuple as
1215+
# the assertion test.
12121216
self.check_syntax_warning('assert(x, "msg")',
12131217
'assertion is always true')
1218+
self.check_syntax_warning('assert(False, "msg")',
1219+
'assertion is always true')
1220+
self.check_syntax_warning('assert(False,)',
1221+
'assertion is always true')
1222+
1223+
with self.check_no_warnings(category=SyntaxWarning):
1224+
compile('assert x, "msg"', '<testcase>', 'exec')
1225+
compile('assert False, "msg"', '<testcase>', 'exec')
1226+
1227+
def test_assert_warning_promotes_to_syntax_error(self):
1228+
# If SyntaxWarning is configured to be an error, it actually raises a
1229+
# SyntaxError.
1230+
# https://bugs.python.org/issue35029
12141231
with warnings.catch_warnings():
12151232
warnings.simplefilter('error', SyntaxWarning)
1216-
compile('assert x, "msg"', '<testcase>', 'exec')
1233+
try:
1234+
compile('assert x, "msg" ', '<testcase>', 'exec')
1235+
except SyntaxError:
1236+
self.fail('SyntaxError incorrectly raised for \'assert x, "msg"\'')
1237+
with self.assertRaises(SyntaxError):
1238+
compile('assert(x, "msg")', '<testcase>', 'exec')
1239+
with self.assertRaises(SyntaxError):
1240+
compile('assert(False, "msg")', '<testcase>', 'exec')
1241+
with self.assertRaises(SyntaxError):
1242+
compile('assert(False,)', '<testcase>', 'exec')
12171243

12181244

12191245
### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Emit SyntaxWarnings for assertions with tuple constants, this is a regression introduced in python3.7

Python/compile.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3355,17 +3355,21 @@ compiler_assert(struct compiler *c, stmt_ty s)
33553355
{
33563356
basicblock *end;
33573357

3358-
if (c->c_optimize)
3359-
return 1;
3360-
if (s->v.Assert.test->kind == Tuple_kind &&
3361-
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0)
3358+
/* Always emit a warning if the test is a non-zero length tuple */
3359+
if ((s->v.Assert.test->kind == Tuple_kind &&
3360+
asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
3361+
(s->v.Assert.test->kind == Constant_kind &&
3362+
PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
3363+
PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
33623364
{
33633365
if (!compiler_warn(c, "assertion is always true, "
33643366
"perhaps remove parentheses?"))
33653367
{
33663368
return 0;
33673369
}
33683370
}
3371+
if (c->c_optimize)
3372+
return 1;
33693373
end = compiler_new_block(c);
33703374
if (end == NULL)
33713375
return 0;

0 commit comments

Comments
 (0)