Merge branch '2.0.x'

This commit is contained in:
David Lord 2021-12-22 20:02:52 -07:00
commit 0fb5c2f034
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
4 changed files with 40 additions and 13 deletions

View file

@ -47,6 +47,11 @@ Unreleased
- Fix type annotation for ``errorhandler`` decorator. :issue:`4295` - Fix type annotation for ``errorhandler`` decorator. :issue:`4295`
- Revert a change to the CLI that caused it to hide ``ImportError`` - Revert a change to the CLI that caused it to hide ``ImportError``
tracebacks when importing the application. :issue:`4307` tracebacks when importing the application. :issue:`4307`
- ``app.json_encoder`` and ``json_decoder`` are only passed to
``dumps`` and ``loads`` if they have custom behavior. This improves
performance, mainly on PyPy. :issue:`4349`
- Clearer error message when ``after_this_request`` is used outside a
request context. :issue:`4333`
Version 2.0.2 Version 2.0.2

View file

@ -80,27 +80,34 @@ messages:
Either identify and stop the other program, or use Either identify and stop the other program, or use
``flask run --port 5001`` to pick a different port. ``flask run --port 5001`` to pick a different port.
You can use ``netstat`` to identify what process id is using a port, You can use ``netstat`` or ``lsof`` to identify what process id is using
then use other operating system tools stop that process. The following a port, then use other operating system tools stop that process. The
example shows that process id 6847 is using port 5000. following example shows that process id 6847 is using port 5000.
.. tabs:: .. tabs::
.. group-tab:: Linux/Mac .. tab:: ``netstat`` (Linux)
.. code-block:: text .. code-block:: text
$ netstat -nlp | grep 5000 $ netstat -nlp | grep 5000
tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN 6847/python tcp 0 0 127.0.0.1:5000 0.0.0.0:* LISTEN 6847/python
.. group-tab:: Windows .. tab:: ``lsof`` (macOS / Linux)
.. code-block:: text
$ lsof -P -i :5000
Python 6847 IPv4 TCP localhost:5000 (LISTEN)
.. tab:: ``netstat`` (Windows)
.. code-block:: text .. code-block:: text
> netstat -ano | findstr 5000 > netstat -ano | findstr 5000
TCP 127.0.0.1:5000 0.0.0.0:0 LISTENING 6847 TCP 127.0.0.1:5000 0.0.0.0:0 LISTENING 6847
MacOS Monterey and later automatically starts a service that uses port macOS Monterey and later automatically starts a service that uses port
5000. To disable the service, go to System Preferences, Sharing, and 5000. To disable the service, go to System Preferences, Sharing, and
disable "AirPlay Receiver". disable "AirPlay Receiver".

View file

@ -130,7 +130,15 @@ def after_this_request(f: AfterRequestCallable) -> AfterRequestCallable:
.. versionadded:: 0.9 .. versionadded:: 0.9
""" """
_request_ctx_stack.top._after_request_functions.append(f) top = _request_ctx_stack.top
if top is None:
raise RuntimeError(
"This decorator can only be used when a request context is"
" active, such as within a view function."
)
top._after_request_functions.append(f)
return f return f
@ -159,12 +167,13 @@ def copy_current_request_context(f: t.Callable) -> t.Callable:
.. versionadded:: 0.10 .. versionadded:: 0.10
""" """
top = _request_ctx_stack.top top = _request_ctx_stack.top
if top is None: if top is None:
raise RuntimeError( raise RuntimeError(
"This decorator can only be used at local scopes " "This decorator can only be used when a request context is"
"when a request context is on the stack. For instance within " " active, such as within a view function."
"view functions."
) )
reqctx = top.copy() reqctx = top.copy()
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):

View file

@ -74,6 +74,11 @@ def _dump_arg_defaults(
if bp is not None and bp.json_encoder is not None: if bp is not None and bp.json_encoder is not None:
cls = bp.json_encoder cls = bp.json_encoder
# Only set a custom encoder if it has custom behavior. This is
# faster on PyPy.
if cls is not _json.JSONEncoder:
kwargs.setdefault("cls", cls)
kwargs.setdefault("cls", cls) kwargs.setdefault("cls", cls)
kwargs.setdefault("ensure_ascii", app.config["JSON_AS_ASCII"]) kwargs.setdefault("ensure_ascii", app.config["JSON_AS_ASCII"])
kwargs.setdefault("sort_keys", app.config["JSON_SORT_KEYS"]) kwargs.setdefault("sort_keys", app.config["JSON_SORT_KEYS"])
@ -95,9 +100,10 @@ def _load_arg_defaults(
if bp is not None and bp.json_decoder is not None: if bp is not None and bp.json_decoder is not None:
cls = bp.json_decoder cls = bp.json_decoder
kwargs.setdefault("cls", cls) # Only set a custom decoder if it has custom behavior. This is
else: # faster on PyPy.
kwargs.setdefault("cls", JSONDecoder) if cls not in {JSONDecoder, _json.JSONDecoder}:
kwargs.setdefault("cls", cls)
def dumps(obj: t.Any, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> str: def dumps(obj: t.Any, app: t.Optional["Flask"] = None, **kwargs: t.Any) -> str: