Browse Source

Test session state in copy_current_request_context

pull/2936/head
Dave Chevell 6 years ago
parent
commit
732d77be45
No known key found for this signature in database
GPG Key ID: 279DF1B52C7C44DC
  1. 4
      CHANGES.rst
  2. 11
      flask/ctx.py
  3. 5
      tests/test_reqctx.py

4
CHANGES.rst

@ -20,9 +20,13 @@ Unreleased
stricter about header encodings than PEP 3333. (`#2766`_) stricter about header encodings than PEP 3333. (`#2766`_)
- Allow custom CLIs using ``FlaskGroup`` to set the debug flag without - Allow custom CLIs using ``FlaskGroup`` to set the debug flag without
it always being overwritten based on environment variables. (`#2765`_) it always being overwritten based on environment variables. (`#2765`_)
- :func:`flask.copy_current_request_context` adds a copy of the current
session object to the request context copy. This prevents
``flask.session`` pointing to an out-of-date object. (`#2935`)
.. _#2766: https://github.com/pallets/flask/issues/2766 .. _#2766: https://github.com/pallets/flask/issues/2766
.. _#2765: https://github.com/pallets/flask/pull/2765 .. _#2765: https://github.com/pallets/flask/pull/2765
.. _#2935: https://github.com/pallets/flask/issues/2935
Version 1.0.2 Version 1.0.2

11
flask/ctx.py

@ -122,7 +122,8 @@ def copy_current_request_context(f):
"""A helper function that decorates a function to retain the current """A helper function that decorates a function to retain the current
request context. This is useful when working with greenlets. The moment request context. This is useful when working with greenlets. The moment
the function is decorated a copy of the request context is created and the function is decorated a copy of the request context is created and
then pushed when the function is called. then pushed when the function is called. A copy of the current session is
also included in the copied request context.
Example:: Example::
@ -133,13 +134,17 @@ def copy_current_request_context(f):
def index(): def index():
@copy_current_request_context @copy_current_request_context
def do_some_work(): def do_some_work():
# do some work here, it can access flask.request like you # do some work here, it can access flask.request or
# would otherwise in the view function. # flask.session like you would otherwise in the view function.
... ...
gevent.spawn(do_some_work) gevent.spawn(do_some_work)
return 'Regular response' return 'Regular response'
.. versionadded:: 0.10 .. versionadded:: 0.10
.. versionchanged:: 1.0.3
A copy of the current session object is added to the request context
copy. This prevents `flask.session` pointing to an out-of-date object.
""" """
top = _request_ctx_stack.top top = _request_ctx_stack.top
if top is None: if top is None:

5
tests/test_reqctx.py

@ -156,7 +156,9 @@ class TestGreenletContextCopying(object):
@app.route('/') @app.route('/')
def index(): def index():
flask.session['fizz'] = 'buzz'
reqctx = flask._request_ctx_stack.top.copy() reqctx = flask._request_ctx_stack.top.copy()
reqctx.session = flask.session.copy()
def g(): def g():
assert not flask.request assert not flask.request
@ -166,6 +168,7 @@ class TestGreenletContextCopying(object):
assert flask.current_app == app assert flask.current_app == app
assert flask.request.path == '/' assert flask.request.path == '/'
assert flask.request.args['foo'] == 'bar' assert flask.request.args['foo'] == 'bar'
assert flask.session.get('fizz') == 'buzz'
assert not flask.request assert not flask.request
return 42 return 42
@ -183,6 +186,7 @@ class TestGreenletContextCopying(object):
@app.route('/') @app.route('/')
def index(): def index():
flask.session['fizz'] = 'buzz'
reqctx = flask._request_ctx_stack.top.copy() reqctx = flask._request_ctx_stack.top.copy()
@flask.copy_current_request_context @flask.copy_current_request_context
@ -191,6 +195,7 @@ class TestGreenletContextCopying(object):
assert flask.current_app == app assert flask.current_app == app
assert flask.request.path == '/' assert flask.request.path == '/'
assert flask.request.args['foo'] == 'bar' assert flask.request.args['foo'] == 'bar'
assert flask.session.get('fizz') == 'buzz'
return 42 return 42
greenlets.append(greenlet(g)) greenlets.append(greenlet(g))

Loading…
Cancel
Save