From 7320e311a0a3f190351173f8be90cab31dadbf73 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 7 Apr 2024 11:22:02 -0700 Subject: [PATCH 1/5] start version 3.0.3 --- CHANGES.rst | 6 ++++++ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 37c54f97..3c04b2f4 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,3 +1,9 @@ +Version 3.0.3 +------------- + +Unreleased + + Version 3.0.2 ------------- diff --git a/pyproject.toml b/pyproject.toml index d2739c2e..bf14d157 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "Flask" -version = "3.0.2" +version = "3.0.3" description = "A simple framework for building complex web applications." readme = "README.md" license = {file = "LICENSE.txt"} From db461112c70d5f2bf93c7a6ac27eeb665c232dd0 Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 7 Apr 2024 11:30:30 -0700 Subject: [PATCH 2/5] access sha1 lazily --- CHANGES.rst | 4 ++++ src/flask/sessions.py | 10 +++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 3c04b2f4..0908a02d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,6 +3,10 @@ Version 3.0.3 Unreleased +- The default ``hashlib.sha1`` may not be available in FIPS builds. Don't + access it at import time so the developer has time to change the default. + :issue:`5448` + Version 3.0.2 ------------- diff --git a/src/flask/sessions.py b/src/flask/sessions.py index bb753eb8..ee19ad63 100644 --- a/src/flask/sessions.py +++ b/src/flask/sessions.py @@ -277,6 +277,14 @@ class SessionInterface: session_json_serializer = TaggedJSONSerializer() +def _lazy_sha1(string: bytes = b"") -> t.Any: + """Don't access ``hashlib.sha1`` until runtime. FIPS builds may not include + SHA-1, in which case the import and use as a default would fail before the + developer can configure something else. + """ + return hashlib.sha1(string) + + class SecureCookieSessionInterface(SessionInterface): """The default session interface that stores sessions in signed cookies through the :mod:`itsdangerous` module. @@ -286,7 +294,7 @@ class SecureCookieSessionInterface(SessionInterface): #: signing of cookie based sessions. salt = "cookie-session" #: the hash function to use for the signature. The default is sha1 - digest_method = staticmethod(hashlib.sha1) + digest_method = staticmethod(_lazy_sha1) #: the name of the itsdangerous supported key derivation. The default #: is hmac. key_derivation = "hmac" From adb7dd99c295a28726c8d818fba54c7b3f958ecc Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 7 Apr 2024 12:03:19 -0700 Subject: [PATCH 3/5] don't access app.logger when configuring app.logger --- docs/logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/logging.rst b/docs/logging.rst index 0912b7a1..39588242 100644 --- a/docs/logging.rst +++ b/docs/logging.rst @@ -159,7 +159,7 @@ Depending on your project, it may be more useful to configure each logger you care about separately, instead of configuring only the root logger. :: for logger in ( - app.logger, + logging.getLogger(app.name), logging.getLogger('sqlalchemy'), logging.getLogger('other_package'), ): From 5fdce4c331ac530280cc941179d364a07f4a1088 Mon Sep 17 00:00:00 2001 From: pgjones Date: Sun, 1 Oct 2023 16:37:05 +0100 Subject: [PATCH 4/5] Don't set the cli attribute in the sansio scaffold It is (currently) Flask specific and hence cannot be shared in the sansio shared code. --- CHANGES.rst | 2 ++ src/flask/app.py | 10 ++++++++++ src/flask/blueprints.py | 38 ++++++++++++++++++++++++++++++++++++ src/flask/sansio/app.py | 4 ---- src/flask/sansio/scaffold.py | 12 ++++-------- 5 files changed, 54 insertions(+), 12 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0908a02d..9a5f7498 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,8 @@ Unreleased - The default ``hashlib.sha1`` may not be available in FIPS builds. Don't access it at import time so the developer has time to change the default. :issue:`5448` +- Don't initialize the ``cli`` attribute in the sansio scaffold, but rather in + the ``Flask`` concrete class. :pr:`5270` Version 3.0.2 diff --git a/src/flask/app.py b/src/flask/app.py index 12ac50d4..7622b5e8 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -241,6 +241,16 @@ class Flask(App): root_path=root_path, ) + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = cli.AppGroup() + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + # Add a static route using the provided static_url_path, static_host, # and static_folder if there is a configured static_folder. # Note we do this without checking if static_folder exists. diff --git a/src/flask/blueprints.py b/src/flask/blueprints.py index 52859b85..aa9eacf2 100644 --- a/src/flask/blueprints.py +++ b/src/flask/blueprints.py @@ -4,16 +4,54 @@ import os import typing as t from datetime import timedelta +from .cli import AppGroup from .globals import current_app from .helpers import send_from_directory from .sansio.blueprints import Blueprint as SansioBlueprint from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa +from .sansio.scaffold import _sentinel if t.TYPE_CHECKING: # pragma: no cover from .wrappers import Response class Blueprint(SansioBlueprint): + def __init__( + self, + name: str, + import_name: str, + static_folder: str | os.PathLike[str] | None = None, + static_url_path: str | None = None, + template_folder: str | os.PathLike[str] | None = None, + url_prefix: str | None = None, + subdomain: str | None = None, + url_defaults: dict[str, t.Any] | None = None, + root_path: str | None = None, + cli_group: str | None = _sentinel, # type: ignore + ) -> None: + super().__init__( + name, + import_name, + static_folder, + static_url_path, + template_folder, + url_prefix, + subdomain, + url_defaults, + root_path, + cli_group, + ) + + #: The Click command group for registering CLI commands for this + #: object. The commands are available from the ``flask`` command + #: once the application has been discovered and blueprints have + #: been registered. + self.cli = AppGroup() + + # Set the name of the Click group in case someone wants to add + # the app's commands to another CLI tool. + self.cli.name = self.name + def get_send_file_max_age(self, filename: str | None) -> int | None: """Used by :func:`send_file` to determine the ``max_age`` cache value for a given file path if it wasn't passed. diff --git a/src/flask/sansio/app.py b/src/flask/sansio/app.py index 21a79ba4..01fd5dbf 100644 --- a/src/flask/sansio/app.py +++ b/src/flask/sansio/app.py @@ -410,10 +410,6 @@ class App(Scaffold): # request. self._got_first_request = False - # Set the name of the Click group in case someone wants to add - # the app's commands to another CLI tool. - self.cli.name = self.name - def _check_setup_finished(self, f_name: str) -> None: if self._got_first_request: raise AssertionError( diff --git a/src/flask/sansio/scaffold.py b/src/flask/sansio/scaffold.py index 53557008..69e33a09 100644 --- a/src/flask/sansio/scaffold.py +++ b/src/flask/sansio/scaffold.py @@ -8,7 +8,6 @@ import typing as t from collections import defaultdict from functools import update_wrapper -import click from jinja2 import BaseLoader from jinja2 import FileSystemLoader from werkzeug.exceptions import default_exceptions @@ -16,10 +15,12 @@ from werkzeug.exceptions import HTTPException from werkzeug.utils import cached_property from .. import typing as ft -from ..cli import AppGroup from ..helpers import get_root_path from ..templating import _default_template_ctx_processor +if t.TYPE_CHECKING: # pragma: no cover + from click import Group + # a singleton sentinel value for parameter defaults _sentinel = object() @@ -66,6 +67,7 @@ class Scaffold: .. versionadded:: 2.0 """ + cli: Group name: str _static_folder: str | None = None _static_url_path: str | None = None @@ -97,12 +99,6 @@ class Scaffold: #: up resources contained in the package. self.root_path = root_path - #: The Click command group for registering CLI commands for this - #: object. The commands are available from the ``flask`` command - #: once the application has been discovered and blueprints have - #: been registered. - self.cli: click.Group = AppGroup() - #: A dictionary mapping endpoint names to view functions. #: #: To register a view function, use the :meth:`route` decorator. From c12a5d874c5a014495eb2db8a73f40037bc813ac Mon Sep 17 00:00:00 2001 From: David Lord Date: Sun, 7 Apr 2024 12:17:41 -0700 Subject: [PATCH 5/5] release version 3.0.3 --- CHANGES.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9a5f7498..082c7065 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,7 +1,7 @@ Version 3.0.3 ------------- -Unreleased +Released 2024-04-07 - The default ``hashlib.sha1`` may not be available in FIPS builds. Don't access it at import time so the developer has time to change the default.