summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUnai Zalakain <unai@gisa-elkartea.org>2013-10-30 12:11:04 +0100
committerTim Graham <timograham@gmail.com>2014-05-16 18:41:40 -0400
commitebb0279f4a7a7155c44c09506bbe5b1f9acc83a2 (patch)
tree769622df7218ad608f9bb0d85e510b4fd02245e7
parent79e9da3d1ef8c4bdc20d53b668228abb219ac55b (diff)
Fixed #16245 -- Included traceback in send_robust()'s response
Exceptions from the (receiver, exception) tuples returned by ``send_robust()`` now have always their traceback attached as their ``__traceback__`` argument.
-rw-r--r--django/dispatch/dispatcher.py5
-rw-r--r--docs/releases/1.8.txt4
-rw-r--r--docs/topics/signals.txt5
-rw-r--r--tests/dispatch/tests/test_dispatcher.py3
4 files changed, 15 insertions, 2 deletions
diff --git a/django/dispatch/dispatcher.py b/django/dispatch/dispatcher.py
index ba97077ce5..20048f5c55 100644
--- a/django/dispatch/dispatcher.py
+++ b/django/dispatch/dispatcher.py
@@ -220,7 +220,8 @@ class Signal(object):
If any receiver raises an error (specifically any subclass of
Exception), the error instance is returned as the result for that
- receiver.
+ receiver. The traceback is always attached to the error at
+ ``__traceback__``.
"""
responses = []
if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS:
@@ -232,6 +233,8 @@ class Signal(object):
try:
response = receiver(signal=self, sender=sender, **named)
except Exception as err:
+ if not hasattr(err, '__traceback__'):
+ err.__traceback__ = sys.exc_info()[2]
responses.append((receiver, err))
else:
responses.append((receiver, response))
diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt
index aa39fb2b7c..94a4f3ed74 100644
--- a/docs/releases/1.8.txt
+++ b/docs/releases/1.8.txt
@@ -153,7 +153,9 @@ Models
Signals
^^^^^^^
-* ...
+* Exceptions from the ``(receiver, exception)`` tuples returned by
+ :meth:`Signal.send_robust() <django.dispatch.Signal.send_robust>` now have
+ their traceback attached as a ``__traceback__`` attribute.
Templates
^^^^^^^^^
diff --git a/docs/topics/signals.txt b/docs/topics/signals.txt
index 346d47d179..fb83258c9b 100644
--- a/docs/topics/signals.txt
+++ b/docs/topics/signals.txt
@@ -274,6 +274,11 @@ be notified of a signal in the face of an error.
and ensures all receivers are notified of the signal. If an error occurs, the
error instance is returned in the tuple pair for the receiver that raised the error.
+.. versionadded:: 1.8
+
+ The tracebacks are present on the ``__traceback__`` attribute
+ of the errors returned when calling ``send_robust()``.
+
Disconnecting signals
=====================
diff --git a/tests/dispatch/tests/test_dispatcher.py b/tests/dispatch/tests/test_dispatcher.py
index 05b375f7d6..1bfa48aa80 100644
--- a/tests/dispatch/tests/test_dispatcher.py
+++ b/tests/dispatch/tests/test_dispatcher.py
@@ -3,6 +3,7 @@ import sys
import time
import unittest
import weakref
+from types import TracebackType
from django.dispatch import Signal, receiver
@@ -134,6 +135,8 @@ class DispatcherTests(unittest.TestCase):
err = result[0][1]
self.assertIsInstance(err, ValueError)
self.assertEqual(err.args, ('this',))
+ self.assertTrue(hasattr(err, '__traceback__'))
+ self.assertTrue(isinstance(err.__traceback__, TracebackType))
a_signal.disconnect(fails)
self._testIsClean(a_signal)