From 9252be9c9ebe46dd6415b24999a869ed87eace57 Mon Sep 17 00:00:00 2001 From: lecovi Date: Mon, 2 May 2022 17:28:23 -0300 Subject: [PATCH 1/6] docs: new configuration format for celery --- docs/patterns/celery.rst | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/patterns/celery.rst b/docs/patterns/celery.rst index 38a9a025..228a04a8 100644 --- a/docs/patterns/celery.rst +++ b/docs/patterns/celery.rst @@ -34,17 +34,15 @@ Celery without any reconfiguration with Flask, it becomes a bit nicer by subclassing tasks and adding support for Flask's application contexts and hooking it up with the Flask configuration. -This is all that is necessary to properly integrate Celery with Flask:: +This is all that is necessary to integrate Celery with Flask: + +.. code-block:: python from celery import Celery def make_celery(app): - celery = Celery( - app.import_name, - backend=app.config['CELERY_RESULT_BACKEND'], - broker=app.config['CELERY_BROKER_URL'] - ) - celery.conf.update(app.config) + celery = Celery(app.import_name) + celery.conf.update(app.config["CELERY_CONFIG"]) class ContextTask(celery.Task): def __call__(self, *args, **kwargs): @@ -59,6 +57,12 @@ from the application config, updates the rest of the Celery config from the Flask config and then creates a subclass of the task that wraps the task execution in an application context. +.. note:: + Celery 5.x deprecated uppercase configuration keys, and 6.x will + remove them. See their official `migration guide`_. + +.. _migration guide: https://docs.celeryproject.org/en/stable/userguide/configuration.html#conf-old-settings-map. + An example task --------------- @@ -69,10 +73,10 @@ application using the factory from above, and then use it to define the task. :: from flask import Flask flask_app = Flask(__name__) - flask_app.config.update( - CELERY_BROKER_URL='redis://localhost:6379', - CELERY_RESULT_BACKEND='redis://localhost:6379' - ) + flask_app.config.update(CELERY_CONFIG={ + 'broker_url': 'redis://localhost:6379', + 'result_backend': 'redis://localhost:6379', + }) celery = make_celery(flask_app) @celery.task() From c45c81938a1715eb4bdf9eaf6ac9d75becb8c191 Mon Sep 17 00:00:00 2001 From: Nathan Brown Date: Thu, 12 May 2022 19:57:50 -0400 Subject: [PATCH 2/6] Add link to additional packaging info --- docs/tutorial/install.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/tutorial/install.rst b/docs/tutorial/install.rst index 3d7d7c60..9e808f14 100644 --- a/docs/tutorial/install.rst +++ b/docs/tutorial/install.rst @@ -67,10 +67,12 @@ This tells Python to copy everything in the ``static`` and ``templates`` directories, and the ``schema.sql`` file, but to exclude all bytecode files. -See the `official packaging guide`_ for another explanation of the files +See the official `Packaging tutorial `_ and +`detailed guide `_ for more explanation of the files and options used. -.. _official packaging guide: https://packaging.python.org/tutorials/packaging-projects/ +.. _packaging tutorial: https://packaging.python.org/tutorials/packaging-projects/ +.. _packaging guide: https://packaging.python.org/guides/distributing-packages-using-setuptools/ Install the Project From a4f63e0390e4f9aba543514d16479ce6f40e46be Mon Sep 17 00:00:00 2001 From: David Lord Date: Mon, 23 May 2022 10:54:02 -0700 Subject: [PATCH 3/6] start version 2.1.3 --- CHANGES.rst | 9 +++++++++ src/flask/__init__.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0e4bebfa..12d89870 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,5 +1,14 @@ .. currentmodule:: flask +Version 2.1.3 +------------- + +Unreleased + +- Inline some optional imports that are only used for certain CLI + commands. :pr:`4606` + + Version 2.1.2 ------------- diff --git a/src/flask/__init__.py b/src/flask/__init__.py index f684f57a..380de0f4 100644 --- a/src/flask/__init__.py +++ b/src/flask/__init__.py @@ -42,4 +42,4 @@ from .signals import template_rendered as template_rendered from .templating import render_template as render_template from .templating import render_template_string as render_template_string -__version__ = "2.1.2" +__version__ = "2.1.3.dev0" From 8cb950671f39c64707b6aaebfc60d7a8f1157da5 Mon Sep 17 00:00:00 2001 From: Justin Bull Date: Thu, 19 May 2022 13:34:46 -0400 Subject: [PATCH 4/6] use bound typevar to accept Flask and Werkzeug Response classes --- CHANGES.rst | 1 + src/flask/typing.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 12d89870..a181badc 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -7,6 +7,7 @@ Unreleased - Inline some optional imports that are only used for certain CLI commands. :pr:`4606` +- Relax type annotation for ``after_request`` functions. :issue:`4600` Version 2.1.2 diff --git a/src/flask/typing.py b/src/flask/typing.py index a839a7e4..ec7c7969 100644 --- a/src/flask/typing.py +++ b/src/flask/typing.py @@ -4,7 +4,7 @@ import typing as t if t.TYPE_CHECKING: from _typeshed.wsgi import WSGIApplication # noqa: F401 from werkzeug.datastructures import Headers # noqa: F401 - from werkzeug.wrappers.response import Response # noqa: F401 + from werkzeug.wrappers import Response # noqa: F401 # The possible types that are directly convertible or are a Response object. ResponseValue = t.Union[ @@ -35,8 +35,13 @@ ResponseReturnValue = t.Union[ "WSGIApplication", ] +# Allow any subclass of werkzeug.Response, such as the one from Flask, +# as a callback argument. Using werkzeug.Response directly makes a +# callback annotated with flask.Response fail type checking. +ResponseClass = t.TypeVar("ResponseClass", bound="Response") + AppOrBlueprintKey = t.Optional[str] # The App key is None, whereas blueprints are named -AfterRequestCallable = t.Callable[["Response"], "Response"] +AfterRequestCallable = t.Callable[[ResponseClass], ResponseClass] BeforeFirstRequestCallable = t.Callable[[], None] BeforeRequestCallable = t.Callable[[], t.Optional[ResponseReturnValue]] TeardownCallable = t.Callable[[t.Optional[BaseException]], None] From 61f62e6005f72c44a90026e2589b6bc5234f2f24 Mon Sep 17 00:00:00 2001 From: David Lord Date: Mon, 23 May 2022 13:15:26 -0700 Subject: [PATCH 5/6] access flask types through namespace alias --- src/flask/app.py | 56 +++++++++++++++++++---------------------- src/flask/blueprints.py | 54 +++++++++++++++++---------------------- src/flask/ctx.py | 6 ++--- src/flask/scaffold.py | 49 ++++++++++++++++-------------------- src/flask/views.py | 8 +++--- 5 files changed, 77 insertions(+), 96 deletions(-) diff --git a/src/flask/app.py b/src/flask/app.py index 348bc7f7..34ea5b29 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -26,6 +26,7 @@ from werkzeug.wrappers import Response as BaseResponse from . import cli from . import json +from . import typing as ft from .config import Config from .config import ConfigAttribute from .ctx import _AppCtxGlobals @@ -58,12 +59,6 @@ from .signals import request_started from .signals import request_tearing_down from .templating import DispatchingJinjaLoader from .templating import Environment -from .typing import BeforeFirstRequestCallable -from .typing import ResponseReturnValue -from .typing import TeardownCallable -from .typing import TemplateFilterCallable -from .typing import TemplateGlobalCallable -from .typing import TemplateTestCallable from .wrappers import Request from .wrappers import Response @@ -72,7 +67,6 @@ if t.TYPE_CHECKING: from .blueprints import Blueprint from .testing import FlaskClient from .testing import FlaskCliRunner - from .typing import ErrorHandlerCallable if sys.version_info >= (3, 8): iscoroutinefunction = inspect.iscoroutinefunction @@ -436,7 +430,7 @@ class Flask(Scaffold): #: :meth:`before_first_request` decorator. #: #: .. versionadded:: 0.8 - self.before_first_request_funcs: t.List[BeforeFirstRequestCallable] = [] + self.before_first_request_funcs: t.List[ft.BeforeFirstRequestCallable] = [] #: A list of functions that are called when the application context #: is destroyed. Since the application context is also torn down @@ -444,7 +438,7 @@ class Flask(Scaffold): #: from databases. #: #: .. versionadded:: 0.9 - self.teardown_appcontext_funcs: t.List[TeardownCallable] = [] + self.teardown_appcontext_funcs: t.List[ft.TeardownCallable] = [] #: A list of shell context processor functions that should be run #: when a shell context is created. @@ -1096,7 +1090,7 @@ class Flask(Scaffold): @setupmethod def template_filter( self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]: + ) -> t.Callable[[ft.TemplateFilterCallable], ft.TemplateFilterCallable]: """A decorator that is used to register custom template filter. You can specify a name for the filter, otherwise the function name will be used. Example:: @@ -1109,7 +1103,7 @@ class Flask(Scaffold): function name will be used. """ - def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable: + def decorator(f: ft.TemplateFilterCallable) -> ft.TemplateFilterCallable: self.add_template_filter(f, name=name) return f @@ -1117,7 +1111,7 @@ class Flask(Scaffold): @setupmethod def add_template_filter( - self, f: TemplateFilterCallable, name: t.Optional[str] = None + self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None ) -> None: """Register a custom template filter. Works exactly like the :meth:`template_filter` decorator. @@ -1130,7 +1124,7 @@ class Flask(Scaffold): @setupmethod def template_test( self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]: + ) -> t.Callable[[ft.TemplateTestCallable], ft.TemplateTestCallable]: """A decorator that is used to register custom template test. You can specify a name for the test, otherwise the function name will be used. Example:: @@ -1150,7 +1144,7 @@ class Flask(Scaffold): function name will be used. """ - def decorator(f: TemplateTestCallable) -> TemplateTestCallable: + def decorator(f: ft.TemplateTestCallable) -> ft.TemplateTestCallable: self.add_template_test(f, name=name) return f @@ -1158,7 +1152,7 @@ class Flask(Scaffold): @setupmethod def add_template_test( - self, f: TemplateTestCallable, name: t.Optional[str] = None + self, f: ft.TemplateTestCallable, name: t.Optional[str] = None ) -> None: """Register a custom template test. Works exactly like the :meth:`template_test` decorator. @@ -1173,7 +1167,7 @@ class Flask(Scaffold): @setupmethod def template_global( self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]: + ) -> t.Callable[[ft.TemplateGlobalCallable], ft.TemplateGlobalCallable]: """A decorator that is used to register a custom template global function. You can specify a name for the global function, otherwise the function name will be used. Example:: @@ -1188,7 +1182,7 @@ class Flask(Scaffold): function name will be used. """ - def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable: + def decorator(f: ft.TemplateGlobalCallable) -> ft.TemplateGlobalCallable: self.add_template_global(f, name=name) return f @@ -1196,7 +1190,7 @@ class Flask(Scaffold): @setupmethod def add_template_global( - self, f: TemplateGlobalCallable, name: t.Optional[str] = None + self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None ) -> None: """Register a custom template global function. Works exactly like the :meth:`template_global` decorator. @@ -1210,8 +1204,8 @@ class Flask(Scaffold): @setupmethod def before_first_request( - self, f: BeforeFirstRequestCallable - ) -> BeforeFirstRequestCallable: + self, f: ft.BeforeFirstRequestCallable + ) -> ft.BeforeFirstRequestCallable: """Registers a function to be run before the first request to this instance of the application. @@ -1224,7 +1218,7 @@ class Flask(Scaffold): return f @setupmethod - def teardown_appcontext(self, f: TeardownCallable) -> TeardownCallable: + def teardown_appcontext(self, f: ft.TeardownCallable) -> ft.TeardownCallable: """Registers a function to be called when the application context ends. These functions are typically also called when the request context is popped. @@ -1265,7 +1259,7 @@ class Flask(Scaffold): self.shell_context_processors.append(f) return f - def _find_error_handler(self, e: Exception) -> t.Optional["ErrorHandlerCallable"]: + def _find_error_handler(self, e: Exception) -> t.Optional[ft.ErrorHandlerCallable]: """Return a registered error handler for an exception in this order: blueprint handler for a specific code, app handler for a specific code, blueprint handler for an exception class, app handler for an exception @@ -1290,7 +1284,7 @@ class Flask(Scaffold): def handle_http_exception( self, e: HTTPException - ) -> t.Union[HTTPException, ResponseReturnValue]: + ) -> t.Union[HTTPException, ft.ResponseReturnValue]: """Handles an HTTP exception. By default this will invoke the registered error handlers and fall back to returning the exception as response. @@ -1360,7 +1354,7 @@ class Flask(Scaffold): def handle_user_exception( self, e: Exception - ) -> t.Union[HTTPException, ResponseReturnValue]: + ) -> t.Union[HTTPException, ft.ResponseReturnValue]: """This method is called whenever an exception occurs that should be handled. A special case is :class:`~werkzeug .exceptions.HTTPException` which is forwarded to the @@ -1430,7 +1424,7 @@ class Flask(Scaffold): raise e self.log_exception(exc_info) - server_error: t.Union[InternalServerError, ResponseReturnValue] + server_error: t.Union[InternalServerError, ft.ResponseReturnValue] server_error = InternalServerError(original_exception=e) handler = self._find_error_handler(server_error) @@ -1484,7 +1478,7 @@ class Flask(Scaffold): raise FormDataRoutingRedirect(request) - def dispatch_request(self) -> ResponseReturnValue: + def dispatch_request(self) -> ft.ResponseReturnValue: """Does the request dispatching. Matches the URL and returns the return value of the view or error handler. This does not have to be a response object. In order to convert the return value to a @@ -1527,7 +1521,7 @@ class Flask(Scaffold): def finalize_request( self, - rv: t.Union[ResponseReturnValue, HTTPException], + rv: t.Union[ft.ResponseReturnValue, HTTPException], from_error_handler: bool = False, ) -> Response: """Given the return value from a view function this finalizes @@ -1630,7 +1624,7 @@ class Flask(Scaffold): return asgiref_async_to_sync(func) - def make_response(self, rv: ResponseReturnValue) -> Response: + def make_response(self, rv: ft.ResponseReturnValue) -> Response: """Convert the return value from a view function to an instance of :attr:`response_class`. @@ -1722,7 +1716,9 @@ class Flask(Scaffold): # evaluate a WSGI callable, or coerce a different response # class to the correct type try: - rv = self.response_class.force_type(rv, request.environ) # type: ignore # noqa: B950 + rv = self.response_class.force_type( + rv, request.environ # type: ignore[arg-type] + ) except TypeError as e: raise TypeError( f"{e}\nThe view function did not return a valid" @@ -1838,7 +1834,7 @@ class Flask(Scaffold): raise error - def preprocess_request(self) -> t.Optional[ResponseReturnValue]: + def preprocess_request(self) -> t.Optional[ft.ResponseReturnValue]: """Called before the request is dispatched. Calls :attr:`url_value_preprocessors` registered with the app and the current blueprint (if any). Then calls :attr:`before_request_funcs` diff --git a/src/flask/blueprints.py b/src/flask/blueprints.py index 5d3b4e22..c60183fa 100644 --- a/src/flask/blueprints.py +++ b/src/flask/blueprints.py @@ -3,23 +3,13 @@ import typing as t from collections import defaultdict from functools import update_wrapper +from . import typing as ft from .scaffold import _endpoint_from_view_func from .scaffold import _sentinel from .scaffold import Scaffold -from .typing import AfterRequestCallable -from .typing import BeforeFirstRequestCallable -from .typing import BeforeRequestCallable -from .typing import TeardownCallable -from .typing import TemplateContextProcessorCallable -from .typing import TemplateFilterCallable -from .typing import TemplateGlobalCallable -from .typing import TemplateTestCallable -from .typing import URLDefaultCallable -from .typing import URLValuePreprocessorCallable if t.TYPE_CHECKING: from .app import Flask - from .typing import ErrorHandlerCallable DeferredSetupFunction = t.Callable[["BlueprintSetupState"], t.Callable] @@ -419,7 +409,7 @@ class Blueprint(Scaffold): def app_template_filter( self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateFilterCallable], TemplateFilterCallable]: + ) -> t.Callable[[ft.TemplateFilterCallable], ft.TemplateFilterCallable]: """Register a custom template filter, available application wide. Like :meth:`Flask.template_filter` but for a blueprint. @@ -427,14 +417,14 @@ class Blueprint(Scaffold): function name will be used. """ - def decorator(f: TemplateFilterCallable) -> TemplateFilterCallable: + def decorator(f: ft.TemplateFilterCallable) -> ft.TemplateFilterCallable: self.add_app_template_filter(f, name=name) return f return decorator def add_app_template_filter( - self, f: TemplateFilterCallable, name: t.Optional[str] = None + self, f: ft.TemplateFilterCallable, name: t.Optional[str] = None ) -> None: """Register a custom template filter, available application wide. Like :meth:`Flask.add_template_filter` but for a blueprint. Works exactly @@ -451,7 +441,7 @@ class Blueprint(Scaffold): def app_template_test( self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateTestCallable], TemplateTestCallable]: + ) -> t.Callable[[ft.TemplateTestCallable], ft.TemplateTestCallable]: """Register a custom template test, available application wide. Like :meth:`Flask.template_test` but for a blueprint. @@ -461,14 +451,14 @@ class Blueprint(Scaffold): function name will be used. """ - def decorator(f: TemplateTestCallable) -> TemplateTestCallable: + def decorator(f: ft.TemplateTestCallable) -> ft.TemplateTestCallable: self.add_app_template_test(f, name=name) return f return decorator def add_app_template_test( - self, f: TemplateTestCallable, name: t.Optional[str] = None + self, f: ft.TemplateTestCallable, name: t.Optional[str] = None ) -> None: """Register a custom template test, available application wide. Like :meth:`Flask.add_template_test` but for a blueprint. Works exactly @@ -487,7 +477,7 @@ class Blueprint(Scaffold): def app_template_global( self, name: t.Optional[str] = None - ) -> t.Callable[[TemplateGlobalCallable], TemplateGlobalCallable]: + ) -> t.Callable[[ft.TemplateGlobalCallable], ft.TemplateGlobalCallable]: """Register a custom template global, available application wide. Like :meth:`Flask.template_global` but for a blueprint. @@ -497,14 +487,14 @@ class Blueprint(Scaffold): function name will be used. """ - def decorator(f: TemplateGlobalCallable) -> TemplateGlobalCallable: + def decorator(f: ft.TemplateGlobalCallable) -> ft.TemplateGlobalCallable: self.add_app_template_global(f, name=name) return f return decorator def add_app_template_global( - self, f: TemplateGlobalCallable, name: t.Optional[str] = None + self, f: ft.TemplateGlobalCallable, name: t.Optional[str] = None ) -> None: """Register a custom template global, available application wide. Like :meth:`Flask.add_template_global` but for a blueprint. Works exactly @@ -521,7 +511,9 @@ class Blueprint(Scaffold): self.record_once(register_template) - def before_app_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable: + def before_app_request( + self, f: ft.BeforeRequestCallable + ) -> ft.BeforeRequestCallable: """Like :meth:`Flask.before_request`. Such a function is executed before each request, even if outside of a blueprint. """ @@ -531,15 +523,15 @@ class Blueprint(Scaffold): return f def before_app_first_request( - self, f: BeforeFirstRequestCallable - ) -> BeforeFirstRequestCallable: + self, f: ft.BeforeFirstRequestCallable + ) -> ft.BeforeFirstRequestCallable: """Like :meth:`Flask.before_first_request`. Such a function is executed before the first request to the application. """ self.record_once(lambda s: s.app.before_first_request_funcs.append(f)) return f - def after_app_request(self, f: AfterRequestCallable) -> AfterRequestCallable: + def after_app_request(self, f: ft.AfterRequestCallable) -> ft.AfterRequestCallable: """Like :meth:`Flask.after_request` but for a blueprint. Such a function is executed after each request, even if outside of the blueprint. """ @@ -548,7 +540,7 @@ class Blueprint(Scaffold): ) return f - def teardown_app_request(self, f: TeardownCallable) -> TeardownCallable: + def teardown_app_request(self, f: ft.TeardownCallable) -> ft.TeardownCallable: """Like :meth:`Flask.teardown_request` but for a blueprint. Such a function is executed when tearing down each request, even if outside of the blueprint. @@ -559,8 +551,8 @@ class Blueprint(Scaffold): return f def app_context_processor( - self, f: TemplateContextProcessorCallable - ) -> TemplateContextProcessorCallable: + self, f: ft.TemplateContextProcessorCallable + ) -> ft.TemplateContextProcessorCallable: """Like :meth:`Flask.context_processor` but for a blueprint. Such a function is executed each request, even if outside of the blueprint. """ @@ -574,22 +566,22 @@ class Blueprint(Scaffold): handler is used for all requests, even if outside of the blueprint. """ - def decorator(f: "ErrorHandlerCallable") -> "ErrorHandlerCallable": + def decorator(f: ft.ErrorHandlerCallable) -> ft.ErrorHandlerCallable: self.record_once(lambda s: s.app.errorhandler(code)(f)) return f return decorator def app_url_value_preprocessor( - self, f: URLValuePreprocessorCallable - ) -> URLValuePreprocessorCallable: + self, f: ft.URLValuePreprocessorCallable + ) -> ft.URLValuePreprocessorCallable: """Same as :meth:`url_value_preprocessor` but application wide.""" self.record_once( lambda s: s.app.url_value_preprocessors.setdefault(None, []).append(f) ) return f - def app_url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable: + def app_url_defaults(self, f: ft.URLDefaultCallable) -> ft.URLDefaultCallable: """Same as :meth:`url_defaults` but application wide.""" self.record_once( lambda s: s.app.url_default_functions.setdefault(None, []).append(f) diff --git a/src/flask/ctx.py b/src/flask/ctx.py index 3ed8fd3a..e6822b2d 100644 --- a/src/flask/ctx.py +++ b/src/flask/ctx.py @@ -5,11 +5,11 @@ from types import TracebackType from werkzeug.exceptions import HTTPException +from . import typing as ft from .globals import _app_ctx_stack from .globals import _request_ctx_stack from .signals import appcontext_popped from .signals import appcontext_pushed -from .typing import AfterRequestCallable if t.TYPE_CHECKING: from .app import Flask @@ -109,7 +109,7 @@ class _AppCtxGlobals: return object.__repr__(self) -def after_this_request(f: AfterRequestCallable) -> AfterRequestCallable: +def after_this_request(f: ft.AfterRequestCallable) -> ft.AfterRequestCallable: """Executes a function after this request. This is useful to modify response objects. The function is passed the response object and has to return the same or a new one. @@ -341,7 +341,7 @@ class RequestContext: # Functions that should be executed after the request on the response # object. These will be called before the regular "after_request" # functions. - self._after_request_functions: t.List[AfterRequestCallable] = [] + self._after_request_functions: t.List[ft.AfterRequestCallable] = [] @property def g(self) -> _AppCtxGlobals: diff --git a/src/flask/scaffold.py b/src/flask/scaffold.py index acf8708b..7cd8bab5 100644 --- a/src/flask/scaffold.py +++ b/src/flask/scaffold.py @@ -12,23 +12,16 @@ from jinja2 import FileSystemLoader from werkzeug.exceptions import default_exceptions from werkzeug.exceptions import HTTPException +from . import typing as ft from .cli import AppGroup from .globals import current_app from .helpers import get_root_path from .helpers import locked_cached_property from .helpers import send_from_directory from .templating import _default_template_ctx_processor -from .typing import AfterRequestCallable -from .typing import AppOrBlueprintKey -from .typing import BeforeRequestCallable -from .typing import TeardownCallable -from .typing import TemplateContextProcessorCallable -from .typing import URLDefaultCallable -from .typing import URLValuePreprocessorCallable if t.TYPE_CHECKING: from .wrappers import Response - from .typing import ErrorHandlerCallable # a singleton sentinel value for parameter defaults _sentinel = object() @@ -143,8 +136,8 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.error_handler_spec: t.Dict[ - AppOrBlueprintKey, - t.Dict[t.Optional[int], t.Dict[t.Type[Exception], "ErrorHandlerCallable"]], + ft.AppOrBlueprintKey, + t.Dict[t.Optional[int], t.Dict[t.Type[Exception], ft.ErrorHandlerCallable]], ] = defaultdict(lambda: defaultdict(dict)) #: A data structure of functions to call at the beginning of @@ -158,7 +151,7 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.before_request_funcs: t.Dict[ - AppOrBlueprintKey, t.List[BeforeRequestCallable] + ft.AppOrBlueprintKey, t.List[ft.BeforeRequestCallable] ] = defaultdict(list) #: A data structure of functions to call at the end of each @@ -172,7 +165,7 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.after_request_funcs: t.Dict[ - AppOrBlueprintKey, t.List[AfterRequestCallable] + ft.AppOrBlueprintKey, t.List[ft.AfterRequestCallable] ] = defaultdict(list) #: A data structure of functions to call at the end of each @@ -187,7 +180,7 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.teardown_request_funcs: t.Dict[ - AppOrBlueprintKey, t.List[TeardownCallable] + ft.AppOrBlueprintKey, t.List[ft.TeardownCallable] ] = defaultdict(list) #: A data structure of functions to call to pass extra context @@ -202,7 +195,7 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.template_context_processors: t.Dict[ - AppOrBlueprintKey, t.List[TemplateContextProcessorCallable] + ft.AppOrBlueprintKey, t.List[ft.TemplateContextProcessorCallable] ] = defaultdict(list, {None: [_default_template_ctx_processor]}) #: A data structure of functions to call to modify the keyword @@ -217,8 +210,8 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.url_value_preprocessors: t.Dict[ - AppOrBlueprintKey, - t.List[URLValuePreprocessorCallable], + ft.AppOrBlueprintKey, + t.List[ft.URLValuePreprocessorCallable], ] = defaultdict(list) #: A data structure of functions to call to modify the keyword @@ -233,7 +226,7 @@ class Scaffold: #: This data structure is internal. It should not be modified #: directly and its format may change at any time. self.url_default_functions: t.Dict[ - AppOrBlueprintKey, t.List[URLDefaultCallable] + ft.AppOrBlueprintKey, t.List[ft.URLDefaultCallable] ] = defaultdict(list) def __repr__(self) -> str: @@ -534,7 +527,7 @@ class Scaffold: return decorator @setupmethod - def before_request(self, f: BeforeRequestCallable) -> BeforeRequestCallable: + def before_request(self, f: ft.BeforeRequestCallable) -> ft.BeforeRequestCallable: """Register a function to run before each request. For example, this can be used to open a database connection, or @@ -556,7 +549,7 @@ class Scaffold: return f @setupmethod - def after_request(self, f: AfterRequestCallable) -> AfterRequestCallable: + def after_request(self, f: ft.AfterRequestCallable) -> ft.AfterRequestCallable: """Register a function to run after each request to this object. The function is called with the response object, and must return @@ -572,7 +565,7 @@ class Scaffold: return f @setupmethod - def teardown_request(self, f: TeardownCallable) -> TeardownCallable: + def teardown_request(self, f: ft.TeardownCallable) -> ft.TeardownCallable: """Register a function to be run at the end of each request, regardless of whether there was an exception or not. These functions are executed when the request context is popped, even if not an @@ -612,16 +605,16 @@ class Scaffold: @setupmethod def context_processor( - self, f: TemplateContextProcessorCallable - ) -> TemplateContextProcessorCallable: + self, f: ft.TemplateContextProcessorCallable + ) -> ft.TemplateContextProcessorCallable: """Registers a template context processor function.""" self.template_context_processors[None].append(f) return f @setupmethod def url_value_preprocessor( - self, f: URLValuePreprocessorCallable - ) -> URLValuePreprocessorCallable: + self, f: ft.URLValuePreprocessorCallable + ) -> ft.URLValuePreprocessorCallable: """Register a URL value preprocessor function for all view functions in the application. These functions will be called before the :meth:`before_request` functions. @@ -638,7 +631,7 @@ class Scaffold: return f @setupmethod - def url_defaults(self, f: URLDefaultCallable) -> URLDefaultCallable: + def url_defaults(self, f: ft.URLDefaultCallable) -> ft.URLDefaultCallable: """Callback function for URL defaults for all view functions of the application. It's called with the endpoint and values and should update the values passed in place. @@ -649,7 +642,7 @@ class Scaffold: @setupmethod def errorhandler( self, code_or_exception: t.Union[t.Type[Exception], int] - ) -> t.Callable[["ErrorHandlerCallable"], "ErrorHandlerCallable"]: + ) -> t.Callable[[ft.ErrorHandlerCallable], ft.ErrorHandlerCallable]: """Register a function to handle errors by code or exception class. A decorator that is used to register a function given an @@ -679,7 +672,7 @@ class Scaffold: an arbitrary exception """ - def decorator(f: "ErrorHandlerCallable") -> "ErrorHandlerCallable": + def decorator(f: ft.ErrorHandlerCallable) -> ft.ErrorHandlerCallable: self.register_error_handler(code_or_exception, f) return f @@ -689,7 +682,7 @@ class Scaffold: def register_error_handler( self, code_or_exception: t.Union[t.Type[Exception], int], - f: "ErrorHandlerCallable", + f: ft.ErrorHandlerCallable, ) -> None: """Alternative error attach function to the :meth:`errorhandler` decorator that is more straightforward to use for non decorator diff --git a/src/flask/views.py b/src/flask/views.py index 1bd5c68b..1dd560c6 100644 --- a/src/flask/views.py +++ b/src/flask/views.py @@ -1,8 +1,8 @@ import typing as t +from . import typing as ft from .globals import current_app from .globals import request -from .typing import ResponseReturnValue http_method_funcs = frozenset( @@ -59,7 +59,7 @@ class View: #: .. versionadded:: 0.8 decorators: t.List[t.Callable] = [] - def dispatch_request(self) -> ResponseReturnValue: + def dispatch_request(self) -> ft.ResponseReturnValue: """Subclasses have to override this method to implement the actual view function code. This method is called with all the arguments from the URL rule. @@ -79,7 +79,7 @@ class View: constructor of the class. """ - def view(*args: t.Any, **kwargs: t.Any) -> ResponseReturnValue: + def view(*args: t.Any, **kwargs: t.Any) -> ft.ResponseReturnValue: self = view.view_class(*class_args, **class_kwargs) # type: ignore return current_app.ensure_sync(self.dispatch_request)(*args, **kwargs) @@ -146,7 +146,7 @@ class MethodView(View, metaclass=MethodViewType): app.add_url_rule('/counter', view_func=CounterAPI.as_view('counter')) """ - def dispatch_request(self, *args: t.Any, **kwargs: t.Any) -> ResponseReturnValue: + def dispatch_request(self, *args: t.Any, **kwargs: t.Any) -> ft.ResponseReturnValue: meth = getattr(self, request.method.lower(), None) # If the request method is HEAD and we don't have a handler for it From 21d32ee0672c69573303ac78ff308109b06c9c91 Mon Sep 17 00:00:00 2001 From: David Lord Date: Wed, 1 Jun 2022 11:23:09 -0700 Subject: [PATCH 6/6] update requirements --- requirements/dev.txt | 4 ++-- requirements/typing.txt | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements/dev.txt b/requirements/dev.txt index 2cdefc96..3667056d 100644 --- a/requirements/dev.txt +++ b/requirements/dev.txt @@ -16,7 +16,7 @@ click==8.1.3 # pip-tools distlib==0.3.4 # via virtualenv -filelock==3.7.0 +filelock==3.7.1 # via # tox # virtualenv @@ -30,7 +30,7 @@ pep517==0.12.0 # via pip-tools pip-compile-multi==2.4.5 # via -r requirements/dev.in -pip-tools==6.6.1 +pip-tools==6.6.2 # via pip-compile-multi platformdirs==2.5.2 # via virtualenv diff --git a/requirements/typing.txt b/requirements/typing.txt index bf5e2a39..2e17dfb6 100644 --- a/requirements/typing.txt +++ b/requirements/typing.txt @@ -9,7 +9,7 @@ cffi==1.15.0 # via cryptography cryptography==37.0.2 # via -r requirements/typing.in -mypy==0.950 +mypy==0.960 # via -r requirements/typing.in mypy-extensions==0.4.3 # via mypy @@ -17,11 +17,11 @@ pycparser==2.21 # via cffi tomli==2.0.1 # via mypy -types-contextvars==2.4.5 +types-contextvars==2.4.6 # via -r requirements/typing.in types-dataclasses==0.6.5 # via -r requirements/typing.in -types-setuptools==57.4.15 +types-setuptools==57.4.17 # via -r requirements/typing.in typing-extensions==4.2.0 # via mypy