Browse Source

Fixed #31327 -- Deprecated providing_args argument for Signal.

Jon Dufresne 5 years ago
parent
commit
769cee5252

+ 3 - 3
django/contrib/auth/signals.py

@@ -1,5 +1,5 @@
 from django.dispatch import Signal
 
-user_logged_in = Signal(providing_args=['request', 'user'])
-user_login_failed = Signal(providing_args=['credentials', 'request'])
-user_logged_out = Signal(providing_args=['request', 'user'])
+user_logged_in = Signal()
+user_login_failed = Signal()
+user_logged_out = Signal()

+ 3 - 3
django/core/signals.py

@@ -1,6 +1,6 @@
 from django.dispatch import Signal
 
-request_started = Signal(providing_args=["environ", "scope"])
+request_started = Signal()
 request_finished = Signal()
-got_request_exception = Signal(providing_args=["request"])
-setting_changed = Signal(providing_args=["setting", "value", "enter"])
+got_request_exception = Signal()
+setting_changed = Signal()

+ 1 - 1
django/db/backends/signals.py

@@ -1,3 +1,3 @@
 from django.dispatch import Signal
 
-connection_created = Signal(providing_args=["connection"])
+connection_created = Signal()

+ 10 - 14
django/db/models/signals.py

@@ -3,7 +3,7 @@ from functools import partial
 from django.db.models.utils import make_model_tuple
 from django.dispatch import Signal
 
-class_prepared = Signal(providing_args=["class"])
+class_prepared = Signal()
 
 
 class ModelSignal(Signal):
@@ -34,20 +34,16 @@ class ModelSignal(Signal):
         )
 
 
-pre_init = ModelSignal(providing_args=["instance", "args", "kwargs"], use_caching=True)
-post_init = ModelSignal(providing_args=["instance"], use_caching=True)
+pre_init = ModelSignal(use_caching=True)
+post_init = ModelSignal(use_caching=True)
 
-pre_save = ModelSignal(providing_args=["instance", "raw", "using", "update_fields"],
-                       use_caching=True)
-post_save = ModelSignal(providing_args=["instance", "raw", "created", "using", "update_fields"], use_caching=True)
+pre_save = ModelSignal(use_caching=True)
+post_save = ModelSignal(use_caching=True)
 
-pre_delete = ModelSignal(providing_args=["instance", "using"], use_caching=True)
-post_delete = ModelSignal(providing_args=["instance", "using"], use_caching=True)
+pre_delete = ModelSignal(use_caching=True)
+post_delete = ModelSignal(use_caching=True)
 
-m2m_changed = ModelSignal(
-    providing_args=["action", "instance", "reverse", "model", "pk_set", "using"],
-    use_caching=True,
-)
+m2m_changed = ModelSignal(use_caching=True)
 
-pre_migrate = Signal(providing_args=["app_config", "verbosity", "interactive", "using", "apps", "plan"])
-post_migrate = Signal(providing_args=["app_config", "verbosity", "interactive", "using", "apps", "plan"])
+pre_migrate = Signal()
+post_migrate = Signal()

+ 11 - 9
django/dispatch/dispatcher.py

@@ -1,6 +1,8 @@
 import threading
+import warnings
 import weakref
 
+from django.utils.deprecation import RemovedInDjango40Warning
 from django.utils.inspect import func_accepts_kwargs
 
 
@@ -28,14 +30,16 @@ class Signal:
     def __init__(self, providing_args=None, use_caching=False):
         """
         Create a new signal.
-
-        providing_args
-            A list of the arguments this signal can pass along in a send() call.
         """
         self.receivers = []
-        if providing_args is None:
-            providing_args = []
-        self.providing_args = set(providing_args)
+        if providing_args is not None:
+            warnings.warn(
+                'The providing_args argument is deprecated. As it is purely '
+                'documentational, it has no replacement. If you rely on this '
+                'argument as documentation, you can move the text to a code '
+                'comment or docstring.',
+                RemovedInDjango40Warning, stacklevel=2,
+            )
         self.lock = threading.Lock()
         self.use_caching = use_caching
         # For convenience we create empty caches even if they are not used.
@@ -187,9 +191,7 @@ class Signal:
                 occur).
 
             named
