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.
This commit is contained in:
pgjones 2023-10-01 16:37:05 +01:00 committed by David Lord
parent adb7dd99c2
commit 5fdce4c331
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
5 changed files with 54 additions and 12 deletions

View file

@ -6,6 +6,8 @@ Unreleased
- The default ``hashlib.sha1`` may not be available in FIPS builds. Don't - 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. access it at import time so the developer has time to change the default.
:issue:`5448` :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 Version 3.0.2

View file

@ -241,6 +241,16 @@ class Flask(App):
root_path=root_path, 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, # Add a static route using the provided static_url_path, static_host,
# and static_folder if there is a configured static_folder. # and static_folder if there is a configured static_folder.
# Note we do this without checking if static_folder exists. # Note we do this without checking if static_folder exists.

View file

@ -4,16 +4,54 @@ import os
import typing as t import typing as t
from datetime import timedelta from datetime import timedelta
from .cli import AppGroup
from .globals import current_app from .globals import current_app
from .helpers import send_from_directory from .helpers import send_from_directory
from .sansio.blueprints import Blueprint as SansioBlueprint from .sansio.blueprints import Blueprint as SansioBlueprint
from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa from .sansio.blueprints import BlueprintSetupState as BlueprintSetupState # noqa
from .sansio.scaffold import _sentinel
if t.TYPE_CHECKING: # pragma: no cover if t.TYPE_CHECKING: # pragma: no cover
from .wrappers import Response from .wrappers import Response
class Blueprint(SansioBlueprint): 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: def get_send_file_max_age(self, filename: str | None) -> int | None:
"""Used by :func:`send_file` to determine the ``max_age`` cache """Used by :func:`send_file` to determine the ``max_age`` cache
value for a given file path if it wasn't passed. value for a given file path if it wasn't passed.

View file

@ -410,10 +410,6 @@ class App(Scaffold):
# request. # request.
self._got_first_request = False 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: def _check_setup_finished(self, f_name: str) -> None:
if self._got_first_request: if self._got_first_request:
raise AssertionError( raise AssertionError(

View file

@ -8,7 +8,6 @@ import typing as t
from collections import defaultdict from collections import defaultdict
from functools import update_wrapper from functools import update_wrapper
import click
from jinja2 import BaseLoader from jinja2 import BaseLoader
from jinja2 import FileSystemLoader from jinja2 import FileSystemLoader
from werkzeug.exceptions import default_exceptions from werkzeug.exceptions import default_exceptions
@ -16,10 +15,12 @@ from werkzeug.exceptions import HTTPException
from werkzeug.utils import cached_property from werkzeug.utils import cached_property
from .. import typing as ft from .. import typing as ft
from ..cli import AppGroup
from ..helpers import get_root_path from ..helpers import get_root_path
from ..templating import _default_template_ctx_processor 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 # a singleton sentinel value for parameter defaults
_sentinel = object() _sentinel = object()
@ -66,6 +67,7 @@ class Scaffold:
.. versionadded:: 2.0 .. versionadded:: 2.0
""" """
cli: Group
name: str name: str
_static_folder: str | None = None _static_folder: str | None = None
_static_url_path: str | None = None _static_url_path: str | None = None
@ -97,12 +99,6 @@ class Scaffold:
#: up resources contained in the package. #: up resources contained in the package.
self.root_path = root_path 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. #: A dictionary mapping endpoint names to view functions.
#: #:
#: To register a view function, use the :meth:`route` decorator. #: To register a view function, use the :meth:`route` decorator.