From a841cfabb58d3c1ac1d11b09353f458e759a63c2 Mon Sep 17 00:00:00 2001 From: olliemath Date: Sat, 20 Nov 2021 14:05:57 +0000 Subject: [PATCH 1/5] Only use a custom JSONDecoder if needed The default JSONDecoder adds no extra functionality to `json.loads`, but using a custom class in the function call you off of an optimized fast path in pypy (it adds some overhead in cpython, but I think it's minimal). This change sticks with the default loading behaviour unless the user has specifically opted in to customising it. Co-authored-by: David Lord --- CHANGES.rst | 3 +++ src/flask/json/__init__.py | 12 +++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 05609229..1af03f26 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -12,6 +12,9 @@ Unreleased - Fix type annotation for ``errorhandler`` decorator. :issue:`4295` - Revert a change to the CLI that caused it to hide ``ImportError`` 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` Version 2.0.2 diff --git a/src/flask/json/__init__.py b/src/flask/json/__init__.py index 10d5123a..ccb9efb1 100644 --- a/src/flask/json/__init__.py +++ b/src/flask/json/__init__.py @@ -81,6 +81,11 @@ def _dump_arg_defaults( if bp is not None and bp.json_encoder is not None: 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("ensure_ascii", app.config["JSON_AS_ASCII"]) kwargs.setdefault("sort_keys", app.config["JSON_SORT_KEYS"]) @@ -102,9 +107,10 @@ def _load_arg_defaults( if bp is not None and bp.json_decoder is not None: cls = bp.json_decoder - kwargs.setdefault("cls", cls) - else: - kwargs.setdefault("cls", JSONDecoder) + # Only set a custom decoder if it has custom behavior. This is + # faster on PyPy. + 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: From 633449a36c959d25577799eb3da76005a803d5cd Mon Sep 17 00:00:00 2001 From: Yourun-Proger Date: Fri, 19 Nov 2021 23:09:38 +0300 Subject: [PATCH 2/5] fix error message --- CHANGES.rst | 2 ++ src/flask/ctx.py | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 1af03f26..3785f737 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,6 +15,8 @@ Unreleased - ``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` +- Fix error message for ``after_this_request`` when it used outside + request context. :issue:`4333` Version 2.0.2 diff --git a/src/flask/ctx.py b/src/flask/ctx.py index 5c064635..5149c821 100644 --- a/src/flask/ctx.py +++ b/src/flask/ctx.py @@ -130,7 +130,15 @@ def after_this_request(f: AfterRequestCallable) -> AfterRequestCallable: .. 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 at local scopes " + "when a request context is on the stack. For instance within " + "view functions." + ) + top._after_request_functions.append(f) + return f From b1a00ebc4c6f15055ddf15ecb17243a089f52a60 Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 22 Dec 2021 18:44:37 -0700 Subject: [PATCH 3/5] update error message for after_this_request and copy_current_request_context --- CHANGES.rst | 2 +- src/flask/ctx.py | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3785f737..cca0c44d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -15,7 +15,7 @@ Unreleased - ``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` -- Fix error message for ``after_this_request`` when it used outside +- Clearer error message when ``after_this_request`` is used outside a request context. :issue:`4333` diff --git a/src/flask/ctx.py b/src/flask/ctx.py index 5149c821..47465fd4 100644 --- a/src/flask/ctx.py +++ b/src/flask/ctx.py @@ -131,14 +131,14 @@ def after_this_request(f: AfterRequestCallable) -> AfterRequestCallable: .. versionadded:: 0.9 """ top = _request_ctx_stack.top + if top is None: raise RuntimeError( - "This decorator can only be used at local scopes " - "when a request context is on the stack. For instance within " - "view functions." + "This decorator can only be used when a request context is" + " active, such as within a view function." ) - top._after_request_functions.append(f) + top._after_request_functions.append(f) return f @@ -167,12 +167,13 @@ def copy_current_request_context(f: t.Callable) -> t.Callable: .. versionadded:: 0.10 """ top = _request_ctx_stack.top + if top is None: raise RuntimeError( - "This decorator can only be used at local scopes " - "when a request context is on the stack. For instance within " - "view functions." + "This decorator can only be used when a request context is" + " active, such as within a view function." ) + reqctx = top.copy() def wrapper(*args, **kwargs): From 0122a4f34f2d4f68fc64ca14532f2fbaed5c302f Mon Sep 17 00:00:00 2001 From: Grey Li Date: Sun, 12 Dec 2021 12:05:44 +0800 Subject: [PATCH 4/5] Fix the command for checking port on macOS in server docs --- docs/server.rst | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/server.rst b/docs/server.rst index 446d5be8..77b25abb 100644 --- a/docs/server.rst +++ b/docs/server.rst @@ -80,27 +80,34 @@ messages: Either identify and stop the other program, or use ``flask run --port 5001`` to pick a different port. -You can use ``netstat`` to identify what process id is using a port, -then use other operating system tools stop that process. The following -example shows that process id 6847 is using port 5000. +You can use ``netstat`` or ``lsof`` to identify what process id is using +a port, then use other operating system tools stop that process. The +following example shows that process id 6847 is using port 5000. .. tabs:: - .. group-tab:: Linux/Mac + .. tab:: ``netstat`` (Linux) .. code-block:: text $ netstat -nlp | grep 5000 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 > netstat -ano | findstr 5000 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 disable "AirPlay Receiver". From 1a1c7ea61860ad97a998b24532f0a89a5aee7914 Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 22 Dec 2021 19:58:07 -0700 Subject: [PATCH 5/5] pin os and python version in rtd build (cherry picked from commit 93a7f08bbca37de2ef73cc21ebfcb6e446087616) --- .readthedocs.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 0c363636..3d3feac4 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -1,4 +1,8 @@ version: 2 +build: + os: ubuntu-20.04 + tools: + python: 3.10 python: install: - requirements: requirements/docs.txt