public
Last active

Show all signals receivers in Django project

  • Download Gist
signals.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
# coding:utf-8
 
import gc
from sys import modules
import inspect
from optparse import make_option
import weakref
 
from django.core.management.base import BaseCommand
from django.dispatch import Signal, saferef
 
REF_TYPES = (weakref.ReferenceType, saferef.BoundMethodWeakref, saferef.BoundMethodWeakref)
 
FORMATS = {
'vim': '{path}:{line}:{name}',
'human': '{name} in line {line} of {path}',
}
 
class Command(BaseCommand):
help = 'Show all signals receivers'
option_list = BaseCommand.option_list + (
make_option('--format',
dest='line_format',
default='human',
choices=FORMATS.keys(),
help='Line format (available choices: {0})'.format(', '.join(FORMATS)),
),
)
def handle(self, *args, **options):
line_format = options['line_format']
if line_format not in FORMATS:
raise CommandError('format must be on of {0}, not {1}'.format(line_format, FORMATS.keys()))
msg = FORMATS[line_format]
signals = [obj for obj in gc.get_objects() if isinstance(obj, Signal)]
for signal in signals:
for receiver in signal.receivers:
_, receiver = receiver
# django.contrib.contenttypes.generic.GenericForeignKey.instance_pre_init is not weakref
if isinstance(receiver, REF_TYPES):
receiver = receiver()
print msg.format(name=receiver.func_name, line=inspect.getsourcelines(receiver)[1], path=inspect.getsourcefile(receiver))

@voldmar - this is really helpful - thanks for posting. Is it possible to get the name of the Signal as well as the receiver function - I've tried myself but can't work out how to do it.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.