|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +import collections.abc as cabc |
1 | 4 | import warnings |
| 5 | +from concurrent import futures |
2 | 6 |
|
3 | 7 | import pytest |
4 | 8 |
|
5 | 9 | import flask |
6 | | -from flask.globals import app_ctx |
7 | 10 | from flask.sessions import SecureCookieSessionInterface |
8 | 11 | from flask.sessions import SessionInterface |
9 | | - |
10 | | -try: |
11 | | - from greenlet import greenlet |
12 | | -except ImportError: |
13 | | - greenlet = None |
| 12 | +from flask.testing import FlaskClient |
14 | 13 |
|
15 | 14 |
|
16 | 15 | def test_teardown_on_pop(app): |
@@ -145,61 +144,34 @@ def index(): |
145 | 144 | index() |
146 | 145 |
|
147 | 146 |
|
148 | | -@pytest.mark.skipif(greenlet is None, reason="greenlet not installed") |
149 | | -class TestGreenletContextCopying: |
150 | | - def test_greenlet_context_copying(self, app, client): |
151 | | - greenlets = [] |
152 | | - |
153 | | - @app.route("/") |
154 | | - def index(): |
155 | | - flask.session["fizz"] = "buzz" |
156 | | - ctx = app_ctx.copy() |
157 | | - |
158 | | - def g(): |
159 | | - assert not flask.request |
160 | | - assert not flask.current_app |
161 | | - with ctx: |
162 | | - assert flask.request |
163 | | - assert flask.current_app == app |
164 | | - assert flask.request.path == "/" |
165 | | - assert flask.request.args["foo"] == "bar" |
166 | | - assert flask.session.get("fizz") == "buzz" |
167 | | - assert not flask.request |
168 | | - return 42 |
169 | | - |
170 | | - greenlets.append(greenlet(g)) |
171 | | - return "Hello World!" |
172 | | - |
173 | | - rv = client.get("/?foo=bar") |
174 | | - assert rv.data == b"Hello World!" |
175 | | - |
176 | | - result = greenlets[0].run() |
177 | | - assert result == 42 |
178 | | - |
179 | | - def test_greenlet_context_copying_api(self, app, client): |
180 | | - greenlets = [] |
181 | | - |
182 | | - @app.route("/") |
183 | | - def index(): |
184 | | - flask.session["fizz"] = "buzz" |
185 | | - |
186 | | - @flask.copy_current_request_context |
187 | | - def g(): |
188 | | - assert flask.request |
189 | | - assert flask.current_app == app |
190 | | - assert flask.request.path == "/" |
191 | | - assert flask.request.args["foo"] == "bar" |
192 | | - assert flask.session.get("fizz") == "buzz" |
193 | | - return 42 |
194 | | - |
195 | | - greenlets.append(greenlet(g)) |
196 | | - return "Hello World!" |
197 | | - |
198 | | - rv = client.get("/?foo=bar") |
199 | | - assert rv.data == b"Hello World!" |
200 | | - |
201 | | - result = greenlets[0].run() |
202 | | - assert result == 42 |
| 147 | +def test_copy_context_thread( |
| 148 | + request: pytest.FixtureRequest, app: flask.Flask, client: FlaskClient |
| 149 | +) -> None: |
| 150 | + executor = futures.ThreadPoolExecutor(max_workers=2) |
| 151 | + request.addfinalizer(lambda: executor.shutdown(cancel_futures=True)) |
| 152 | + result: cabc.Iterator[int] | None = None |
| 153 | + |
| 154 | + @app.route("/") |
| 155 | + def index(): |
| 156 | + flask.session["fizz"] = "buzz" |
| 157 | + |
| 158 | + @flask.copy_current_request_context |
| 159 | + def work(n: int) -> int: |
| 160 | + assert flask.current_app == app |
| 161 | + assert flask.request.path == "/" |
| 162 | + assert flask.request.args["foo"] == "bar" |
| 163 | + assert flask.session["fizz"] == "buzz" |
| 164 | + return n |
| 165 | + |
| 166 | + nonlocal result |
| 167 | + result = executor.map(work, range(10)) |
| 168 | + return "Hello World!" |
| 169 | + |
| 170 | + rv = client.get(query_string={"foo": "bar"}) |
| 171 | + assert rv.text == "Hello World!" |
| 172 | + |
| 173 | + assert result is not None |
| 174 | + assert set(result) == set(range(10)) |
203 | 175 |
|
204 | 176 |
|
205 | 177 | def test_session_error_pops_context(): |
|
0 commit comments