Skip to content

Instantly share code, notes, and snippets.

@jefftriplett
Forked from voldmar/signals.py
Last active April 1, 2016 08:43
Show Gist options
  • Save jefftriplett/6211009 to your computer and use it in GitHub Desktop.
Save jefftriplett/6211009 to your computer and use it in GitHub Desktop.
Django management command to trace / list all signals. My fork is just a few cleanups where CommandError wasn't referenced, etc.
# coding:utf-8
import gc
import inspect
import weakref
from django.core.management.base import BaseCommand, CommandError
from django.dispatch import Signal, saferef
from optparse import make_option
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))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment