diff options
author | Ilya Baryshev <baryshev@gmail.com> | 2015-07-02 23:44:37 +0300 |
---|---|---|
committer | Raphaƫl Barrois <raphael.barrois@polytechnique.org> | 2015-07-05 17:04:18 +0200 |
commit | d471c1b4b0d4b06d557b5b6a9349a7dc55515d69 (patch) | |
tree | 923ed608763457fd0bf83ff5fdb8632779b69a48 | |
parent | 5114549520e95c658716b7cbe9a7ab333d8ca524 (diff) | |
download | factory-boy-d471c1b4b0d4b06d557b5b6a9349a7dc55515d69.tar factory-boy-d471c1b4b0d4b06d557b5b6a9349a7dc55515d69.tar.gz |
Fix mute_signals behavior for signals with caching
Connecting signals (with use_caching=True) inside mute_signals
was breaking unmute on exit. Paused receivers were not running.
This was caused by signal cache not being restored after unpatching.
Workaround is to clear signal cache on exit.
Fixes #212
-rw-r--r-- | docs/changelog.rst | 1 | ||||
-rw-r--r-- | factory/django.py | 2 | ||||
-rw-r--r-- | tests/test_django.py | 13 |
3 files changed, 16 insertions, 0 deletions
diff --git a/docs/changelog.rst b/docs/changelog.rst index eea38c5..01d5775 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -20,6 +20,7 @@ ChangeLog *Bugfix:* - :issue:`201`: Properly handle custom Django managers when dealing with abstract Django models. + - :issue:`212`: Fix :meth:`factory.django.mute_signals` to handle Django's signal caching .. _v2.5.2: diff --git a/factory/django.py b/factory/django.py index e4a3ea7..5cc2b31 100644 --- a/factory/django.py +++ b/factory/django.py @@ -277,6 +277,8 @@ class mute_signals(object): receivers) signal.receivers = receivers + with signal.lock: + signal.sender_receivers_cache.clear() self.paused = {} def copy(self): diff --git a/tests/test_django.py b/tests/test_django.py index b8e7ccb..103df91 100644 --- a/tests/test_django.py +++ b/tests/test_django.py @@ -678,6 +678,19 @@ class PreventSignalsTestCase(unittest.TestCase): self.assertSignalsReactivated() + def test_signal_cache(self): + with factory.django.mute_signals(signals.pre_save, signals.post_save): + signals.post_save.connect(self.handlers.mute_block_receiver) + WithSignalsFactory() + + self.assertTrue(self.handlers.mute_block_receiver.call_count, 1) + self.assertEqual(self.handlers.pre_init.call_count, 1) + self.assertFalse(self.handlers.pre_save.called) + self.assertFalse(self.handlers.post_save.called) + + self.assertSignalsReactivated() + self.assertTrue(self.handlers.mute_block_receiver.call_count, 1) + def test_class_decorator(self): @factory.django.mute_signals(signals.pre_save, signals.post_save) class WithSignalsDecoratedFactory(factory.django.DjangoModelFactory): |