Compare commits

...

11 Commits

Author SHA1 Message Date
abhiram kamini 7bf3be8dfa
Update server.rst
made changes to rename system preferences to system settings according to new mac os name change
2025-06-04 17:24:45 -07:00
David Lord a42c4d54a3
Fix global CONTRIBUTING link (#5737)
pre-commit / main (push) Has been cancelled Details
2025-05-20 12:30:04 -04:00
AJ Jordan 184ec3c545
Fix global CONTRIBUTING link 2025-05-20 12:26:17 -04:00
David Lord bbaf13333f
fix syntax
pre-commit / main (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.10) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.11) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.12) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.13) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.9) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Development Versions, 3.10, tests-dev) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Mac, macos-latest, 3.13) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Minimum Versions, 3.13, tests-min) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (PyPy, pypy-3.11, pypy3.11) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Windows, windows-latest, 3.13) (push) Has been cancelled Details
Tests / typing (push) Has been cancelled Details
2025-05-13 08:09:39 -07:00
David Lord 57e7286948
release version 3.1.1 (#5730) 2025-05-13 08:01:42 -07:00
David Lord 7fff56f517
release version 3.1.1 2025-05-13 07:51:12 -07:00
David Lord 73d6504063
Merge commit from fork
Sessions: fix signing key selection when key rotation is enabled
2025-05-13 07:46:54 -07:00
David Lord cbb6c36692
update docs about fallback order 2025-05-12 18:30:27 -07:00
James Addison fb54159861
secret key rotation: fix key list ordering
The `itsdangerous` serializer interface[1] expects keys to be
provided with the oldest key at index zero and the active signing key
at the end of the list.

We document[2] that `SECRET_KEY_FALLBACKS` should be configured with
the most recent first (at index zero), so to achieve the expected
behaviour, those should be inserted in reverse-order at the head of
the list.

[1] - https://itsdangerous.palletsprojects.com/en/stable/serializer/#itsdangerous.serializer.Serializer

[2] - https://flask.palletsprojects.com/en/stable/config/#SECRET_KEY_FALLBACKS
2025-05-12 18:30:27 -07:00
David Lord 941efd4a36
use uv (#5727)
pre-commit / main (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.10) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.11) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.12) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.13) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (3.9) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Development Versions, 3.10, tests-dev) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Mac, macos-latest, 3.13) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Minimum Versions, 3.13, tests-min) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (PyPy, pypy-3.11, pypy3.11) (push) Has been cancelled Details
Tests / ${{ matrix.name || matrix.python }} (Windows, windows-latest, 3.13) (push) Has been cancelled Details
Tests / typing (push) Has been cancelled Details
2025-05-11 18:04:35 -07:00
David Lord 0109e496f6
use uv 2025-05-11 17:58:53 -07:00
30 changed files with 1903 additions and 548 deletions

View File

@ -10,6 +10,7 @@ on:
permissions:
issues: write
pull-requests: write
discussions: write
concurrency:
group: lock
jobs:

View File

@ -7,10 +7,19 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
with:
python-version: 3.x
- uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
if: ${{ !cancelled() }}
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
with:
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
id: setup-python
with:
python-version-file: pyproject.toml
- uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ~/.cache/pre-commit
key: pre-commit|${{ hashFiles('pyproject.toml', '.pre-commit-config.yaml') }}
- run: uv run --locked --group pre-commit pre-commit run --show-diff-on-failure --color=always --all-files
- uses: pre-commit-ci/lite-action@5d6cc0eb514c891a40562a58a8e71576c5c7fb43 # v1.1.0
if: ${{ !cancelled() }}

View File

