-
-
Notifications
You must be signed in to change notification settings - Fork 31.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-128384: Add thread-safe context manager to "warnings" module #128300
Closed
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1f8b441
to
3952bb0
Compare
Expose the mutex from _warnings.c and hold it when mutating the filters list.
By default, inherit the context from the thread calling `Thread.start()`.
3952bb0
to
3bac8d1
Compare
When reset is called, the warnings.filters list should be ignored since the list of active filters should be empty at that point.
Closing this since gh-130010 seems a better approach. |
gst
reviewed
Apr 7, 2025
|
||
|
||
class PyContextTests(ContextTests, unittest.TestCase): | ||
module = c_warnings |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't you want the other one ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, you're right.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Suggestion cannot be applied right now. Please check back later.
This PR adds a new thread-local (and async friendly) context manager that uses
contextvars
. The recommended pattern for new code that doesn't care about backwards compatibility would be:For code that wants to be compatible with older versions of Python, the suggested code is:
This change retains
warnings.filters
andwarnings.catch_warnings()
as mechanisms that use process global state. Conceptually, there will be two sets of warning filters: the legacy process globalwarnings.filters
list and the thread localget_context()._filters
list. The context object returned byget_context()
has an API that overlaps with thewarnings
module function API.Perhaps we could eventually warn when the process global versions are used but I think that would be many years in the future and not worth considering now.
It would be intuitive if the thread local filtering was inherited when a new thread is created. I've created a separate PR that adds this feature to
threading.Thread
: gh-128209. That's a potentially controversial change but I think it's the correct thing to do. It will make contextvars behave similarly between asyncio tasks (which already inherit context) and threads. I think people will expect the warnings context manager to have lexical scope. If you see the code:Then you would assume that
inner_function()
is going to haveMyWarning
filtered, even if it internally spawns a thread.Regarding backwards compatibility, I did a code search and there are quite a few examples for code that manipulates
warnings.filters
directly, either mutating it or assigning a different list to the module global. There is also code that does this:📚 Documentation preview 📚: https://cpython-previews--128300.org.readthedocs.build/