Merge pull request #3894 from pallets/update-werkzeug
Update for recent changes in Pallets libraries
This commit is contained in:
commit
9f7ac04aaf
11 changed files with 59 additions and 79 deletions
|
|
@ -49,7 +49,8 @@ Unreleased
|
|||
implementations in ``werkzeug.utils``. :pr:`3828`
|
||||
- Some ``send_file`` parameters have been renamed, the old names are
|
||||
deprecated. ``attachment_filename`` is renamed to ``download_name``.
|
||||
``cache_timeout`` is renamed to ``max_age``. :pr:`3828`
|
||||
``cache_timeout`` is renamed to ``max_age``. ``add_etags`` is
|
||||
renamed to ``etag``. :pr:`3828, 3883`
|
||||
- ``send_file`` passes ``download_name`` even if
|
||||
``as_attachment=False`` by using ``Content-Disposition: inline``.
|
||||
:pr:`3828`
|
||||
|
|
|
|||
23
docs/api.rst
23
docs/api.rst
|
|
@ -27,9 +27,9 @@ Incoming Request Data
|
|||
---------------------
|
||||
|
||||
.. autoclass:: Request
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: json_module
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: json_module
|
||||
|
||||
.. attribute:: request
|
||||
|
||||
|
|
@ -48,20 +48,9 @@ Response Objects
|
|||
----------------
|
||||
|
||||
.. autoclass:: flask.Response
|
||||
:members: set_cookie, max_cookie_size, data, mimetype, is_json, get_json
|
||||
|
||||
.. attribute:: headers
|
||||
|
||||
A :class:`~werkzeug.datastructures.Headers` object representing the response headers.
|
||||
|
||||
.. attribute:: status
|
||||
|
||||
A string with a response status.
|
||||
|
||||
.. attribute:: status_code
|
||||
|
||||
The response status as integer.
|
||||
|
||||
:members:
|
||||
:inherited-members:
|
||||
:exclude-members: json_module
|
||||
|
||||
Sessions
|
||||
--------
|
||||
|
|
|
|||
|
|
@ -249,25 +249,11 @@ be passed an instance of ``InternalServerError``, not the original
|
|||
unhandled error.
|
||||
|
||||
The original error is available as ``e.original_exception``.
|
||||
Until Werkzeug 1.0.0, this attribute will only exist during unhandled
|
||||
errors, use ``getattr`` to get access it for compatibility.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@app.errorhandler(InternalServerError)
|
||||
def handle_500(e):
|
||||
original = getattr(e, "original_exception", None)
|
||||
|
||||
if original is None:
|
||||
# direct 500 error, such as abort(500)
|
||||
return render_template("500.html"), 500
|
||||
|
||||
# wrapped unhandled error
|
||||
return render_template("500_unhandled.html", e=original), 500
|
||||
|
||||
An error handler for "500 Internal Server Error" will be passed uncaught exceptions in
|
||||
addition to explicit 500 errors. In debug mode, a handler for "500 Internal Server Error" will not be used.
|
||||
Instead, the interactive debugger will be shown.
|
||||
An error handler for "500 Internal Server Error" will be passed uncaught
|
||||
exceptions in addition to explicit 500 errors. In debug mode, a handler
|
||||
for "500 Internal Server Error" will not be used. Instead, the
|
||||
interactive debugger will be shown.
|
||||
|
||||
|
||||
Custom Error Pages
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ Notice that our test functions begin with the word `test`; this allows
|
|||
By using ``client.get`` we can send an HTTP ``GET`` request to the
|
||||
application with the given path. The return value will be a
|
||||
:class:`~flask.Flask.response_class` object. We can now use the
|
||||
:attr:`~werkzeug.wrappers.BaseResponse.data` attribute to inspect
|
||||
:attr:`~werkzeug.wrappers.Response.data` attribute to inspect
|
||||
the return value (as string) from the application.
|
||||
In this case, we ensure that ``'No entries here so far'``
|
||||
is part of the output.
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ URL when the register view redirects to the login view.
|
|||
:attr:`~Response.data` contains the body of the response as bytes. If
|
||||
you expect a certain value to render on the page, check that it's in
|
||||
``data``. Bytes must be compared to bytes. If you want to compare text,
|
||||
use :meth:`get_data(as_text=True) <werkzeug.wrappers.BaseResponse.get_data>`
|
||||
use :meth:`get_data(as_text=True) <werkzeug.wrappers.Response.get_data>`
|
||||
instead.
|
||||
|
||||
``pytest.mark.parametrize`` tells Pytest to run the same test function
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
from .cli import main
|
||||
|
||||
main(as_module=True)
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ from werkzeug.routing import Map
|
|||
from werkzeug.routing import RequestRedirect
|
||||
from werkzeug.routing import RoutingException
|
||||
from werkzeug.routing import Rule
|
||||
from werkzeug.wrappers import BaseResponse
|
||||
from werkzeug.wrappers import Response as BaseResponse
|
||||
|
||||
from . import cli
|
||||
from . import json
|
||||
|
|
@ -278,7 +278,7 @@ class Flask(Scaffold):
|
|||
#: This is a ``dict`` instead of an ``ImmutableDict`` to allow
|
||||
#: easier configuration.
|
||||
#:
|
||||
jinja_options = {"extensions": ["jinja2.ext.autoescape", "jinja2.ext.with_"]}
|
||||
jinja_options = {}
|
||||
|
||||
#: Default configuration parameters.
|
||||
default_config = ImmutableDict(
|
||||
|
|
@ -1386,17 +1386,10 @@ class Flask(Scaffold):
|
|||
|
||||
.. versionadded:: 0.7
|
||||
"""
|
||||
if isinstance(e, BadRequestKeyError):
|
||||
if self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]:
|
||||
e.show_exception = True
|
||||
|
||||
# Werkzeug < 0.15 doesn't add the KeyError to the 400
|
||||
# message, add it in manually.
|
||||
# TODO: clean up once Werkzeug >= 0.15.5 is required
|
||||
if e.args[0] not in e.get_description():
|
||||
e.description = f"KeyError: {e.args[0]!r}"
|
||||
elif not hasattr(BadRequestKeyError, "show_exception"):
|
||||
e.args = ()
|
||||
if isinstance(e, BadRequestKeyError) and (
|
||||
self.debug or self.config["TRAP_BAD_REQUEST_ERRORS"]
|
||||
):
|
||||
e.show_exception = True
|
||||
|
||||
if isinstance(e, HTTPException) and not self.trap_http_exception(e):
|
||||
return self.handle_http_exception(e)
|
||||
|
|
@ -1454,10 +1447,7 @@ class Flask(Scaffold):
|
|||
raise e
|
||||
|
||||
self.log_exception(exc_info)
|
||||
server_error = InternalServerError()
|
||||
# TODO: pass as param when Werkzeug>=1.0.0 is required
|
||||
# TODO: also remove note about this from docstring and docs
|
||||
server_error.original_exception = e
|
||||
server_error = InternalServerError(original_exception=e)
|
||||
handler = self._find_error_handler(server_error)
|
||||
|
||||
if handler is not None:
|
||||
|
|
|
|||
|
|
@ -953,10 +953,10 @@ debug mode.
|
|||
)
|
||||
|
||||
|
||||
def main(as_module=False):
|
||||
def main():
|
||||
# TODO omit sys.argv once https://github.com/pallets/click/issues/536 is fixed
|
||||
cli.main(args=sys.argv[1:], prog_name="python -m flask" if as_module else None)
|
||||
cli.main(args=sys.argv[1:])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(as_module=True)
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -439,6 +439,8 @@ def get_flashed_messages(with_categories=False, category_filter=()):
|
|||
def _prepare_send_file_kwargs(
|
||||
download_name=None,
|
||||
attachment_filename=None,
|
||||
etag=None,
|
||||
add_etags=None,
|
||||
max_age=None,
|
||||
cache_timeout=None,
|
||||
**kwargs,
|
||||
|
|
@ -461,12 +463,22 @@ def _prepare_send_file_kwargs(
|
|||
)
|
||||
max_age = cache_timeout
|
||||
|
||||
if add_etags is not None:
|
||||
warnings.warn(
|
||||
"The 'add_etags' parameter has been renamed to 'etag'. The old name will be"
|
||||
" removed in Flask 2.1.",
|
||||
DeprecationWarning,
|
||||
stacklevel=3,
|
||||
)
|
||||
etag = add_etags
|
||||
|
||||
if max_age is None:
|
||||
max_age = current_app.get_send_file_max_age
|
||||
|
||||
kwargs.update(
|
||||
environ=request.environ,
|
||||
download_name=download_name,
|
||||
etag=etag,
|
||||
max_age=max_age,
|
||||
use_x_sendfile=current_app.use_x_sendfile,
|
||||
response_class=current_app.response_class,
|
||||
|
|
@ -482,7 +494,8 @@ def send_file(
|
|||
download_name=None,
|
||||
attachment_filename=None,
|
||||
conditional=True,
|
||||
add_etags=True,
|
||||
etag=True,
|
||||
add_etags=None,
|
||||
last_modified=None,
|
||||
max_age=None,
|
||||
cache_timeout=None,
|
||||
|
|
@ -518,8 +531,8 @@ def send_file(
|
|||
the file. Defaults to the passed file name.
|
||||
:param conditional: Enable conditional and range responses based on
|
||||
request headers. Requires passing a file path and ``environ``.
|
||||
:param add_etags: Calculate an ETag for the file. Requires passing a
|
||||
file path.
|
||||
:param etag: Calculate an ETag for the file, which requires passing
|
||||
a file path. Can also be a string to use instead.
|
||||
:param last_modified: The last modified time to send for the file,
|
||||
in seconds. If not provided, it will try to detect it from the
|
||||
file path.
|
||||
|
|
@ -537,6 +550,10 @@ def send_file(
|
|||
``conditional`` is enabled and ``max_age`` is not set by
|
||||
default.
|
||||
|
||||
.. versionchanged:: 2.0.0
|
||||
``etag`` replaces the ``add_etags`` parameter. It can be a
|
||||
string to use instead of generating one.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
Passing a file-like object that inherits from
|
||||
:class:`~io.TextIOBase` will raise a :exc:`ValueError` rather
|
||||
|
|
@ -593,6 +610,7 @@ def send_file(
|
|||
download_name=download_name,
|
||||
attachment_filename=attachment_filename,
|
||||
conditional=conditional,
|
||||
etag=etag,
|
||||
add_etags=add_etags,
|
||||
last_modified=last_modified,
|
||||
max_age=max_age,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import werkzeug.test
|
|||
from click.testing import CliRunner
|
||||
from werkzeug.test import Client
|
||||
from werkzeug.urls import url_parse
|
||||
from werkzeug.wrappers import BaseRequest
|
||||
from werkzeug.wrappers import Request as BaseRequest
|
||||
|
||||
from . import _request_ctx_stack
|
||||
from .cli import ScriptInfo
|
||||
|
|
|
|||
|
|
@ -1,23 +1,12 @@
|
|||
from werkzeug.exceptions import BadRequest
|
||||
from werkzeug.wrappers import Request as RequestBase
|
||||
from werkzeug.wrappers import Response as ResponseBase
|
||||
from werkzeug.wrappers.json import JSONMixin as _JSONMixin
|
||||
|
||||
from . import json
|
||||
from .globals import current_app
|
||||
|
||||
|
||||
class JSONMixin(_JSONMixin):
|
||||
json_module = json
|
||||
|
||||
def on_json_loading_failed(self, e):
|
||||
if current_app and current_app.debug:
|
||||
raise BadRequest(f"Failed to decode JSON object: {e}")
|
||||
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
class Request(RequestBase, JSONMixin):
|
||||
class Request(RequestBase):
|
||||
"""The request object used by default in Flask. Remembers the
|
||||
matched endpoint and view arguments.
|
||||
|
||||
|
|
@ -30,6 +19,8 @@ class Request(RequestBase, JSONMixin):
|
|||
specific ones.
|
||||
"""
|
||||
|
||||
json_module = json
|
||||
|
||||
#: The internal URL rule that matched the request. This can be
|
||||
#: useful to inspect which methods are allowed for the URL from
|
||||
#: a before/after handler (``request.url_rule.methods``) etc.
|
||||
|
|
@ -89,8 +80,14 @@ class Request(RequestBase, JSONMixin):
|
|||
|
||||
attach_enctype_error_multidict(self)
|
||||
|
||||
def on_json_loading_failed(self, e):
|
||||
if current_app and current_app.debug:
|
||||
raise BadRequest(f"Failed to decode JSON object: {e}")
|
||||
|
||||
class Response(JSONMixin, ResponseBase):
|
||||
raise BadRequest()
|
||||
|
||||
|
||||
class Response(ResponseBase):
|
||||
"""The response object that is used by default in Flask. Works like the
|
||||
response object from Werkzeug but is set to have an HTML mimetype by
|
||||
default. Quite often you don't have to create this object yourself because
|
||||
|
|
@ -110,14 +107,13 @@ class Response(JSONMixin, ResponseBase):
|
|||
|
||||
default_mimetype = "text/html"
|
||||
|
||||
def _get_data_for_json(self, cache):
|
||||
return self.get_data()
|
||||
json_module = json
|
||||
|
||||
@property
|
||||
def max_cookie_size(self):
|
||||
"""Read-only view of the :data:`MAX_COOKIE_SIZE` config key.
|
||||
|
||||
See :attr:`~werkzeug.wrappers.BaseResponse.max_cookie_size` in
|
||||
See :attr:`~werkzeug.wrappers.Response.max_cookie_size` in
|
||||
Werkzeug's docs.
|
||||
"""
|
||||
if current_app:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue