gh-96661: Ensure default action for warnings is restored in the interpreter's state #96662
+9
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
On the first run all the tests from
test_warnings
suite pass.On every subsequent run several tests fail because warnings being emitted via
module.warn
/module.warn_explicit
functions are ignored by default and not caught by thecatch_warnings
class object.It turns out that failures are caused by
test_warnings._WarningsTests.test_default_action
that changes default action for warnings toignore
but fails to restore it back todefault
.Even though the code of
test_warnings._WarningsTests.test_default_action
contains the followingfinally
block which sets module's default action member to its original value, this value is never propagated to the interpreter's state structure.The quirk is in the broken reference chain.
At the very beginning of the test this chain looks perfectly correct:
original -> module.defaultaction -> module._defaultaction -> interp.warnings.default_action
.However, test deletes
module.defaultaction
and assigns a different string literal (i.e.ignore
) to it thus takingmodule.defaultaction
away from the aforementioned chain:Furthermore, as soon as a warning is fired after
module.defaultaction
value has been updated,interp.warnings.default_action
is set to reference newmodule.defaultaction
.The bottom line result is two separate reference chains:
original -> module._defaultaction
andmodule.defaultaction -> interp.warnings.default_action
.The assignment
self.module.defaultaction = original
in the test'sfinally
block (see above) can by no means changeinterp.warnings.default_action
value despite partially restoring the original reference chain:original -> module.defaultaction -> module._defaultaction
.The
warnings
C module interface is pretty terse containing only two functions:warn_explicit
and_filters_mutated
.The latter one has nothing to do with
interp.warnings.default_action
value whereas the former does exactly what we need: setsinterp.warnings.default_action
to referencemodule.defaultaction
.test_default_action
fromtest_warnings
suite doesn't restore default action in the interpreter's state structure #96661