mirror of https://github.com/pallets/flask.git
blinker is required, signals are always available
This commit is contained in:
parent
e1e4e82096
commit
9cb1a7a52d
|
@ -28,6 +28,8 @@ Unreleased
|
||||||
- The ``app.got_first_request`` property is deprecated. :pr:`4997`
|
- The ``app.got_first_request`` property is deprecated. :pr:`4997`
|
||||||
- The ``locked_cached_property`` decorator is deprecated. Use a lock inside the
|
- The ``locked_cached_property`` decorator is deprecated. Use a lock inside the
|
||||||
decorated function if locking is needed. :issue:`4993`
|
decorated function if locking is needed. :issue:`4993`
|
||||||
|
- Signals are always available. ``blinker>=1.6.2`` is a required dependency. The
|
||||||
|
``signals_available`` attribute is deprecated. :issue:`5056`
|
||||||
- Remove uses of locks that could cause requests to block each other very briefly.
|
- Remove uses of locks that could cause requests to block each other very briefly.
|
||||||
:issue:`4993`
|
:issue:`4993`
|
||||||
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
|
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
|
||||||
|
|
28
docs/api.rst
28
docs/api.rst
|
@ -333,14 +333,9 @@ Useful Internals
|
||||||
Signals
|
Signals
|
||||||
-------
|
-------
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
Signals are provided by the `Blinker`_ library. See :doc:`signals` for an introduction.
|
||||||
|
|
||||||
.. data:: signals.signals_available
|
.. _blinker: https://blinker.readthedocs.io/
|
||||||
|
|
||||||
``True`` if the signaling system is available. This is the case
|
|
||||||
when `blinker`_ is installed.
|
|
||||||
|
|
||||||
The following signals exist in Flask:
|
|
||||||
|
|
||||||
.. data:: template_rendered
|
.. data:: template_rendered
|
||||||
|
|
||||||
|
@ -507,7 +502,6 @@ The following signals exist in Flask:
|
||||||
|
|
||||||
.. versionadded:: 0.10
|
.. versionadded:: 0.10
|
||||||
|
|
||||||
|
|
||||||
.. data:: message_flashed
|
.. data:: message_flashed
|
||||||
|
|
||||||
This signal is sent when the application is flashing a message. The
|
This signal is sent when the application is flashing a message. The
|
||||||
|
@ -525,22 +519,10 @@ The following signals exist in Flask:
|
||||||
|
|
||||||
.. versionadded:: 0.10
|
.. versionadded:: 0.10
|
||||||
|
|
||||||
.. class:: signals.Namespace
|
.. data:: signals.signals_available
|
||||||
|
|
||||||
An alias for :class:`blinker.base.Namespace` if blinker is available,
|
.. deprecated:: 2.3
|
||||||
otherwise a dummy class that creates fake signals. This class is
|
Will be removed in Flask 2.4. Signals are always available
|
||||||
available for Flask extensions that want to provide the same fallback
|
|
||||||
system as Flask itself.
|
|
||||||
|
|
||||||
.. method:: signal(name, doc=None)
|
|
||||||
|
|
||||||
Creates a new signal for this namespace if blinker is available,
|
|
||||||
otherwise returns a fake signal that has a send method that will
|
|
||||||
do nothing but will fail with a :exc:`RuntimeError` for all other
|
|
||||||
operations, including connecting.
|
|
||||||
|
|
||||||
|
|
||||||
.. _blinker: https://pypi.org/project/blinker/
|
|
||||||
|
|
||||||
|
|
||||||
Class-Based Views
|
Class-Based Views
|
||||||
|
|
|
@ -140,10 +140,8 @@ Accessing ``db`` will call ``get_db`` internally, in the same way that
|
||||||
Events and Signals
|
Events and Signals
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
The application will call functions registered with
|
The application will call functions registered with :meth:`~Flask.teardown_appcontext`
|
||||||
:meth:`~Flask.teardown_appcontext` when the application context is
|
when the application context is popped.
|
||||||
popped.
|
|
||||||
|
|
||||||
If :data:`~signals.signals_available` is true, the following signals are
|
The following signals are sent: :data:`appcontext_pushed`,
|
||||||
sent: :data:`appcontext_pushed`, :data:`appcontext_tearing_down`, and
|
:data:`appcontext_tearing_down`, and :data:`appcontext_popped`.
|
||||||
:data:`appcontext_popped`.
|
|
||||||
|
|
|
@ -24,12 +24,14 @@ These distributions will be installed automatically when installing Flask.
|
||||||
to protect Flask's session cookie.
|
to protect Flask's session cookie.
|
||||||
* `Click`_ is a framework for writing command line applications. It provides
|
* `Click`_ is a framework for writing command line applications. It provides
|
||||||
the ``flask`` command and allows adding custom management commands.
|
the ``flask`` command and allows adding custom management commands.
|
||||||
|
* `Blinker`_ provides support for :doc:`signals`.
|
||||||
|
|
||||||
.. _Werkzeug: https://palletsprojects.com/p/werkzeug/
|
.. _Werkzeug: https://palletsprojects.com/p/werkzeug/
|
||||||
.. _Jinja: https://palletsprojects.com/p/jinja/
|
.. _Jinja: https://palletsprojects.com/p/jinja/
|
||||||
.. _MarkupSafe: https://palletsprojects.com/p/markupsafe/
|
.. _MarkupSafe: https://palletsprojects.com/p/markupsafe/
|
||||||
.. _ItsDangerous: https://palletsprojects.com/p/itsdangerous/
|
.. _ItsDangerous: https://palletsprojects.com/p/itsdangerous/
|
||||||
.. _Click: https://palletsprojects.com/p/click/
|
.. _Click: https://palletsprojects.com/p/click/
|
||||||
|
.. _Blinker: https://blinker.readthedocs.io/
|
||||||
|
|
||||||
|
|
||||||
Optional dependencies
|
Optional dependencies
|
||||||
|
@ -38,13 +40,11 @@ Optional dependencies
|
||||||
These distributions will not be installed automatically. Flask will detect and
|
These distributions will not be installed automatically. Flask will detect and
|
||||||
use them if you install them.
|
use them if you install them.
|
||||||
|
|
||||||
* `Blinker`_ provides support for :doc:`signals`.
|
|
||||||
* `python-dotenv`_ enables support for :ref:`dotenv` when running ``flask``
|
* `python-dotenv`_ enables support for :ref:`dotenv` when running ``flask``
|
||||||
commands.
|
commands.
|
||||||
* `Watchdog`_ provides a faster, more efficient reloader for the development
|
* `Watchdog`_ provides a faster, more efficient reloader for the development
|
||||||
server.
|
server.
|
||||||
|
|
||||||
.. _Blinker: https://blinker.readthedocs.io/en/stable/
|
|
||||||
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
|
.. _python-dotenv: https://github.com/theskumar/python-dotenv#readme
|
||||||
.. _watchdog: https://pythonhosted.org/watchdog/
|
.. _watchdog: https://pythonhosted.org/watchdog/
|
||||||
|
|
||||||
|
|
|
@ -204,21 +204,16 @@ contexts until the ``with`` block exits.
|
||||||
Signals
|
Signals
|
||||||
~~~~~~~
|
~~~~~~~
|
||||||
|
|
||||||
If :data:`~signals.signals_available` is true, the following signals are
|
The following signals are sent:
|
||||||
sent:
|
|
||||||
|
|
||||||
#. :data:`request_started` is sent before the
|
#. :data:`request_started` is sent before the :meth:`~Flask.before_request` functions
|
||||||
:meth:`~Flask.before_request` functions are called.
|
are called.
|
||||||
|
#. :data:`request_finished` is sent after the :meth:`~Flask.after_request` functions
|
||||||
#. :data:`request_finished` is sent after the
|
are called.
|
||||||
:meth:`~Flask.after_request` functions are called.
|
#. :data:`got_request_exception` is sent when an exception begins to be handled, but
|
||||||
|
before an :meth:`~Flask.errorhandler` is looked up or called.
|
||||||
#. :data:`got_request_exception` is sent when an exception begins to
|
#. :data:`request_tearing_down` is sent after the :meth:`~Flask.teardown_request`
|
||||||
be handled, but before an :meth:`~Flask.errorhandler` is looked up or
|
functions are called.
|
||||||
called.
|
|
||||||
|
|
||||||
#. :data:`request_tearing_down` is sent after the
|
|
||||||
:meth:`~Flask.teardown_request` functions are called.
|
|
||||||
|
|
||||||
|
|
||||||
.. _notes-on-proxies:
|
.. _notes-on-proxies:
|
||||||
|
|
|
@ -1,33 +1,28 @@
|
||||||
Signals
|
Signals
|
||||||
=======
|
=======
|
||||||
|
|
||||||
.. versionadded:: 0.6
|
Signals are a lightweight way to notify subscribers of certain events during the
|
||||||
|
lifecycle of the application and each request. When an event occurs, it emits the
|
||||||
|
signal, which calls each subscriber.
|
||||||
|
|
||||||
Starting with Flask 0.6, there is integrated support for signalling in
|
Signals are implemented by the `Blinker`_ library. See its documentation for detailed
|
||||||
Flask. This support is provided by the excellent `blinker`_ library and
|
information. Flask provides some built-in signals. Extensions may provide their own.
|
||||||
will gracefully fall back if it is not available.
|
|
||||||
|
|
||||||
What are signals? Signals help you decouple applications by sending
|
Many signals mirror Flask's decorator-based callbacks with similar names. For example,
|
||||||
notifications when actions occur elsewhere in the core framework or
|
the :data:`.request_started` signal is similar to the :meth:`~.Flask.before_request`
|
||||||
another Flask extensions. In short, signals allow certain senders to
|
decorator. The advantage of signals over handlers is that they can be subscribed to
|
||||||
notify subscribers that something happened.
|
temporarily, and can't directly affect the application. This is useful for testing,
|
||||||
|
metrics, auditing, and more. For example, if you want to know what templates were
|
||||||
|
rendered at what parts of what requests, there is a signal that will notify you of that
|
||||||
|
information.
|
||||||
|
|
||||||
Flask comes with a couple of signals and other extensions might provide
|
|
||||||
more. Also keep in mind that signals are intended to notify subscribers
|
|
||||||
and should not encourage subscribers to modify data. You will notice that
|
|
||||||
there are signals that appear to do the same thing like some of the
|
|
||||||
builtin decorators do (eg: :data:`~flask.request_started` is very similar
|
|
||||||
to :meth:`~flask.Flask.before_request`). However, there are differences in
|
|
||||||
how they work. The core :meth:`~flask.Flask.before_request` handler, for
|
|
||||||
example, is executed in a specific order and is able to abort the request
|
|
||||||
early by returning a response. In contrast all signal handlers are
|
|
||||||
executed in undefined order and do not modify any data.
|
|
||||||
|
|
||||||
The big advantage of signals over handlers is that you can safely
|
Core Signals
|
||||||
subscribe to them for just a split second. These temporary
|
------------
|
||||||
subscriptions are helpful for unit testing for example. Say you want to
|
|
||||||
know what templates were rendered as part of a request: signals allow you
|
See :ref:`core-signals-list` for a list of all built-in signals. The :doc:`lifecycle`
|
||||||
to do exactly that.
|
page also describes the order that signals and decorators execute.
|
||||||
|
|
||||||
|
|
||||||
Subscribing to Signals
|
Subscribing to Signals
|
||||||
----------------------
|
----------------------
|
||||||
|
@ -99,11 +94,6 @@ The example above would then look like this::
|
||||||
...
|
...
|
||||||
template, context = templates[0]
|
template, context = templates[0]
|
||||||
|
|
||||||
.. admonition:: Blinker API Changes
|
|
||||||
|
|
||||||
The :meth:`~blinker.base.Signal.connected_to` method arrived in Blinker
|
|
||||||
with version 1.1.
|
|
||||||
|
|
||||||
Creating Signals
|
Creating Signals
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
@ -123,12 +113,6 @@ The name for the signal here makes it unique and also simplifies
|
||||||
debugging. You can access the name of the signal with the
|
debugging. You can access the name of the signal with the
|
||||||
:attr:`~blinker.base.NamedSignal.name` attribute.
|
:attr:`~blinker.base.NamedSignal.name` attribute.
|
||||||
|
|
||||||
.. admonition:: For Extension Developers
|
|
||||||
|
|
||||||
If you are writing a Flask extension and you want to gracefully degrade for
|
|
||||||
missing blinker installations, you can do so by using the
|
|
||||||
:class:`flask.signals.Namespace` class.
|
|
||||||
|
|
||||||
.. _signals-sending:
|
.. _signals-sending:
|
||||||
|
|
||||||
Sending Signals
|
Sending Signals
|
||||||
|
@ -170,7 +154,7 @@ in :ref:`signals-sending` and the :data:`~flask.request_tearing_down` signal.
|
||||||
Decorator Based Signal Subscriptions
|
Decorator Based Signal Subscriptions
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
With Blinker 1.1 you can also easily subscribe to signals by using the new
|
You can also easily subscribe to signals by using the
|
||||||
:meth:`~blinker.base.NamedSignal.connect_via` decorator::
|
:meth:`~blinker.base.NamedSignal.connect_via` decorator::
|
||||||
|
|
||||||
from flask import template_rendered
|
from flask import template_rendered
|
||||||
|
@ -179,10 +163,5 @@ With Blinker 1.1 you can also easily subscribe to signals by using the new
|
||||||
def when_template_rendered(sender, template, context, **extra):
|
def when_template_rendered(sender, template, context, **extra):
|
||||||
print(f'Template {template.name} is rendered with {context}')
|
print(f'Template {template.name} is rendered with {context}')
|
||||||
|
|
||||||
Core Signals
|
|
||||||
------------
|
|
||||||
|
|
||||||
Take a look at :ref:`core-signals-list` for a list of all builtin signals.
|
|
||||||
|
|
||||||
|
|
||||||
.. _blinker: https://pypi.org/project/blinker/
|
.. _blinker: https://pypi.org/project/blinker/
|
||||||
|
|
|
@ -11,7 +11,7 @@ dependencies = ["flask"]
|
||||||
Documentation = "https://flask.palletsprojects.com/patterns/jquery/"
|
Documentation = "https://flask.palletsprojects.com/patterns/jquery/"
|
||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
test = ["pytest", "blinker"]
|
test = ["pytest"]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools"]
|
requires = ["setuptools"]
|
||||||
|
|
|
@ -24,6 +24,7 @@ dependencies = [
|
||||||
"Jinja2>=3.0",
|
"Jinja2>=3.0",
|
||||||
"itsdangerous>=2.0",
|
"itsdangerous>=2.0",
|
||||||
"click>=8.0",
|
"click>=8.0",
|
||||||
|
"blinker>=1.6.2",
|
||||||
"importlib-metadata>=3.6.0; python_version < '3.10'",
|
"importlib-metadata>=3.6.0; python_version < '3.10'",
|
||||||
]
|
]
|
||||||
dynamic = ["version"]
|
dynamic = ["version"]
|
||||||
|
@ -90,7 +91,6 @@ warn_unused_ignores = true
|
||||||
[[tool.mypy.overrides]]
|
[[tool.mypy.overrides]]
|
||||||
module = [
|
module = [
|
||||||
"asgiref.*",
|
"asgiref.*",
|
||||||
"blinker.*",
|
|
||||||
"dotenv.*",
|
"dotenv.*",
|
||||||
"cryptography.*",
|
"cryptography.*",
|
||||||
"importlib_metadata",
|
"importlib_metadata",
|
||||||
|
|
|
@ -11,5 +11,3 @@ packaging==23.0
|
||||||
# via build
|
# via build
|
||||||
pyproject-hooks==1.0.0
|
pyproject-hooks==1.0.0
|
||||||
# via build
|
# via build
|
||||||
tomli==2.0.1
|
|
||||||
# via build
|
|
||||||
|
|
|
@ -3,3 +3,4 @@ Jinja2==3.0.0
|
||||||
MarkupSafe==2.0.0
|
MarkupSafe==2.0.0
|
||||||
itsdangerous==2.0.0
|
itsdangerous==2.0.0
|
||||||
click==8.0.0
|
click==8.0.0
|
||||||
|
blinker==1.6.2
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
# SHA1:4de7d9e6254a945fd97ec10880dd23b6cd43b70d
|
# SHA1:575f86f45391b662630a6080f0a12676215eb0cf
|
||||||
#
|
#
|
||||||
# This file is autogenerated by pip-compile-multi
|
# This file is autogenerated by pip-compile-multi
|
||||||
# To update, run:
|
# To update, run:
|
||||||
#
|
#
|
||||||
# pip-compile-multi
|
# pip-compile-multi
|
||||||
#
|
#
|
||||||
|
blinker==1.6.2
|
||||||
|
# via -r requirements/tests-pallets-min.in
|
||||||
click==8.0.0
|
click==8.0.0
|
||||||
# via -r requirements/tests-pallets-min.in
|
# via -r requirements/tests-pallets-min.in
|
||||||
itsdangerous==2.0.0
|
itsdangerous==2.0.0
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
pytest
|
pytest
|
||||||
asgiref
|
asgiref
|
||||||
blinker
|
|
||||||
greenlet ; python_version < "3.11"
|
greenlet ; python_version < "3.11"
|
||||||
python-dotenv>=1; python_version >= "3.8"
|
python-dotenv>=1; python_version >= "3.8"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# SHA1:30698f5f4f9cba5088318306829a15b0dc123b38
|
# SHA1:3c8dde35aba20388b22430b17974af8ef8205b4f
|
||||||
#
|
#
|
||||||
# This file is autogenerated by pip-compile-multi
|
# This file is autogenerated by pip-compile-multi
|
||||||
# To update, run:
|
# To update, run:
|
||||||
|
@ -7,12 +7,6 @@
|
||||||
#
|
#
|
||||||
asgiref==3.6.0
|
asgiref==3.6.0
|
||||||
# via -r requirements/tests.in
|
# via -r requirements/tests.in
|
||||||
blinker==1.6.1
|
|
||||||
# via -r requirements/tests.in
|
|
||||||
exceptiongroup==1.1.1
|
|
||||||
# via pytest
|
|
||||||
greenlet==2.0.2 ; python_version < "3.11"
|
|
||||||
# via -r requirements/tests.in
|
|
||||||
iniconfig==2.0.0
|
iniconfig==2.0.0
|
||||||
# via pytest
|
# via pytest
|
||||||
packaging==23.0
|
packaging==23.0
|
||||||
|
@ -23,7 +17,3 @@ pytest==7.3.0
|
||||||
# via -r requirements/tests.in
|
# via -r requirements/tests.in
|
||||||
python-dotenv==1.0.0 ; python_version >= "3.8"
|
python-dotenv==1.0.0 ; python_version >= "3.8"
|
||||||
# via -r requirements/tests.in
|
# via -r requirements/tests.in
|
||||||
tomli==2.0.1
|
|
||||||
# via pytest
|
|
||||||
typing-extensions==4.5.0
|
|
||||||
# via blinker
|
|
||||||
|
|
|
@ -15,8 +15,6 @@ mypy-extensions==1.0.0
|
||||||
# via mypy
|
# via mypy
|
||||||
pycparser==2.21
|
pycparser==2.21
|
||||||
# via cffi
|
# via cffi
|
||||||
tomli==2.0.1
|
|
||||||
# via mypy
|
|
||||||
types-contextvars==2.4.7.2
|
types-contextvars==2.4.7.2
|
||||||
# via -r requirements/typing.in
|
# via -r requirements/typing.in
|
||||||
types-dataclasses==0.6.6
|
types-dataclasses==0.6.6
|
||||||
|
|
|
@ -32,7 +32,6 @@ from .signals import message_flashed as message_flashed
|
||||||
from .signals import request_finished as request_finished
|
from .signals import request_finished as request_finished
|
||||||
from .signals import request_started as request_started
|
from .signals import request_started as request_started
|
||||||
from .signals import request_tearing_down as request_tearing_down
|
from .signals import request_tearing_down as request_tearing_down
|
||||||
from .signals import signals_available as signals_available
|
|
||||||
from .signals import template_rendered as template_rendered
|
from .signals import template_rendered as template_rendered
|
||||||
from .templating import render_template as render_template
|
from .templating import render_template as render_template
|
||||||
from .templating import render_template_string as render_template_string
|
from .templating import render_template_string as render_template_string
|
||||||
|
@ -89,4 +88,15 @@ def __getattr__(name):
|
||||||
)
|
)
|
||||||
return Markup
|
return Markup
|
||||||
|
|
||||||
|
if name == "signals_available":
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
warnings.warn(
|
||||||
|
"'signals_available' is deprecated and will be removed in Flask 2.4."
|
||||||
|
" Signals are always available",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
raise AttributeError(name)
|
raise AttributeError(name)
|
||||||
|
|
|
@ -1,49 +1,13 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
import warnings
|
||||||
|
|
||||||
try:
|
from blinker import Namespace
|
||||||
from blinker import Namespace
|
|
||||||
|
|
||||||
signals_available = True
|
# This namespace is only for signals provided by Flask itself.
|
||||||
except ImportError:
|
|
||||||
signals_available = False
|
|
||||||
|
|
||||||
class Namespace: # type: ignore
|
|
||||||
def signal(self, name: str, doc: t.Optional[str] = None) -> "_FakeSignal":
|
|
||||||
return _FakeSignal(name, doc)
|
|
||||||
|
|
||||||
class _FakeSignal:
|
|
||||||
"""If blinker is unavailable, create a fake class with the same
|
|
||||||
interface that allows sending of signals but will fail with an
|
|
||||||
error on anything else. Instead of doing anything on send, it
|
|
||||||
will just ignore the arguments and do nothing instead.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, name: str, doc: t.Optional[str] = None) -> None:
|
|
||||||
self.name = name
|
|
||||||
self.__doc__ = doc
|
|
||||||
|
|
||||||
def send(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _fail(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
|
|
||||||
raise RuntimeError(
|
|
||||||
"Signalling support is unavailable because the blinker"
|
|
||||||
" library is not installed."
|
|
||||||
) from None
|
|
||||||
|
|
||||||
connect = connect_via = connected_to = temporarily_connected_to = _fail
|
|
||||||
disconnect = _fail
|
|
||||||
has_receivers_for = receivers_for = _fail
|
|
||||||
del _fail
|
|
||||||
|
|
||||||
|
|
||||||
# The namespace for code signals. If you are not Flask code, do
|
|
||||||
# not put signals in here. Create your own namespace instead.
|
|
||||||
_signals = Namespace()
|
_signals = Namespace()
|
||||||
|
|
||||||
|
|
||||||
# Core signals. For usage examples grep the source code or consult
|
|
||||||
# the API documentation in docs/api.rst as well as docs/signals.rst
|
|
||||||
template_rendered = _signals.signal("template-rendered")
|
template_rendered = _signals.signal("template-rendered")
|
||||||
before_render_template = _signals.signal("before-render-template")
|
before_render_template = _signals.signal("before-render-template")
|
||||||
request_started = _signals.signal("request-started")
|
request_started = _signals.signal("request-started")
|
||||||
|
@ -54,3 +18,16 @@ appcontext_tearing_down = _signals.signal("appcontext-tearing-down")
|
||||||
appcontext_pushed = _signals.signal("appcontext-pushed")
|
appcontext_pushed = _signals.signal("appcontext-pushed")
|
||||||
appcontext_popped = _signals.signal("appcontext-popped")
|
appcontext_popped = _signals.signal("appcontext-popped")
|
||||||
message_flashed = _signals.signal("message-flashed")
|
message_flashed = _signals.signal("message-flashed")
|
||||||
|
|
||||||
|
|
||||||
|
def __getattr__(name: str) -> t.Any:
|
||||||
|
if name == "signals_available":
|
||||||
|
warnings.warn(
|
||||||
|
"The 'signals_available' attribute is deprecated and will be removed in"
|
||||||
|
" Flask 2.4. Signals are always available.",
|
||||||
|
DeprecationWarning,
|
||||||
|
stacklevel=2,
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
raise AttributeError(name)
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
import pytest
|
|
||||||
|
|
||||||
try:
|
|
||||||
import blinker
|
|
||||||
except ImportError:
|
|
||||||
blinker = None
|
|
||||||
|
|
||||||
import flask
|
import flask
|
||||||
|
|
||||||
pytestmark = pytest.mark.skipif(
|
|
||||||
blinker is None, reason="Signals require the blinker library."
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_template_rendered(app, client):
|
def test_template_rendered(app, client):
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
|
|
|
@ -10,11 +10,6 @@ from flask.json import jsonify
|
||||||
from flask.testing import EnvironBuilder
|
from flask.testing import EnvironBuilder
|
||||||
from flask.testing import FlaskCliRunner
|
from flask.testing import FlaskCliRunner
|
||||||
|
|
||||||
try:
|
|
||||||
import blinker
|
|
||||||
except ImportError:
|
|
||||||
blinker = None
|
|
||||||
|
|
||||||
|
|
||||||
def test_environ_defaults_from_config(app, client):
|
def test_environ_defaults_from_config(app, client):
|
||||||
app.config["SERVER_NAME"] = "example.com:1234"
|
app.config["SERVER_NAME"] = "example.com:1234"
|
||||||
|
@ -285,7 +280,6 @@ def test_json_request_and_response(app, client):
|
||||||
assert rv.get_json() == json_data
|
assert rv.get_json() == json_data
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(blinker is None, reason="blinker is not installed")
|
|
||||||
def test_client_json_no_app_context(app, client):
|
def test_client_json_no_app_context(app, client):
|
||||||
@app.route("/hello", methods=["POST"])
|
@app.route("/hello", methods=["POST"])
|
||||||
def hello():
|
def hello():
|
||||||
|
|
Loading…
Reference in New Issue