@ -1,8 +1,7 @@
name: Publish
on:
push:
tags:
- '*'
tags: ['*']
jobs:
build:
runs-on: ubuntu-latest
@ -10,16 +9,15 @@ jobs:
hash: ${{ steps.hash.outputs.hash }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
with:
python-version: '3.x'
cache: pip
cache-dependency-path: requirements*/*.txt
- run: pip install -r requirements/build.txt
# Use the commit date instead of the current date during the build.
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version-file: pyproject.toml
- run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> $GITHUB_ENV
- run: python -m build
# Generate hashes used for provenance.
- run: uv build
- name: generate hash
id: hash
run: cd dist && echo "hash=$(sha256sum * | base64 -w0)" >> $GITHUB_OUTPUT
@ -37,14 +35,12 @@ jobs:
with:
base64-subjects: ${{ needs.build.outputs.hash }}
create-release:
# Upload the sdist, wheels, and provenance to a GitHub release. They remain
# available as build artifacts for a while as well.
needs: [provenance]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- name: create release
run: >
gh release create --draft --repo ${{ github.repository }}
@ -54,8 +50,6 @@ jobs:
GH_TOKEN: ${{ github.token }}
publish-pypi:
needs: [provenance]
# Wait for approval before attempting to upload to PyPI. This allows reviewing the
# files in the draft release.
environment:
name: publish
url: https://pypi.org/project/Flask/${{ github.ref_name }}
@ -63,7 +57,7 @@ jobs:
permissions:
id-token: write
steps:
- uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
- uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # v1.12.4
with:
packages-dir: artifact/

View File

@ -1,10 +1,10 @@
name: Tests
on:
pull_request:
paths-ignore: ['docs/**', 'README.md']
push:
branches: [main, stable]
paths-ignore: ['docs/**', '*.md', '*.rst']
pull_request:
paths-ignore: [ 'docs/**', '*.md', '*.rst' ]
paths-ignore: ['docs/**', 'README.md']
jobs:
tests:
name: ${{ matrix.name || matrix.python }}
@ -14,38 +14,39 @@ jobs:
matrix:
include:
- {python: '3.13'}
- {name: Windows, python: '3.13', os: windows-latest}
- {name: Mac, python: '3.13', os: macos-latest}
- {python: '3.12'}
- {name: Windows, python: '3.12', os: windows-latest}
- {name: Mac, python: '3.12', os: macos-latest}
- {python: '3.11'}
- {python: '3.10'}
- {python: '3.9'}
- {name: PyPy, python: 'pypy-3.10', tox: pypy310}
- {name: Minimum Versions, python: '3.12', tox: py-min}
- {name: Development Versions, python: '3.9', tox: py-dev}
- {name: PyPy, python: 'pypy-3.11', tox: pypy3.11}
- {name: Minimum Versions, python: '3.13', tox: tests-min}
- {name: Development Versions, python: '3.10', tox: tests-dev}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
with:
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version: ${{ matrix.python }}
allow-prereleases: true
cache: pip
cache-dependency-path: requirements*/*.txt
- run: pip install tox
- run: tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }}
- run: uv run --locked tox run -e ${{ matrix.tox || format('py{0}', matrix.python) }}
typing:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- uses: actions/setup-python@8d9ed9ac5c53483de85588cdf95a591a75ab9f55 # v5.5.0
- uses: astral-sh/setup-uv@6b9c6063abd6010835644d4c2e1bef4cf5cd0fca # v6.0.1
with:
python-version: '3.x'
cache: pip
cache-dependency-path: requirements*/*.txt
enable-cache: true
prune-cache: false
- uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0
with:
python-version-file: pyproject.toml
- name: cache mypy
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: ./.mypy_cache
key: mypy|${{ hashFiles('pyproject.toml') }}
- run: pip install tox
- run: tox run -e typing
- run: uv run --locked tox run -e typing

2
.gitignore vendored
View File

@ -1,7 +1,5 @@
.idea/
.vscode/
.venv*/
venv*/
__pycache__/
dist/
.coverage*

View File

@ -1,11 +1,15 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.11.2
rev: 24e02b24b8ab2b7c76225602d13fa60e12d114e6 # frozen: v0.11.9
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 14ac15b122e538e407d036ff45e3895b7cf4a2bf # frozen: 0.7.3
hooks:
- id: uv-lock
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0
hooks:
- id: check-merge-conflict
- id: debug-statements

View File

