From 235c52fa10094135746d04a5b6a7bea8125357f0 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sat, 29 Mar 2025 14:37:13 -0700 Subject: [PATCH 01/11] fix rtd build --- .readthedocs.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 865c6859..5196b205 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -9,5 +9,6 @@ python: - method: pip path: . sphinx: + configuration: docs/conf.py builder: dirhtml fail_on_warning: true From 165af0a090e229e94ccd93896efc15b9fe0488da Mon Sep 17 00:00:00 2001 From: David Lord Date: Sat, 29 Mar 2025 14:44:59 -0700 Subject: [PATCH 02/11] update dev dependencies --- .github/workflows/pre-commit.yaml | 2 +- .github/workflows/publish.yaml | 12 ++++---- .github/workflows/tests.yaml | 6 ++-- .pre-commit-config.yaml | 2 +- requirements/dev.txt | 50 +++++++++++++++++-------------- requirements/docs.txt | 18 ++++++----- requirements/tests.txt | 6 ++-- requirements/typing.txt | 14 ++++----- src/flask/app.py | 6 ++-- src/flask/testing.py | 6 ++-- 10 files changed, 64 insertions(+), 58 deletions(-) diff --git a/.github/workflows/pre-commit.yaml b/.github/workflows/pre-commit.yaml index 263d42b3..6d1759a8 100644 --- a/.github/workflows/pre-commit.yaml +++ b/.github/workflows/pre-commit.yaml @@ -8,7 +8,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: python-version: 3.x - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1 diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index e6206667..ca55b4dd 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -10,7 +10,7 @@ jobs: hash: ${{ steps.hash.outputs.hash }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: python-version: '3.x' cache: pip @@ -23,7 +23,7 @@ jobs: - name: generate hash id: hash run: cd dist && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT - - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: path: ./dist provenance: @@ -33,7 +33,7 @@ jobs: id-token: write contents: write # Can't pin with hash due to how this workflow works. - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0 + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 with: base64-subjects: ${{ needs.build.outputs.hash }} create-release: @@ -44,7 +44,7 @@ jobs: permissions: contents: write steps: - - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 - name: create release run: > gh release create --draft --repo ${{ github.repository }} @@ -63,7 +63,7 @@ jobs: permissions: id-token: write steps: - - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 - - uses: pypa/gh-action-pypi-publish@15c56dba361d8335944d31a2ecd17d700fc7bcbc # v1.12.2 + - uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1 + - uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4 with: packages-dir: artifact/ diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index fcfb0a80..f44d905d 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -25,7 +25,7 @@ jobs: - {name: Development Versions, python: '3.9', tox: py-dev} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: python-version: ${{ matrix.python }} allow-prereleases: true @@ -37,13 +37,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0 + - uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0 with: python-version: '3.x' cache: pip cache-dependency-path: requirements*/*.txt - name: cache mypy - uses: actions/cache@6849a6489940f00c2f30c0fb92c6274307ccb58a # v4.1.2 + uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: path: ./.mypy_cache key: mypy|${{ hashFiles('pyproject.toml') }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7db182a0..299c4584 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.7.3 + rev: v0.11.2 hooks: - id: ruff - id: ruff-format diff --git a/requirements/dev.txt b/requirements/dev.txt index e1056206..2bc16c1e 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -12,13 +12,13 @@ asgiref==3.8.1 # via # -r /Users/david/Projects/flask/requirements/tests.txt # -r /Users/david/Projects/flask/requirements/typing.txt -babel==2.16.0 +babel==2.17.0 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx -cachetools==5.5.0 +cachetools==5.5.2 # via tox -certifi==2024.8.30 +certifi==2025.1.31 # via # -r /Users/david/Projects/flask/requirements/docs.txt # requests @@ -30,13 +30,13 @@ cfgv==3.4.0 # via pre-commit chardet==5.2.0 # via tox -charset-normalizer==3.4.0 +charset-normalizer==3.4.1 # via # -r /Users/david/Projects/flask/requirements/docs.txt # requests colorama==0.4.6 # via tox -cryptography==43.0.3 +cryptography==44.0.2 # via -r /Users/david/Projects/flask/requirements/typing.txt distlib==0.3.9 # via virtualenv @@ -45,11 +45,11 @@ docutils==0.21.2 # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx # sphinx-tabs -filelock==3.16.1 +filelock==3.18.0 # via # tox # virtualenv -identify==2.6.2 +identify==2.6.9 # via pre-commit idna==3.10 # via @@ -59,12 +59,12 @@ imagesize==1.4.1 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx -iniconfig==2.0.0 +iniconfig==2.1.0 # via # -r /Users/david/Projects/flask/requirements/tests.txt # -r /Users/david/Projects/flask/requirements/typing.txt # pytest -jinja2==3.1.4 +jinja2==3.1.6 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx @@ -72,7 +72,7 @@ markupsafe==3.0.2 # via # -r /Users/david/Projects/flask/requirements/docs.txt # jinja2 -mypy==1.13.0 +mypy==1.15.0 # via -r /Users/david/Projects/flask/requirements/typing.txt mypy-extensions==1.0.0 # via @@ -95,7 +95,7 @@ packaging==24.2 # tox pallets-sphinx-themes==2.3.0 # via -r /Users/david/Projects/flask/requirements/docs.txt -platformdirs==4.3.6 +platformdirs==4.3.7 # via # tox # virtualenv @@ -105,26 +105,26 @@ pluggy==1.5.0 # -r /Users/david/Projects/flask/requirements/typing.txt # pytest # tox -pre-commit==4.0.1 +pre-commit==4.2.0 # via -r dev.in pycparser==2.22 # via # -r /Users/david/Projects/flask/requirements/typing.txt # cffi -pygments==2.18.0 +pygments==2.19.1 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx # sphinx-tabs -pyproject-api==1.8.0 +pyproject-api==1.9.0 # via tox -pyright==1.1.389 +pyright==1.1.398 # via -r /Users/david/Projects/flask/requirements/typing.txt -pytest==8.3.3 +pytest==8.3.5 # via # -r /Users/david/Projects/flask/requirements/tests.txt # -r /Users/david/Projects/flask/requirements/typing.txt -python-dotenv==1.0.1 +python-dotenv==1.1.0 # via # -r /Users/david/Projects/flask/requirements/tests.txt # -r /Users/david/Projects/flask/requirements/typing.txt @@ -134,18 +134,22 @@ requests==2.32.3 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx +roman-numerals-py==3.1.0 + # via + # -r /Users/david/Projects/flask/requirements/docs.txt + # sphinx snowballstemmer==2.2.0 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx -sphinx==8.1.3 +sphinx==8.2.3 # via # -r /Users/david/Projects/flask/requirements/docs.txt # pallets-sphinx-themes # sphinx-notfound-page # sphinx-tabs # sphinxcontrib-log-cabinet -sphinx-notfound-page==1.0.4 +sphinx-notfound-page==1.1.0 # via # -r /Users/david/Projects/flask/requirements/docs.txt # pallets-sphinx-themes @@ -177,22 +181,22 @@ sphinxcontrib-serializinghtml==2.0.0 # via # -r /Users/david/Projects/flask/requirements/docs.txt # sphinx -tox==4.23.2 +tox==4.25.0 # via -r dev.in types-contextvars==2.4.7.3 # via -r /Users/david/Projects/flask/requirements/typing.txt types-dataclasses==0.6.6 # via -r /Users/david/Projects/flask/requirements/typing.txt -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # -r /Users/david/Projects/flask/requirements/typing.txt # mypy # pyright -urllib3==2.2.3 +urllib3==2.3.0 # via # -r /Users/david/Projects/flask/requirements/docs.txt # requests -virtualenv==20.27.1 +virtualenv==20.29.3 # via # pre-commit # tox diff --git a/requirements/docs.txt b/requirements/docs.txt index 47c22099..ac300f44 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -6,11 +6,11 @@ # alabaster==1.0.0 # via sphinx -babel==2.16.0 +babel==2.17.0 # via sphinx -certifi==2024.8.30 +certifi==2025.1.31 # via requests -charset-normalizer==3.4.0 +charset-normalizer==3.4.1 # via requests docutils==0.21.2 # via @@ -20,7 +20,7 @@ idna==3.10 # via requests imagesize==1.4.1 # via sphinx -jinja2==3.1.4 +jinja2==3.1.6 # via sphinx markupsafe==3.0.2 # via jinja2 @@ -30,22 +30,24 @@ packaging==24.2 # sphinx pallets-sphinx-themes==2.3.0 # via -r docs.in -pygments==2.18.0 +pygments==2.19.1 # via # sphinx # sphinx-tabs requests==2.32.3 # via sphinx +roman-numerals-py==3.1.0 + # via sphinx snowballstemmer==2.2.0 # via sphinx -sphinx==8.1.3 +sphinx==8.2.3 # via # -r docs.in # pallets-sphinx-themes # sphinx-notfound-page # sphinx-tabs # sphinxcontrib-log-cabinet -sphinx-notfound-page==1.0.4 +sphinx-notfound-page==1.1.0 # via pallets-sphinx-themes sphinx-tabs==3.4.7 # via -r docs.in @@ -63,5 +65,5 @@ sphinxcontrib-qthelp==2.0.0 # via sphinx sphinxcontrib-serializinghtml==2.0.0 # via sphinx -urllib3==2.2.3 +urllib3==2.3.0 # via requests diff --git a/requirements/tests.txt b/requirements/tests.txt index cc8b9a2e..9457c2b7 100644 --- a/requirements/tests.txt +++ b/requirements/tests.txt @@ -6,13 +6,13 @@ # asgiref==3.8.1 # via -r tests.in -iniconfig==2.0.0 +iniconfig==2.1.0 # via pytest packaging==24.2 # via pytest pluggy==1.5.0 # via pytest -pytest==8.3.3 +pytest==8.3.5 # via -r tests.in -python-dotenv==1.0.1 +python-dotenv==1.1.0 # via -r tests.in diff --git a/requirements/typing.txt b/requirements/typing.txt index 7eddb5f1..cb9a05f9 100644 --- a/requirements/typing.txt +++ b/requirements/typing.txt @@ -8,11 +8,11 @@ asgiref==3.8.1 # via -r typing.in cffi==1.17.1 # via cryptography -cryptography==43.0.3 +cryptography==44.0.2 # via -r typing.in -iniconfig==2.0.0 +iniconfig==2.1.0 # via pytest -mypy==1.13.0 +mypy==1.15.0 # via -r typing.in mypy-extensions==1.0.0 # via mypy @@ -24,17 +24,17 @@ pluggy==1.5.0 # via pytest pycparser==2.22 # via cffi -pyright==1.1.389 +pyright==1.1.398 # via -r typing.in -pytest==8.3.3 +pytest==8.3.5 # via -r typing.in -python-dotenv==1.0.1 +python-dotenv==1.1.0 # via -r typing.in types-contextvars==2.4.7.3 # via -r typing.in types-dataclasses==0.6.6 # via -r typing.in -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # mypy # pyright diff --git a/src/flask/app.py b/src/flask/app.py index 905b2477..d2743c41 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -265,9 +265,9 @@ class Flask(App): # For one, it might be created while the server is running (e.g. during # development). Also, Google App Engine stores static files somewhere if self.has_static_folder: - assert ( - bool(static_host) == host_matching - ), "Invalid static_host/host_matching combination" + assert bool(static_host) == host_matching, ( + "Invalid static_host/host_matching combination" + ) # Use a weakref to avoid creating a reference cycle between the app # and the view function (see #3761). self_ref = weakref.ref(self) diff --git a/src/flask/testing.py b/src/flask/testing.py index a62c4836..da156cc1 100644 --- a/src/flask/testing.py +++ b/src/flask/testing.py @@ -58,9 +58,9 @@ class EnvironBuilder(werkzeug.test.EnvironBuilder): ) -> None: assert not (base_url or subdomain or url_scheme) or ( base_url is not None - ) != bool( - subdomain or url_scheme - ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + ) != bool(subdomain or url_scheme), ( + 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + ) if base_url is None: http_host = app.config.get("SERVER_NAME") or "localhost" From 75a8327cfd6eb912e469a8a613151d7ee50a1c1c Mon Sep 17 00:00:00 2001 From: zhuangzhuang Date: Wed, 27 Nov 2024 18:14:18 +0800 Subject: [PATCH 03/11] Update mongoengine.rst --- docs/patterns/mongoengine.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/patterns/mongoengine.rst b/docs/patterns/mongoengine.rst index 015e7b61..624988e4 100644 --- a/docs/patterns/mongoengine.rst +++ b/docs/patterns/mongoengine.rst @@ -80,7 +80,7 @@ Queries Use the class ``objects`` attribute to make queries. A keyword argument looks for an equal value on the field. :: - bttf = Movies.objects(title="Back To The Future").get_or_404() + bttf = Movie.objects(title="Back To The Future").get_or_404() Query operators may be used by concatenating them with the field name using a double-underscore. ``objects``, and queries returned by From f51a23839aa55aee2f2a9196c344df6eecd854d7 Mon Sep 17 00:00:00 2001 From: kotvkvante Date: Sun, 26 Jan 2025 01:12:11 +0300 Subject: [PATCH 04/11] fix bash cli syntax error and app name --- docs/patterns/appfactories.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/patterns/appfactories.rst b/docs/patterns/appfactories.rst index 32fd062b..0f248783 100644 --- a/docs/patterns/appfactories.rst +++ b/docs/patterns/appfactories.rst @@ -99,9 +99,9 @@ to the factory like this: .. code-block:: text - $ flask --app hello:create_app(local_auth=True) run + $ flask --app 'hello:create_app(local_auth=True)' run -Then the ``create_app`` factory in ``myapp`` is called with the keyword +Then the ``create_app`` factory in ``hello`` is called with the keyword argument ``local_auth=True``. See :doc:`/cli` for more detail. Factory Improvements From da600394865c06a4772c433c1a560453dcf4f868 Mon Sep 17 00:00:00 2001 From: George Waters Date: Wed, 29 Jan 2025 22:22:52 -0500 Subject: [PATCH 05/11] Handle help arg by itself the same as no args When the 'flask' command is used with only the '--help' parameter, this change will make sure to try and load the app before the help callback is run. This was previously only being done when the 'flask' command was used by itself. This meant when passing in '--help', any custom commands were not getting shown in the help message. With this change, custom commands will be included in the help message when running 'flask' on the command line by itself or with the '--help' parameter. --- CHANGES.rst | 2 ++ src/flask/cli.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 14c6a6ac..fd88e12d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ Version 3.1.1 Unreleased - Fix type hint for `cli_runner.invoke`. :issue:`5645` +- ``flask --help`` loads the app and plugins first to make sure all commands + are shown. :issue:5673` Version 3.1.0 diff --git a/src/flask/cli.py b/src/flask/cli.py index dd03f3c5..ed11f256 100644 --- a/src/flask/cli.py +++ b/src/flask/cli.py @@ -684,7 +684,9 @@ class FlaskGroup(AppGroup): return super().make_context(info_name, args, parent=parent, **extra) def parse_args(self, ctx: click.Context, args: list[str]) -> list[str]: - if not args and self.no_args_is_help: + if (not args and self.no_args_is_help) or ( + len(args) == 1 and args[0] in self.get_help_option_names(ctx) + ): # Attempt to load --env-file and --app early in case they # were given as env vars. Otherwise no_args_is_help will not # see commands from app.cli. From 2ae36c8dd5c9d24578d9fca85f8c351290d0de04 Mon Sep 17 00:00:00 2001 From: black Date: Mon, 24 Mar 2025 10:42:52 +0100 Subject: [PATCH 06/11] Remove HTTP Public Key Pinning from docs The header is considered obsolete and no longer supported by any major browser. MDN link is dead. --- docs/web-security.rst | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/docs/web-security.rst b/docs/web-security.rst index f13bb7b8..d742056f 100644 --- a/docs/web-security.rst +++ b/docs/web-security.rst @@ -269,19 +269,6 @@ values (or any values that need secure signatures). .. _samesite_support: https://caniuse.com/#feat=same-site-cookie-attribute -HTTP Public Key Pinning (HPKP) -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -This tells the browser to authenticate with the server using only the specific -certificate key to prevent MITM attacks. - -.. warning:: - Be careful when enabling this, as it is very difficult to undo if you set up - or upgrade your key incorrectly. - -- https://developer.mozilla.org/en-US/docs/Web/HTTP/Public_Key_Pinning - - Copy/Paste to Terminal ---------------------- From 7d5d1874581209f66ad7bcdfb7f85b2b9a7ca471 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sat, 29 Mar 2025 15:23:34 -0700 Subject: [PATCH 07/11] better type checking during deprecation --- src/flask/__init__.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/flask/__init__.py b/src/flask/__init__.py index 7440aef1..1fdc50ce 100644 --- a/src/flask/__init__.py +++ b/src/flask/__init__.py @@ -42,19 +42,20 @@ from .templating import stream_template_string as stream_template_string from .wrappers import Request as Request from .wrappers import Response as Response +if not t.TYPE_CHECKING: -def __getattr__(name: str) -> t.Any: - if name == "__version__": - import importlib.metadata - import warnings + def __getattr__(name: str) -> t.Any: + if name == "__version__": + import importlib.metadata + import warnings - warnings.warn( - "The '__version__' attribute is deprecated and will be removed in" - " Flask 3.2. Use feature detection or" - " 'importlib.metadata.version(\"flask\")' instead.", - DeprecationWarning, - stacklevel=2, - ) - return importlib.metadata.version("flask") + warnings.warn( + "The '__version__' attribute is deprecated and will be removed in" + " Flask 3.2. Use feature detection or" + " 'importlib.metadata.version(\"flask\")' instead.", + DeprecationWarning, + stacklevel=2, + ) + return importlib.metadata.version("flask") - raise AttributeError(name) + raise AttributeError(name) From c94d2a77db0102a7cf8ceec7804f366f180c373f Mon Sep 17 00:00:00 2001 From: David Lord Date: Sat, 29 Mar 2025 15:30:56 -0700 Subject: [PATCH 08/11] add endpoint name in favicon example --- docs/patterns/favicon.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/patterns/favicon.rst b/docs/patterns/favicon.rst index 21ea767f..b867854f 100644 --- a/docs/patterns/favicon.rst +++ b/docs/patterns/favicon.rst @@ -24,8 +24,11 @@ the root path of the domain you either need to configure the web server to serve the icon at the root or if you can't do that you're out of luck. If however your application is the root you can simply route a redirect:: - app.add_url_rule('/favicon.ico', - redirect_to=url_for('static', filename='favicon.ico')) + app.add_url_rule( + "/favicon.ico", + endpoint="favicon", + redirect_to=url_for("static", filename="favicon.ico"), + ) If you want to save the extra redirect request you can also write a view using :func:`~flask.send_from_directory`:: From 41ec5760a2c55a099c3a1733fdd36fbb1258a02b Mon Sep 17 00:00:00 2001 From: David Lord Date: Sat, 29 Mar 2025 15:42:58 -0700 Subject: [PATCH 09/11] remove tests about deprecated pkgutil.get_loader --- tests/conftest.py | 32 -------------------------------- tests/test_instance_config.py | 6 +++--- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 58cf85d8..214f5203 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,5 +1,4 @@ import os -import pkgutil import sys import pytest @@ -96,37 +95,6 @@ def leak_detector(): assert leaks == [] -@pytest.fixture(params=(True, False)) -def limit_loader(request, monkeypatch): - """Patch pkgutil.get_loader to give loader without get_filename or archive. - - This provides for tests where a system has custom loaders, e.g. Google App - Engine's HardenedModulesHook, which have neither the `get_filename` method - nor the `archive` attribute. - - This fixture will run the testcase twice, once with and once without the - limitation/mock. - """ - if not request.param: - return - - class LimitedLoader: - def __init__(self, loader): - self.loader = loader - - def __getattr__(self, name): - if name in {"archive", "get_filename"}: - raise AttributeError(f"Mocking a loader which does not have {name!r}.") - return getattr(self.loader, name) - - old_get_loader = pkgutil.get_loader - - def get_loader(*args, **kwargs): - return LimitedLoader(old_get_loader(*args, **kwargs)) - - monkeypatch.setattr(pkgutil, "get_loader", get_loader) - - @pytest.fixture def modules_tmp_path(tmp_path, monkeypatch): """A temporary directory added to sys.path.""" diff --git a/tests/test_instance_config.py b/tests/test_instance_config.py index 1918bd99..835a8784 100644 --- a/tests/test_instance_config.py +++ b/tests/test_instance_config.py @@ -63,7 +63,7 @@ def test_uninstalled_namespace_paths(tmp_path, monkeypatch, purge_module): def test_installed_module_paths( - modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages, limit_loader + modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages ): (site_packages / "site_app.py").write_text( "import flask\napp = flask.Flask(__name__)\n" @@ -78,7 +78,7 @@ def test_installed_module_paths( def test_installed_package_paths( - limit_loader, modules_tmp_path, modules_tmp_path_prefix, purge_module, monkeypatch + modules_tmp_path, modules_tmp_path_prefix, purge_module, monkeypatch ): installed_path = modules_tmp_path / "path" installed_path.mkdir() @@ -97,7 +97,7 @@ def test_installed_package_paths( def test_prefix_package_paths( - limit_loader, modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages + modules_tmp_path, modules_tmp_path_prefix, purge_module, site_packages ): app = site_packages / "site_package" app.mkdir() From bfffe87d4c2ea255b9a51432bebb3d28741245c4 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sat, 29 Mar 2025 15:57:16 -0700 Subject: [PATCH 10/11] add ghsa links --- CHANGES.rst | 1 + docs/conf.py | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index fd88e12d..a65b68b5 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -107,6 +107,7 @@ Released 2023-05-01 - Set ``Vary: Cookie`` header when the session is accessed, modified, or refreshed. - Update Werkzeug requirement to >=2.3.3 to apply recent bug fixes. + :ghsa:`m2qf-hxjv-5gpq` Version 2.3.1 diff --git a/docs/conf.py b/docs/conf.py index a7b8f919..eca4f810 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,6 +26,7 @@ autodoc_preserve_defaults = True extlinks = { "issue": ("https://github.com/pallets/flask/issues/%s", "#%s"), "pr": ("https://github.com/pallets/flask/pull/%s", "#%s"), + "ghsa": ("https://github.com/pallets/flask/security/advisories/GHSA-%s", "GHSA-%s"), } intersphinx_mapping = { "python": ("https://docs.python.org/3/", None), From 410e5ab7ed0ef326fa8b5164a633863f137ffff5 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Mon, 18 Nov 2024 12:55:14 -0600 Subject: [PATCH 11/11] Accept `AsyncIterable` for responses --- CHANGES.rst | 3 +++ src/flask/typing.py | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CHANGES.rst b/CHANGES.rst index a65b68b5..51c99d42 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,9 @@ Unreleased - Fix type hint for `cli_runner.invoke`. :issue:`5645` - ``flask --help`` loads the app and plugins first to make sure all commands are shown. :issue:5673` +- Mark sans-io base class as being able to handle views that return + ``AsyncIterable``. This is not accurate for Flask, but makes typing easier + for Quart. :pr:`5659` Version 3.1.0 diff --git a/src/flask/typing.py b/src/flask/typing.py index e7234e96..6b70c409 100644 --- a/src/flask/typing.py +++ b/src/flask/typing.py @@ -1,5 +1,6 @@ from __future__ import annotations +import collections.abc as cabc import typing as t if t.TYPE_CHECKING: # pragma: no cover @@ -17,6 +18,8 @@ ResponseValue = t.Union[ t.Mapping[str, t.Any], t.Iterator[str], t.Iterator[bytes], + cabc.AsyncIterable[str], # for Quart, until App is generic. + cabc.AsyncIterable[bytes], ] # the possible types for an individual HTTP header