Compare commits

...

17 Commits

Author SHA1 Message Date
David Lord bfffe87d4c
add ghsa links
pre-commit / main (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (3.10) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (3.11) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (3.12) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (3.13) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (3.9) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (Development Versions, 3.9, py-dev) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (Mac, macos-latest, 3.12) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (Minimum Versions, 3.12, py-min) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (PyPy, pypy-3.10, pypy310) (push) Waiting to run Details
Tests / ${{ matrix.name || matrix.python }} (Windows, windows-latest, 3.12) (push) Waiting to run Details
Tests / typing (push) Waiting to run Details
2025-03-29 15:57:16 -07:00
David Lord 73ce26c3e8
remove tests about deprecated pkgutil.get_loader (#5702) 2025-03-29 15:45:11 -07:00
David Lord 41ec5760a2
remove tests about deprecated pkgutil.get_loader 2025-03-29 15:42:58 -07:00
David Lord 2732c4db66
add endpoint name in favicon example (#5701) 2025-03-29 15:32:28 -07:00
David Lord c94d2a77db
add endpoint name in favicon example 2025-03-29 15:30:56 -07:00
David Lord 315ebc1176
better type checking during deprecation (#5700) 2025-03-29 15:28:27 -07:00
David Lord 7d5d187458
better type checking during deprecation 2025-03-29 15:23:34 -07:00
David Lord c7c8dc38ea
Remove HTTP Public Key Pinning from docs (#5695) 2025-03-29 15:17:48 -07:00
black 2ae36c8dd5
Remove HTTP Public Key Pinning from docs
The header is considered obsolete and no longer supported by any major
browser. MDN link is dead.
2025-03-29 15:16:24 -07:00
David Lord 5ea0ab8ea2
Handle help arg by itself the same as no args (#5674) 2025-03-29 15:15:04 -07:00
George Waters da60039486
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.
2025-03-29 15:13:23 -07:00
David Lord 08c480b3b3
Update app factory docs (#5671) 2025-03-29 15:10:55 -07:00
kotvkvante f51a23839a fix bash cli syntax error and app name 2025-03-29 15:09:26 -07:00
David Lord 04b070fa26
Fix typo in the docs (#5650) 2025-03-29 14:49:06 -07:00
zhuangzhuang 75a8327cfd
Update mongoengine.rst 2025-03-29 14:47:41 -07:00
David Lord 165af0a090
update dev dependencies 2025-03-29 14:44:59 -07:00
David Lord 235c52fa10
fix rtd build 2025-03-29 14:37:13 -07:00
21 changed files with 97 additions and 125 deletions

View File

@ -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

View File

@ -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/

View File

@ -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') }}

View File

@ -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

View File

@ -9,5 +9,6 @@ python:
- method: pip
path: .
sphinx:
configuration: docs/conf.py
builder: dirhtml
fail_on_warning: true

View File

@ -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
@ -105,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

View File

@ -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),

View File

@ -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

View File

@ -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`::

View File

@ -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

View File

@ -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
----------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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.

View File

@ -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"

View File

@ -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."""

View File

@ -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()