@ -1,14 +1,10 @@
version: 2
build:
os: ubuntu-22.04
os: ubuntu-24.04
tools:
python: '3.12'
python:
install:
- requirements: requirements/docs.txt
- method: pip
path: .
sphinx:
configuration: docs/conf.py
builder: dirhtml
fail_on_warning: true
python: '3.13'
commands:
- asdf plugin add uv
- asdf install uv latest
- asdf global uv latest
- uv run --group docs sphinx-build -W -b dirhtml docs $READTHEDOCS_OUTPUT/html

View File

@ -1,11 +1,13 @@
Version 3.1.1
-------------
Unreleased
Released 2025-05-13
- Fix type hint for `cli_runner.invoke`. :issue:`5645`
- Fix signing key selection order when key rotation is enabled via
``SECRET_KEY_FALLBACKS``. :ghsa:`4grg-w6v8-c28g`
- 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`
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`

View File

@ -127,13 +127,16 @@ The following configuration values are used internally by Flask:
.. py:data:: SECRET_KEY_FALLBACKS
A list of old secret keys that can still be used for unsigning, most recent
first. This allows a project to implement key rotation without invalidating
active sessions or other recently-signed secrets.
A list of old secret keys that can still be used for unsigning. This allows
a project to implement key rotation without invalidating active sessions or
other recently-signed secrets.
Keys should be removed after an appropriate period of time, as checking each
additional key adds some overhead.
Order should not matter, but the default implementation will test the last
key in the list first, so it might make sense to order oldest to newest.
Flask's built-in secure cookie session supports this. Extensions that use
:data:`SECRET_KEY` may not support this yet.

View File

@ -1,7 +1,7 @@
Contributing
============
See the Pallets `detailed contributing documentation <_contrib>`_ for many ways
See the Pallets `detailed contributing documentation <contrib_>`_ for many ways
to contribute, including reporting issues, requesting features, asking or
answering questions, and making PRs.

View File

@ -77,7 +77,7 @@ following example shows that process id 6847 is using port 5000.
macOS Monterey and later automatically starts a service that uses port
5000. You can choose to disable this service instead of using a different port by
searching for "AirPlay Receiver" in System Preferences and toggling it off.
searching for "AirPlay Receiver" in System Settings and toggling it off.
Deferred Errors on Reload

View File

