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_warningssuite pass.On every subsequent run several tests fail because warnings being emitted via
module.warn/module.warn_explicitfunctions are ignored by default and not caught by thecatch_warningsclass object.It turns out that failures are caused by
test_warnings._WarningsTests.test_default_actionthat changes default action for warnings toignorebut fails to restore it back todefault.Even though the code of
test_warnings._WarningsTests.test_default_actioncontains the followingfinallyblock 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.defaultactionand assigns a different string literal (i.e.ignore) to it thus takingmodule.defaultactionaway from the aforementioned chain:Furthermore, as soon as a warning is fired after
module.defaultactionvalue has been updated,interp.warnings.default_actionis set to reference newmodule.defaultaction.The bottom line result is two separate reference chains:
original -> module._defaultactionandmodule.defaultaction -> interp.warnings.default_action.The assignment
self.module.defaultaction = originalin the test'sfinallyblock (see above) can by no means changeinterp.warnings.default_actionvalue despite partially restoring the original reference chain:original -> module.defaultaction -> module._defaultaction.The
warningsC module interface is pretty terse containing only two functions:warn_explicitand_filters_mutated.The latter one has nothing to do with
interp.warnings.default_actionvalue whereas the former does exactly what we need: setsinterp.warnings.default_actionto referencemodule.defaultaction.test_default_actionfromtest_warningssuite doesn't restore default action in the interpreter's state structure #96661