When using copy_current_request_context in the middle of a request, I'm expecting it to copy the current state of flask.request and flask.session at the time it's called.
The current state of flask.request is copied, but flask.session is from before the current request and doesn't contain changes made during the current request, before copy_current_request_context was called. To me this seems like unexpected behaviour. If it's not I'd like to understand a bit more about why, and also to find out whether there's any workaround or alternative approach I can take.
Here's a fully functional example you can save and run. It adds a test value to flask.request and flask.session during the request, then uses copy_current_request_context to decorate a method that will retrieve those same values in another thread. Two requests are made; on the first request the copied context can find the new value added to flask.request but cannot find the value added to flask.session. On the second request, the copied context can find the value added to flask.request, and now finds the value that was previously added to flask.session in the first request.
I've found a solution for this - but I don't trust it because I don't have a strong enough knowledge of the Werkzeug internals to know if there are unintended side effects.
After making a copy of the request context, you can simply give it a copy of the current session object. Here's a modified version of copy_current_request_context that does just that:
raiseRuntimeError('This decorator can only be used at local scopes ''when a request context is on the stack. For instance within ''view functions.')
reqctx.session = session.copy() is the addition here.
With this change, my example produces the expected behaviour. The Flask test suite passes, so there's no obvious side effects I can see.
I would love to have the built in copy_current_request_context produce this behaviour, but I suppose the question becomes: should it? I'm guessing the behaviour I've run into exists because is not because copy_current_request_context is copying an old session object as I originally thought, but instead simply isn't copying anything. It stands to reason that as a byproduct of that flask.session proxy points to the previous state of the session object in the copied request context. Since the end result is that the request and session state are inconsistent I think my solution still makes sense, so I've opened #2936 to propose the change.