new preserve context implementation #4666
Merged
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.
Uses the new mechanism introduced by pallets/werkzeug#2439 to preserve the app and request context. If the
werkzeug.debug.preserve_contextkey is in the environ, it is a callable. It is called to record context managers that should be entered again after the request ends. Rather than keeping the contexts on the stack for longer, this allows preserving the contexts independently of the context-local stack and subsequent requests.Because
request,g, etc. are context-local, they would never be available in the debugger when using the default threaded server. Now they will point to the correct data in the debugger. The same mechanism is used by the test client.The contexts are now always popped at the end of the request, even if they are preserved. This means teardown functions will run to clean up resources. The previous implementation would pop the preserved context from the stack on the next, but that would never happen when using the threaded server because each request would be in a new thread with its own stack. I have a feeling this was causing issues especially with Flask-SQLAlchemy, where connections would never be released for requests caught by the debugger.
The contexts are restored after the request finishes in the test client, or when code is executed in the debugger. This means that signals will run each time, and teardown functions will run each time.
Only the contexts directly preserved by
werkzeug.debug.preserve_contextare popped. This reverts #3157, which caused every instance of the same context to be popped. This means that the context preserved withstream_with_contextwill not be popped when awith clientblock ends, it will only be popped onceresponse.datais read (orresponse.close()is called).closes #2836