-                Named arguments which will be passed to receivers. These
-                arguments must be a subset of the argument names defined in
-                providing_args.
+                Named arguments which will be passed to receivers.
 
         Return a list of tuple pairs [(receiver, response), ... ].
 

+ 1 - 1
django/test/signals.py

@@ -14,7 +14,7 @@ from django.utils import timezone
 from django.utils.formats import FORMAT_SETTINGS, reset_format_cache
 from django.utils.functional import empty
 
-template_rendered = Signal(providing_args=["template", "context"])
+template_rendered = Signal()
 
 # Most setting_changed receivers are supposed to be added below,
 # except for cases where the receiver is related to a contrib app.

+ 1 - 1
django/utils/autoreload.py

@@ -21,7 +21,7 @@ from django.utils.functional import cached_property
 from django.utils.version import get_version_tuple
 
 autoreload_started = Signal()
-file_changed = Signal(providing_args=['file_path', 'kind'])
+file_changed = Signal()
 
 DJANGO_AUTORELOAD_ENV = 'RUN_MAIN'
 

+ 3 - 0
docs/internals/deprecation.txt

@@ -58,6 +58,9 @@ details on these changes.
   ``django.utils.deprecation.MiddlewareMixin.__init__()`` will be required and
   won't accept ``None``.
 
+* The ``providing_args`` argument for ``django.dispatch.Signal`` will be
+  removed.
+
 See the :ref:`Django 3.1 release notes <deprecated-features-3.1>` for more
 details on these changes.
 

+ 5 - 0
docs/releases/3.1.txt

@@ -546,6 +546,11 @@ Miscellaneous
   older versions of Django. Support for the old format remains until Django
   4.0.
 
+* The purely documentational ``providing_args`` argument for
+  :class:`~django.dispatch.Signal` is deprecated. If you rely on this
+  argument as documentation, you can move the text to a code comment or 
+  docstring.
+  
 .. _removed-features-3.1:
 
 Features removed in 3.1

+ 4 - 11
docs/topics/signals.txt

@@ -216,24 +216,17 @@ its own signals.
 Defining signals
 ----------------
 
-.. class:: Signal(providing_args=list)
+.. class:: Signal()
 
-All signals are :class:`django.dispatch.Signal` instances. The
-``providing_args`` is a list of the names of arguments the signal will provide
-to listeners. This is purely documentational, however, as there is nothing that
-checks that the signal actually provides these arguments to its listeners.
+All signals are :class:`django.dispatch.Signal` instances.
 
 For example::
 
     import django.dispatch
 
-    pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
+    pizza_done = django.dispatch.Signal()
 
-This declares a ``pizza_done`` signal that will provide receivers with
-``toppings`` and ``size`` arguments.
-
-Remember that you're allowed to change this list of arguments at any time, so
-getting the API right on the first try isn't necessary.
+This declares a ``pizza_done`` signal.
 
 Sending signals
 ---------------

+ 4 - 4
tests/dispatch/tests.py

@@ -29,10 +29,10 @@ class Callable:
         return val
 
 
-a_signal = Signal(providing_args=["val"])
-b_signal = Signal(providing_args=["val"])
-c_signal = Signal(providing_args=["val"])
-d_signal = Signal(providing_args=["val"], use_caching=True)
+a_signal = Signal()
+b_signal = Signal()
+c_signal = Signal()
+d_signal = Signal(use_caching=True)
 
 
 class DispatcherTests(SimpleTestCase):

+ 22 - 0
tests/signals/test_deprecation.py

@@ -0,0 +1,22 @@
+import warnings
+
+from django.dispatch import Signal
+from django.test import SimpleTestCase
+from django.utils.deprecation import RemovedInDjango40Warning
+
+
+class SignalDeprecationTests(SimpleTestCase):
+    def test_providing_args_warning(self):
+        msg = (
+            'The providing_args argument is deprecated. As it is purely '
+            'documentational, it has no replacement. If you rely on this '
+            'argument as documentation, you can move the text to a code '
+            'comment or docstring.'
+        )
+        with self.assertWarnsMessage(RemovedInDjango40Warning, msg):
+            Signal(providing_args=['arg1', 'arg2'])
+
+    def test_without_providing_args_does_not_warn(self):
+        with warnings.catch_warnings(record=True) as recorded:
+            Signal()
+        self.assertEqual(len(recorded), 0)