@ -1,16 +1,16 @@
[project]
name = "Flask"
version = "3.1.1.dev"
version = "3.1.1"
description = "A simple framework for building complex web applications."
readme = "README.md"
license = {file = "LICENSE.txt"}
license = "BSD-3-Clause"
license-files = ["LICENSE.txt"]
maintainers = [{name = "Pallets", email = "contact@palletsprojects.com"}]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Framework :: Flask",
"Intended Audience :: Developers",
"License :: OSI Approved :: BSD License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
@ -21,25 +21,65 @@ classifiers = [
]
requires-python = ">=3.9"
dependencies = [
"Werkzeug>=3.1",
"Jinja2>=3.1.2",
"itsdangerous>=2.2",
"blinker>=1.9.0",
"click>=8.1.3",
"blinker>=1.9",
"importlib-metadata>=3.6; python_version < '3.10'",
"importlib-metadata>=3.6.0; python_version < '3.10'",
"itsdangerous>=2.2.0",
"jinja2>=3.1.2",
"markupsafe>=2.1.1",
"werkzeug>=3.1.0",
]
[project.optional-dependencies]
async = ["asgiref>=3.2"]
dotenv = ["python-dotenv"]
[dependency-groups]
dev = [
"ruff",
"tox",
"tox-uv",
]
docs = [
"pallets-sphinx-themes",
"sphinx",
"sphinx-tabs",
"sphinxcontrib-log-cabinet",
]
docs-auto = [
"sphinx-autobuild",
]
gha-update = [
"gha-update ; python_full_version >= '3.12'",
]
pre-commit = [
"pre-commit",
"pre-commit-uv",
]
tests = [
"asgiref",
"greenlet ; python_version < '3.11'",
"pytest",
"python-dotenv",
]
typing = [
"asgiref",
"cryptography",
"mypy",
"pyright",
"pytest",
"python-dotenv",
"types-contextvars",
"types-dataclasses",
]
[project.urls]
Donate = "https://palletsprojects.com/donate"
Documentation = "https://flask.palletsprojects.com/"
Changes = "https://flask.palletsprojects.com/changes/"
Changes = "https://flask.palletsprojects.com/page/changes/"
Source = "https://github.com/pallets/flask/"
Chat = "https://discord.gg/pallets"
[project.optional-dependencies]
async = ["asgiref>=3.2"]
dotenv = ["python-dotenv"]
[project.scripts]
flask = "flask.cli:main"
@ -54,16 +94,17 @@ name = "flask"
include = [
"docs/",
"examples/",
"requirements/",
"tests/",
"CHANGES.rst",
"CONTRIBUTING.rst",
"tox.ini",
"uv.lock"
]
exclude = [
"docs/_build/",
]
[tool.uv]
default-groups = ["dev", "pre-commit", "tests", "typing"]
[tool.pytest.ini_options]
testpaths = ["tests"]
filterwarnings = [
@ -77,9 +118,16 @@ source = ["flask", "tests"]
[tool.coverage.paths]
source = ["src", "*/site-packages"]
[tool.coverage.report]
exclude_also = [
"if t.TYPE_CHECKING",
"raise NotImplementedError",
": \\.{3}",
]
[tool.mypy]
python_version = "3.9"
files = ["src/flask", "tests/type_check"]
files = ["src", "tests/type_check"]
show_error_codes = true
pretty = true
strict = true
@ -95,7 +143,7 @@ ignore_missing_imports = true
[tool.pyright]
pythonVersion = "3.9"
include = ["src/flask", "tests/type_check"]
include = ["src", "tests/type_check"]
typeCheckingMode = "basic"
[tool.ruff]
@ -122,3 +170,111 @@ order-by-type = false
tag-only = [
"slsa-framework/slsa-github-generator",
]
[tool.tox]
env_list = [
"py3.13", "py3.12", "py3.11", "py3.10", "py3.9",
"pypy3.11",
"tests-min", "tests-dev",
"style",
"typing",
"docs",
]
[tool.tox.env_run_base]
description = "pytest on latest dependency versions"
runner = "uv-venv-lock-runner"
package = "wheel"
wheel_build_env = ".pkg"
constrain_package_deps = true
use_frozen_constraints = true
dependency_groups = ["tests"]
env_tmp_dir = "{toxworkdir}/tmp/{envname}"
commands = [[
"pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}",
{replace = "posargs", default = [], extend = true},
]]
[tool.tox.env.tests-min]
description = "pytest on minimum dependency versions"
base_python = ["3.13"]
commands = [
[
"uv", "pip", "install",
"blinker==1.9.0",
"click==8.1.3",
"itsdangerous==2.2.0",
"jinja2==3.1.2",
"markupsafe==2.1.1",
"werkzeug==3.1.0",
],
[
"pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}",
{replace = "posargs", default = [], extend = true},
],
]
[tool.tox.env.tests-dev]
description = "pytest on development dependency versions (git main branch)"
base_python = ["3.10"]
commands = [
[
"uv", "pip", "install",
"https://github.com/pallets-eco/blinker/archive/refs/heads/main.tar.gz",
"https://github.com/pallets/click/archive/refs/heads/main.tar.gz",
"https://github.com/pallets/itsdangerous/archive/refs/heads/main.tar.gz",
"https://github.com/pallets/jinja/archive/refs/heads/main.tar.gz",
"https://github.com/pallets/markupsafe/archive/refs/heads/main.tar.gz",
"https://github.com/pallets/werkzeug/archive/refs/heads/main.tar.gz",
],
[
"pytest", "-v", "--tb=short", "--basetemp={env_tmp_dir}",
{replace = "posargs", default = [], extend = true},
],
]
[tool.tox.env.style]
description = "run all pre-commit hooks on all files"
dependency_groups = ["pre-commit"]
skip_install = true
commands = [["pre-commit", "run", "--all-files"]]
[tool.tox.env.typing]
description = "run static type checkers"
dependency_groups = ["typing"]
commands = [
["mypy"],
["pyright"],
]
[tool.tox.env.docs]
description = "build docs"
dependency_groups = ["docs"]
commands = [["sphinx-build", "-E", "-W", "-b", "dirhtml", "docs", "docs/_build/dirhtml"]]
[tool.tox.env.docs-auto]
description = "continuously rebuild docs and start a local server"
dependency_groups = ["docs", "docs-auto"]
commands = [["sphinx-autobuild", "-W", "-b", "dirhtml", "--watch", "src", "docs", "docs/_build/dirhtml"]]
[tool.tox.env.update-actions]
description = "update GitHub Actions pins"
labels = ["update"]
dependency_groups = ["gha-update"]
skip_install = true
commands = [["gha-update"]]
[tool.tox.env.update-pre_commit]
description = "update pre-commit pins"
labels = ["update"]
dependency_groups = ["pre-commit"]
skip_install = true
commands = [["pre-commit", "autoupdate", "--freeze", "-j4"]]
[tool.tox.env.update-requirements]
description = "update uv lock"
labels = ["update"]
dependency_groups = []
no_default_groups = true
skip_install = true
commands = [["uv", "lock", {replace = "posargs", default = ["-U"], extend = true}]]

View File

@ -1 +0,0 @@
build

View File

@ -1,12 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile build.in
#
build==1.2.2.post1
# via -r build.in
packaging==24.2
# via build
pyproject-hooks==1.2.0
# via build

View File

@ -1,5 +0,0 @@
-r docs.txt
-r tests.txt
-r typing.txt
pre-commit
tox

View File

@ -1,202 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile dev.in
#
alabaster==1.0.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
asgiref==3.8.1
# via
# -r /Users/david/Projects/flask/requirements/tests.txt
# -r /Users/david/Projects/flask/requirements/typing.txt
babel==2.17.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
cachetools==5.5.2
# via tox
certifi==2025.1.31
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# requests
cffi==1.17.1
# via
# -r /Users/david/Projects/flask/requirements/typing.txt
# cryptography
cfgv==3.4.0
# via pre-commit
chardet==5.2.0
# via tox
charset-normalizer==3.4.1
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# requests
colorama==0.4.6
# via tox
cryptography==44.0.2
# via -r /Users/david/Projects/flask/requirements/typing.txt
distlib==0.3.9
# via virtualenv
docutils==0.21.2
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
# sphinx-tabs
filelock==3.18.0
# via
# tox
# virtualenv
identify==2.6.9
# via pre-commit
idna==3.10
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# requests
imagesize==1.4.1
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
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.6
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
markupsafe==3.0.2
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# jinja2
mypy==1.15.0
# via -r /Users/david/Projects/flask/requirements/typing.txt
mypy-extensions==1.0.0
# via
# -r /Users/david/Projects/flask/requirements/typing.txt
# mypy
nodeenv==1.9.1
# via
# -r /Users/david/Projects/flask/requirements/typing.txt
# pre-commit
# pyright
packaging==24.2
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# -r /Users/david/Projects/flask/requirements/tests.txt
# -r /Users/david/Projects/flask/requirements/typing.txt
# pallets-sphinx-themes
# pyproject-api
# pytest
# sphinx
# tox
pallets-sphinx-themes==2.3.0
# via -r /Users/david/Projects/flask/requirements/docs.txt
platformdirs==4.3.7
# via
# tox
# virtualenv
pluggy==1.5.0
# via
# -r /Users/david/Projects/flask/requirements/tests.txt
# -r /Users/david/Projects/flask/requirements/typing.txt
# pytest
# tox
pre-commit==4.2.0
# via -r dev.in
pycparser==2.22
# via
# -r /Users/david/Projects/flask/requirements/typing.txt
# cffi
pygments==2.19.1
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
# sphinx-tabs
pyproject-api==1.9.0
# via tox
pyright==1.1.398
# via -r /Users/david/Projects/flask/requirements/typing.txt
pytest==8.3.5
# via
# -r /Users/david/Projects/flask/requirements/tests.txt
# -r /Users/david/Projects/flask/requirements/typing.txt
python-dotenv==1.1.0
# via
# -r /Users/david/Projects/flask/requirements/tests.txt
# -r /Users/david/Projects/flask/requirements/typing.txt
pyyaml==6.0.2
# via pre-commit
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.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.1.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# pallets-sphinx-themes
sphinx-tabs==3.4.7
# via -r /Users/david/Projects/flask/requirements/docs.txt
sphinxcontrib-applehelp==2.0.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
sphinxcontrib-devhelp==2.0.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
sphinxcontrib-htmlhelp==2.1.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
sphinxcontrib-jsmath==1.0.1
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
sphinxcontrib-log-cabinet==1.0.1
# via -r /Users/david/Projects/flask/requirements/docs.txt
sphinxcontrib-qthelp==2.0.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
sphinxcontrib-serializinghtml==2.0.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# sphinx
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.13.0
# via
# -r /Users/david/Projects/flask/requirements/typing.txt
# mypy
# pyright
urllib3==2.3.0
# via
# -r /Users/david/Projects/flask/requirements/docs.txt
# requests
virtualenv==20.29.3
# via
# pre-commit
# tox

View File

@ -1,4 +0,0 @@
pallets-sphinx-themes
sphinx
sphinxcontrib-log-cabinet
sphinx-tabs

View File

@ -1,69 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile docs.in
#
alabaster==1.0.0
# via sphinx
babel==2.17.0
# via sphinx
certifi==2025.1.31
# via requests
charset-normalizer==3.4.1
# via requests
docutils==0.21.2
# via
# sphinx
# sphinx-tabs
idna==3.10
# via requests
imagesize==1.4.1
# via sphinx
jinja2==3.1.6
# via sphinx
markupsafe==3.0.2
# via jinja2
packaging==24.2
# via
# pallets-sphinx-themes
# sphinx
pallets-sphinx-themes==2.3.0
# via -r docs.in
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.2.3
# via
# -r docs.in
# pallets-sphinx-themes
# sphinx-notfound-page
# sphinx-tabs
# sphinxcontrib-log-cabinet
sphinx-notfound-page==1.1.0
# via pallets-sphinx-themes
sphinx-tabs==3.4.7
# via -r docs.in
sphinxcontrib-applehelp==2.0.0
# via sphinx
sphinxcontrib-devhelp==2.0.0
# via sphinx
sphinxcontrib-htmlhelp==2.1.0
# via sphinx
sphinxcontrib-jsmath==1.0.1
# via sphinx
sphinxcontrib-log-cabinet==1.0.1
# via -r docs.in
sphinxcontrib-qthelp==2.0.0
# via sphinx
sphinxcontrib-serializinghtml==2.0.0
# via sphinx
urllib3==2.3.0
# via requests

View File

@ -1,6 +0,0 @@
https://github.com/pallets/werkzeug/archive/refs/heads/main.tar.gz
https://github.com/pallets/jinja/archive/refs/heads/main.tar.gz
https://github.com/pallets/markupsafe/archive/refs/heads/main.tar.gz
https://github.com/pallets/itsdangerous/archive/refs/heads/main.tar.gz
https://github.com/pallets/click/archive/refs/heads/main.tar.gz
https://github.com/pallets-eco/blinker/archive/refs/heads/main.tar.gz

View File

@ -1,6 +0,0 @@
werkzeug==3.1.0
jinja2==3.1.2
markupsafe==2.1.1
itsdangerous==2.2.0
click==8.1.3
blinker==1.9.0

View File

@ -1,21 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile tests-min.in
#
blinker==1.9.0
# via -r tests-min.in
click==8.1.3
# via -r tests-min.in
itsdangerous==2.2.0
# via -r tests-min.in
jinja2==3.1.2
# via -r tests-min.in
markupsafe==2.1.1
# via
# -r tests-min.in
# jinja2
# werkzeug
werkzeug==3.1.0
# via -r tests-min.in

View File

@ -1,4 +0,0 @@
pytest
asgiref
greenlet ; python_version < "3.11"
python-dotenv

View File

@ -1,18 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile tests.in
#
asgiref==3.8.1
# via -r tests.in
iniconfig==2.1.0
# via pytest
packaging==24.2
# via pytest
pluggy==1.5.0
# via pytest
pytest==8.3.5
# via -r tests.in
python-dotenv==1.1.0
# via -r tests.in

View File

@ -1,8 +0,0 @@
mypy
pyright
pytest
types-contextvars
types-dataclasses
asgiref
cryptography
python-dotenv

View File

@ -1,40 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile typing.in
#
asgiref==3.8.1
# via -r typing.in
cffi==1.17.1
# via cryptography
cryptography==44.0.2
# via -r typing.in
iniconfig==2.1.0
# via pytest
mypy==1.15.0
# via -r typing.in
mypy-extensions==1.0.0
# via mypy
nodeenv==1.9.1
# via pyright
packaging==24.2
# via pytest
pluggy==1.5.0
# via pytest
pycparser==2.22
# via cffi
pyright==1.1.398
# via -r typing.in
pytest==8.3.5
# via -r typing.in
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.13.0
# via
# mypy
# pyright

View File

@ -1222,7 +1222,7 @@ class Flask(App):
# waiting to do it manually, so that the class can handle any
# special logic
rv = self.response_class(
rv,
rv, # pyright: ignore
status=status,
headers=headers, # type: ignore[arg-type]
)

View File

@ -318,11 +318,12 @@ class SecureCookieSessionInterface(SessionInterface):
if not app.secret_key:
return None
keys: list[str | bytes] = [app.secret_key]
keys: list[str | bytes] = []
if fallbacks := app.config["SECRET_KEY_FALLBACKS"]:
keys.extend(fallbacks)
keys.append(app.secret_key) # itsdangerous expects current key at top
return URLSafeTimedSerializer(
keys, # type: ignore[arg-type]
salt=self.salt,

View File

@ -381,14 +381,21 @@ def test_session_secret_key_fallbacks(app, client) -> None:
def get_session() -> dict[str, t.Any]:
return dict(flask.session)
# Set session with initial secret key
# Set session with initial secret key, and two valid expiring keys
app.secret_key, app.config["SECRET_KEY_FALLBACKS"] = (
"0 key",
["-1 key", "-2 key"],
)
client.post()
assert client.get().json == {"a": 1}
# Change secret key, session can't be loaded and appears empty
app.secret_key = "new test key"
app.secret_key = "? key"
assert client.get().json == {}
# Add initial secret key as fallback, session can be loaded
app.config["SECRET_KEY_FALLBACKS"] = ["test key"]
# Rotate the valid keys, session can be loaded
app.secret_key, app.config["SECRET_KEY_FALLBACKS"] = (
"+1 key",
["0 key", "-1 key"],
)
assert client.get().json == {"a": 1}

62
tox.ini
View File

@ -1,62 +0,0 @@
[tox]
envlist =
py3{13,12,11,10,9}
pypy310
py313-min
py39-dev
style
typing
docs
skip_missing_interpreters = true
[testenv]
package = wheel
wheel_build_env = .pkg
envtmpdir = {toxworkdir}/tmp/{envname}
constrain_package_deps = true
use_frozen_constraints = true
deps =
-r requirements/tests.txt
min: -r requirements/tests-min.txt
dev: -r requirements/tests-dev.txt
commands = pytest -v --tb=short --basetemp={envtmpdir} {posargs}
[testenv:style]
deps = pre-commit
skip_install = true
commands = pre-commit run --all-files
[testenv:typing]
deps = -r requirements/typing.txt
commands =
mypy
pyright
[testenv:docs]
deps = -r requirements/docs.txt
commands = sphinx-build -E -W -b dirhtml docs docs/_build/dirhtml
[testenv:update-actions]
labels = update
deps = gha-update
skip_install = true
commands = gha-update
[testenv:update-pre_commit]
labels = update
deps = pre-commit
skip_install = true
commands = pre-commit autoupdate -j4
[testenv:update-requirements]
labels = update
deps = pip-tools
skip_install = true
change_dir = requirements
commands =
pip-compile build.in -q {posargs:-U}
pip-compile docs.in -q {posargs:-U}
pip-compile tests.in -q {posargs:-U}
pip-compile tests-min.in -q
pip-compile typing.in -q {posargs:-U}
pip-compile dev.in -q {posargs:-U}

1641
uv.lock Normal file

File diff suppressed because it is too large Load Diff