Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2fa4266

Browse files
gh-139640: Fix swallowing syntax warnings in different modules
RevertGH-131993.Fix swallowing some syntax warnings in different modules if they accidentallyhave the same message and are emitted from the same line.ast.parse() no longer emits syntax warnings forreturn/break/continue in finally (seePEP-765) -- they are onlyemitted during compilation.
1 parent12805ef commit2fa4266

File tree

9 files changed

+74
-55
lines changed

9 files changed

+74
-55
lines changed

‎Include/cpython/warnings.h‎

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,3 @@ PyAPI_FUNC(int) PyErr_WarnExplicitFormat(
1818

1919
// DEPRECATED: Use PyErr_WarnEx() instead.
2020
#definePyErr_Warn(category,msg) PyErr_WarnEx((category), (msg), 1)
21-
22-
int_PyErr_WarnExplicitObjectWithContext(
23-
PyObject*category,
24-
PyObject*message,
25-
PyObject*filename,
26-
intlineno);

‎Include/internal/pycore_compile.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ extern int _PyAST_Preprocess(
4949
PyObject*filename,
5050
intoptimize,
5151
intff_features,
52-
intsyntax_check_only);
52+
intsyntax_check_only,
53+
intenable_warnings);
5354

5455

5556
typedefstruct {

‎Lib/test/test_compile.py‎

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,22 +1664,21 @@ class WeirdDict(dict):
16641664
self.assertRaises(NameError,ns['foo'])
16651665

16661666
deftest_compile_warnings(self):
1667-
# See gh-131927
1668-
# Compile warnings originating from the same file and
1669-
# line are now only emitted once.
1667+
# Each invocation of compile() emits compiler warnings, even if they
1668+
# have the same message and line number.
1669+
source=textwrap.dedent(r"""
1670+
# tokenizer
1671+
1or 0 # line 3
1672+
# code generator
1673+
1 is 1 # line 5
1674+
""")
16701675
withwarnings.catch_warnings(record=True)ascaught:
16711676
warnings.simplefilter("default")
1672-
compile('1 is 1','<stdin>','eval')
1673-
compile('1 is 1','<stdin>','eval')
1674-
1675-
self.assertEqual(len(caught),1)
1676-
1677-
withwarnings.catch_warnings(record=True)ascaught:
1678-
warnings.simplefilter("always")
1679-
compile('1 is 1','<stdin>','eval')
1680-
compile('1 is 1','<stdin>','eval')
1677+
foriinrange(2):
1678+
# Even if compile() is at the same line.
1679+
compile(source,'<stdin>','exec')
16811680

1682-
self.assertEqual(len(caught),2)
1681+
self.assertEqual([wm.linenoforwmincaught], [3,5]*2)
16831682

16841683
deftest_compile_warning_in_finally(self):
16851684
# Ensure that warnings inside finally blocks are
@@ -1690,16 +1689,46 @@ def test_compile_warning_in_finally(self):
16901689
try:
16911690
pass
16921691
finally:
1693-
1 is 1
1692+
1 is 1 # line 5
1693+
try:
1694+
pass
1695+
finally: # nested
1696+
1 is 1 # line 9
16941697
""")
16951698

16961699
withwarnings.catch_warnings(record=True)ascaught:
1697-
warnings.simplefilter("default")
1700+
warnings.simplefilter("always")
1701+
compile(source,'<stdin>','exec')
1702+
1703+
self.assertEqual(sorted(wm.linenoforwmincaught), [5,9])
1704+
forwmincaught:
1705+
self.assertEqual(wm.category,SyntaxWarning)
1706+
self.assertIn("\"is\" with 'int' literal",str(wm.message))
1707+
1708+
# Other code path is used for "try" with "except*".
1709+
source=textwrap.dedent("""
1710+
try:
1711+
pass
1712+
except *Exception:
1713+
pass
1714+
finally:
1715+
1 is 1 # line 7
1716+
try:
1717+
pass
1718+
except *Exception:
1719+
pass
1720+
finally: # nested
1721+
1 is 1 # line 13
1722+
""")
1723+
1724+
withwarnings.catch_warnings(record=True)ascaught:
1725+
warnings.simplefilter("always")
16981726
compile(source,'<stdin>','exec')
16991727

1700-
self.assertEqual(len(caught),1)
1701-
self.assertEqual(caught[0].category,SyntaxWarning)
1702-
self.assertIn("\"is\" with 'int' literal",str(caught[0].message))
1728+
self.assertEqual(sorted(wm.linenoforwmincaught), [7,13])
1729+
forwmincaught:
1730+
self.assertEqual(wm.category,SyntaxWarning)
1731+
self.assertIn("\"is\" with 'int' literal",str(wm.message))
17031732

17041733
classTestBooleanExpression(unittest.TestCase):
17051734
classValue:

‎Lib/test/test_pyrepl/test_interact.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ def f():
293293
""")
294294

