diff options
-rw-r--r-- | Lib/test/test_grammar.py | 30 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2021-03-15-07-50-30.bpo-43497.Uc5ZCJ.rst | 1 | ||||
-rw-r--r-- | Python/compile.c | 12 |
3 files changed, 37 insertions, 6 deletions
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py index 0be869e..c15f10b 100644 --- a/Lib/test/test_grammar.py +++ b/Lib/test/test_grammar.py @@ -279,6 +279,7 @@ class GrammarTests(unittest.TestCase): from test.support import check_syntax_error from test.support.warnings_helper import check_syntax_warning + from test.support.warnings_helper import check_no_warnings # single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE # XXX can't test in a script -- this rule is only used when interactive @@ -1194,7 +1195,7 @@ class GrammarTests(unittest.TestCase): # these tests fail if python is run with -O, so check __debug__ @unittest.skipUnless(__debug__, "Won't work if __debug__ is False") - def testAssert2(self): + def test_assert_failures(self): try: assert 0, "msg" except AssertionError as e: @@ -1209,11 +1210,36 @@ class GrammarTests(unittest.TestCase): else: self.fail("AssertionError not raised by 'assert False'") + def test_assert_syntax_warnings(self): + # Ensure that we warn users if they provide a non-zero length tuple as + # the assertion test. self.check_syntax_warning('assert(x, "msg")', 'assertion is always true') + self.check_syntax_warning('assert(False, "msg")', + 'assertion is always true') + self.check_syntax_warning('assert(False,)', + 'assertion is always true') + + with self.check_no_warnings(category=SyntaxWarning): + compile('assert x, "msg"', '<testcase>', 'exec') + compile('assert False, "msg"', '<testcase>', 'exec') + + def test_assert_warning_promotes_to_syntax_error(self): + # If SyntaxWarning is configured to be an error, it actually raises a + # SyntaxError. + # https://bugs.python.org/issue35029 with warnings.catch_warnings(): warnings.simplefilter('error', SyntaxWarning) - compile('assert x, "msg"', '<testcase>', 'exec') + try: + compile('assert x, "msg" ', '<testcase>', 'exec') + except SyntaxError: + self.fail('SyntaxError incorrectly raised for \'assert x, "msg"\'') + with self.assertRaises(SyntaxError): + compile('assert(x, "msg")', '<testcase>', 'exec') + with self.assertRaises(SyntaxError): + compile('assert(False, "msg")', '<testcase>', 'exec') + with self.assertRaises(SyntaxError): + compile('assert(False,)', '<testcase>', 'exec') ### compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | funcdef | classdef diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-15-07-50-30.bpo-43497.Uc5ZCJ.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-15-07-50-30.bpo-43497.Uc5ZCJ.rst new file mode 100644 index 0000000..d30677f --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-15-07-50-30.bpo-43497.Uc5ZCJ.rst @@ -0,0 +1 @@ +Emit SyntaxWarnings for assertions with tuple constants, this is a regression introduced in python3.7
\ No newline at end of file diff --git a/Python/compile.c b/Python/compile.c index ea1bf6b..a1260aa 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -3355,10 +3355,12 @@ compiler_assert(struct compiler *c, stmt_ty s) { basicblock *end; - if (c->c_optimize) - return 1; - if (s->v.Assert.test->kind == Tuple_kind && - asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) + /* Always emit a warning if the test is a non-zero length tuple */ + if ((s->v.Assert.test->kind == Tuple_kind && + asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) || + (s->v.Assert.test->kind == Constant_kind && + PyTuple_Check(s->v.Assert.test->v.Constant.value) && + PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0)) { if (!compiler_warn(c, "assertion is always true, " "perhaps remove parentheses?")) @@ -3366,6 +3368,8 @@ compiler_assert(struct compiler *c, stmt_ty s) return 0; } } + if (c->c_optimize) + return 1; end = compiler_new_block(c); if (end == NULL) return 0; |