diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml
index 7654a223..b121dd8e 100644
--- a/.github/workflows/tests.yaml
+++ b/.github/workflows/tests.yaml
@@ -32,6 +32,8 @@ jobs:
- {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}
- {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37}
- {name: 'PyPy', python: 'pypy-3.7', os: ubuntu-latest, tox: pypy37}
+ - {name: 'Pallets Minimum Versions', python: '3.10', os: ubuntu-latest, tox: py-min}
+ - {name: 'Pallets Development Versions', python: '3.7', os: ubuntu-latest, tox: py-dev}
- {name: Typing, python: '3.10', os: ubuntu-latest, tox: typing}
steps:
- uses: actions/checkout@v2
diff --git a/CHANGES.rst b/CHANGES.rst
index 7c8d279b..4aa1b97a 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -30,6 +30,17 @@ Unreleased
- ``filename`` is renamed to ``path``.
+Version 2.0.3
+-------------
+
+Unreleased
+
+- The test client's ``as_tuple`` parameter is deprecated and will be
+ removed in Werkzeug 2.1. It is now also deprecated in Flask, to be
+ removed in Flask 2.1, while remaining compatible with both in
+ 2.0.x. Use ``response.request.environ`` instead. :pr:`4341`
+
+
Version 2.0.2
-------------
diff --git a/docs/quickstart.rst b/docs/quickstart.rst
index 9bddbfc0..e07e8dbf 100644
--- a/docs/quickstart.rst
+++ b/docs/quickstart.rst
@@ -468,7 +468,7 @@ Here is a basic introduction to how the :class:`~markupsafe.Markup` class works:
>>> Markup.escape('')
Markup('<blink>hacker</blink>')
>>> Markup('Marked up » HTML').striptags()
- 'Marked up \xbb HTML'
+ 'Marked up ยป HTML'
.. versionchanged:: 0.5
diff --git a/requirements/tests-pallets-dev.in b/requirements/tests-pallets-dev.in
new file mode 100644
index 00000000..dddbe48a
--- /dev/null
+++ b/requirements/tests-pallets-dev.in
@@ -0,0 +1,5 @@
+https://github.com/pallets/werkzeug/archive/refs/heads/main.tar.gz
+https://github.com/pallets/jinja/archive/refs/heads/main.tar.gz
+https://github.com/pallets/markupsafe/archive/refs/heads/main.tar.gz
+https://github.com/pallets/itsdangerous/archive/refs/heads/main.tar.gz
+https://github.com/pallets/click/archive/refs/heads/main.tar.gz
diff --git a/requirements/tests-pallets-dev.txt b/requirements/tests-pallets-dev.txt
new file mode 100644
index 00000000..19894ed6
--- /dev/null
+++ b/requirements/tests-pallets-dev.txt
@@ -0,0 +1,18 @@
+#
+# This file is autogenerated by pip-compile with python 3.10
+# To update, run:
+#
+# pip-compile requirements/tests-pallets-dev.in
+#
+click @ https://github.com/pallets/click/archive/refs/heads/main.tar.gz
+ # via -r requirements/tests-pallets-dev.in
+itsdangerous @ https://github.com/pallets/itsdangerous/archive/refs/heads/main.tar.gz
+ # via -r requirements/tests-pallets-dev.in
+jinja2 @ https://github.com/pallets/jinja/archive/refs/heads/main.tar.gz
+ # via -r requirements/tests-pallets-dev.in
+markupsafe @ https://github.com/pallets/markupsafe/archive/refs/heads/main.tar.gz
+ # via
+ # -r requirements/tests-pallets-dev.in
+ # jinja2
+werkzeug @ https://github.com/pallets/werkzeug/archive/refs/heads/main.tar.gz
+ # via -r requirements/tests-pallets-dev.in
diff --git a/requirements/tests-pallets-min.in b/requirements/tests-pallets-min.in
new file mode 100644
index 00000000..6c8a55d9
--- /dev/null
+++ b/requirements/tests-pallets-min.in
@@ -0,0 +1,5 @@
+Werkzeug==2.0.0
+Jinja2==3.0.0
+MarkupSafe==2.0.0
+itsdangerous==2.0.0
+click==8.0.0
diff --git a/requirements/tests-pallets-min.txt b/requirements/tests-pallets-min.txt
new file mode 100644
index 00000000..75b3524c
--- /dev/null
+++ b/requirements/tests-pallets-min.txt
@@ -0,0 +1,18 @@
+#
+# This file is autogenerated by pip-compile with python 3.10
+# To update, run:
+#
+# pip-compile requirements/tests-pallets-min.in
+#
+click==8.0.0
+ # via -r requirements/tests-pallets-min.in
+itsdangerous==2.0.0
+ # via -r requirements/tests-pallets-min.in
+jinja2==3.0.0
+ # via -r requirements/tests-pallets-min.in
+markupsafe==2.0.0
+ # via
+ # -r requirements/tests-pallets-min.in
+ # jinja2
+werkzeug==2.0.0
+ # via -r requirements/tests-pallets-min.in
diff --git a/src/flask/testing.py b/src/flask/testing.py
index fe3b846a..1b35cc7a 100644
--- a/src/flask/testing.py
+++ b/src/flask/testing.py
@@ -9,14 +9,15 @@ from werkzeug.test import Client
from werkzeug.urls import url_parse
from werkzeug.wrappers import Request as BaseRequest
-from . import _request_ctx_stack
from .cli import ScriptInfo
+from .globals import _request_ctx_stack
from .json import dumps as json_dumps
from .sessions import SessionMixin
if t.TYPE_CHECKING:
+ from werkzeug.test import TestResponse
+
from .app import Flask
- from .wrappers import Response
class EnvironBuilder(werkzeug.test.EnvironBuilder):
@@ -171,14 +172,15 @@ class FlaskClient(Client):
headers = resp.get_wsgi_headers(c.request.environ)
self.cookie_jar.extract_wsgi(c.request.environ, headers)
- def open( # type: ignore
+ def open(
self,
*args: t.Any,
- as_tuple: bool = False,
buffered: bool = False,
follow_redirects: bool = False,
**kwargs: t.Any,
- ) -> "Response":
+ ) -> "TestResponse":
+ as_tuple = kwargs.pop("as_tuple", None)
+
# Same logic as super.open, but apply environ_base and preserve_context.
request = None
@@ -213,12 +215,28 @@ class FlaskClient(Client):
finally:
builder.close()
- return super().open( # type: ignore
- request,
- as_tuple=as_tuple,
- buffered=buffered,
- follow_redirects=follow_redirects,
- )
+ if as_tuple is not None:
+ import warnings
+
+ warnings.warn(
+ "'as_tuple' is deprecated and will be removed in"
+ " Werkzeug 2.1 and Flask 2.1. Use"
+ " 'response.request.environ' instead.",
+ DeprecationWarning,
+ stacklevel=3,
+ )
+ return super().open(
+ request,
+ as_tuple=as_tuple,
+ buffered=buffered,
+ follow_redirects=follow_redirects,
+ )
+ else:
+ return super().open(
+ request,
+ buffered=buffered,
+ follow_redirects=follow_redirects,
+ )
def __enter__(self) -> "FlaskClient":
if self.preserve_context:
@@ -272,7 +290,7 @@ class FlaskCliRunner(CliRunner):
:return: a :class:`~click.testing.Result` object.
"""
if cli is None:
- cli = self.app.cli
+ cli = self.app.cli # type: ignore
if "obj" not in kwargs:
kwargs["obj"] = ScriptInfo(create_app=lambda: self.app)
diff --git a/tox.ini b/tox.ini
index 3967b7ee..50bf2660 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,8 @@
[tox]
envlist =
py3{11,10,9,8,7},pypy3{8,7}
+ py310-min
+ py37-dev
style
typing
docs
@@ -9,6 +11,8 @@ skip_missing_interpreters = true
[testenv]
deps =
-r requirements/tests.txt
+ min: -r requirements/tests-pallets-min.txt
+ dev: -r requirements/tests-pallets-dev.txt
examples/tutorial[test]
examples/javascript[test]