295295
withwarnings.catch_warnings(record=True)ascaught:
296-
warnings.simplefilter("default")
296+
warnings.simplefilter("always")
297297
console.runsource(code)
298298

299299
count=sum("'return' in a 'finally' block"instr(w.message)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Fix swallowing some syntax warnings in different modules if they
2+
accidentally have the same message and are emitted from the same line.
3+
:func:`ast.parse` no longer emits syntax warnings for
4+
`return`/`break`/`continue` in `finally` (see:pep:`765`) -- they are only
5+
emitted during compilation.

‎Python/_warnings.c‎

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1473,28 +1473,6 @@ PyErr_WarnExplicitObject(PyObject *category, PyObject *message,
14731473
return0;
14741474
}
14751475

1476-
/* Like PyErr_WarnExplicitObject, but automatically sets up context */
1477-
int
1478-
_PyErr_WarnExplicitObjectWithContext(PyObject*category,PyObject*message,
1479-
PyObject*filename,intlineno)
1480-
{
1481-
PyObject*unused_filename,*module,*registry;
1482-
intunused_lineno;
1483-
intstack_level=1;
1484-
1485-
if (!setup_context(stack_level,NULL,&unused_filename,&unused_lineno,
1486-
&module,&registry)) {
1487-
return-1;
1488-
}
1489-
1490-
intrc=PyErr_WarnExplicitObject(category,message,filename,lineno,
1491-
module,registry);
1492-
Py_DECREF(unused_filename);
1493-
Py_DECREF(registry);
1494-
Py_DECREF(module);
1495-
returnrc;
1496-
}
1497-
14981476
int
14991477
PyErr_WarnExplicit(PyObject*category,constchar*text,
15001478
constchar*filename_str,intlineno,

‎Python/ast_preprocess.c‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ typedef struct {
1919
intoptimize;
2020
intff_features;
2121
intsyntax_check_only;
22+
intenable_warnings;
2223

2324
_Py_c_array_tcf_finally;/* context for PEP 765 check */
2425
intcf_finally_used;
@@ -78,7 +79,7 @@ control_flow_in_finally_warning(const char *kw, stmt_ty n, _PyASTPreprocessState
7879
staticint
7980
before_return(_PyASTPreprocessState*state,stmt_tynode_)
8081
{
81-
if (state->cf_finally_used>0) {
82+
if (state->enable_warnings&&state->cf_finally_used>0) {
8283
ControlFlowInFinallyContext*ctx=get_cf_finally_top(state);
8384
if (ctx->in_finally&& !ctx->in_funcdef) {
8485
if (!control_flow_in_finally_warning("return",node_,state)) {
@@ -92,7 +93,7 @@ before_return(_PyASTPreprocessState *state, stmt_ty node_)
9293
staticint
9394
before_loop_exit(_PyASTPreprocessState*state,stmt_tynode_,constchar*kw)
9495
{
95-
if (state->cf_finally_used>0) {
96+
if (state->enable_warnings&&state->cf_finally_used>0) {
9697
ControlFlowInFinallyContext*ctx=get_cf_finally_top(state);
9798
if (ctx->in_finally&& !ctx->in_loop) {
9899
if (!control_flow_in_finally_warning(kw,node_,state)) {
@@ -968,14 +969,15 @@ astfold_type_param(type_param_ty node_, PyArena *ctx_, _PyASTPreprocessState *st
968969

969970
int
970971
_PyAST_Preprocess(mod_tymod,PyArena*arena,PyObject*filename,intoptimize,
971-
intff_features,intsyntax_check_only)
972+
intff_features,intsyntax_check_only,intenable_warnings)
972973
{
973974
_PyASTPreprocessStatestate;
974975
memset(&state,0,sizeof(_PyASTPreprocessState));
975976
state.filename=filename;
976977
state.optimize=optimize;
977978
state.ff_features=ff_features;
978979
state.syntax_check_only=syntax_check_only;
980+
state.enable_warnings=enable_warnings;
979981
if (_Py_CArray_Init(&state.cf_finally,sizeof(ControlFlowInFinallyContext),20)<0) {
980982
return-1;
981983
}

‎Python/compile.c‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ typedef struct _PyCompiler {
103103
boolc_save_nested_seqs;/* if true, construct recursive instruction sequences
104104
* (including instructions for nested code objects)
105105
*/
106+
intc_disable_warning;
106107
}compiler;
107108

108109
staticint
@@ -135,7 +136,7 @@ compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
135136
c->c_optimize= (optimize==-1) ?_Py_GetConfig()->optimization_level :optimize;
136137
c->c_save_nested_seqs= false;
137138

138-
if (!_PyAST_Preprocess(mod,arena,filename,c->c_optimize,merged,0)) {
139+
if (!_PyAST_Preprocess(mod,arena,filename,c->c_optimize,merged,0,1)) {
139140
returnERROR;
140141
}
141142
c->c_st=_PySymtable_Build(mod,filename,&c->c_future);
@@ -765,6 +766,9 @@ _PyCompile_PushFBlock(compiler *c, location loc,
765766
f->fb_loc=loc;
766767
f->fb_exit=exit;
767768
f->fb_datum=datum;
769+
if (t==COMPILE_FBLOCK_FINALLY_END) {
770+
c->c_disable_warning++;
771+
}
768772
returnSUCCESS;
769773
}
770774

@@ -776,6 +780,9 @@ _PyCompile_PopFBlock(compiler *c, fblocktype t, jump_target_label block_label)
776780
u->u_nfblocks--;
777781
assert(u->u_fblock[u->u_nfblocks].fb_type==t);
778782
assert(SAME_JUMP_TARGET_LABEL(u->u_fblock[u->u_nfblocks].fb_block,block_label));
783+
if (t==COMPILE_FBLOCK_FINALLY_END) {
784+
c->c_disable_warning--;
785+
}
779786
}
780787

781788
fblockinfo*
@@ -1203,6 +1210,9 @@ _PyCompile_Error(compiler *c, location loc, const char *format, ...)
12031210
int
12041211
_PyCompile_Warn(compiler*c,locationloc,constchar*format, ...)
12051212
{
1213+
if (c->c_disable_warning) {
1214+
return0;
1215+
}
12061216
va_listvargs;
12071217
va_start(vargs,format);
12081218
PyObject*msg=PyUnicode_FromFormatV(format,vargs);
@@ -1492,7 +1502,7 @@ _PyCompile_AstPreprocess(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
14921502
if (optimize==-1) {
14931503
optimize=_Py_GetConfig()->optimization_level;
14941504
}
1495-
if (!_PyAST_Preprocess(mod,arena,filename,optimize,flags,no_const_folding)) {
1505+
if (!_PyAST_Preprocess(mod,arena,filename,optimize,flags,no_const_folding,0)) {
14961506
return-1;
14971507
}
14981508
return0;

‎Python/errors.c‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,8 +1962,8 @@ int
19621962
_PyErr_EmitSyntaxWarning(PyObject*msg,PyObject*filename,intlineno,intcol_offset,
19631963
intend_lineno,intend_col_offset)
19641964
{
1965-
if (_PyErr_WarnExplicitObjectWithContext(PyExc_SyntaxWarning,msg,
1966-
filename,lineno)<0)
1965+
if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning,msg,
1966+
filename,lineno,NULL,NULL)<0)
19671967
{
19681968
if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
19691969
/* Replace the SyntaxWarning exception with a SyntaxError

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp