Commit 34a3bd52 authored by Jacob Kaplan-Moss's avatar Jacob Kaplan-Moss
Browse files

Major refactoring of django.dispatch with an eye towards speed. The net result...

Major refactoring of django.dispatch with an eye towards speed. The net result is that signals are up to 90% faster.

Though some attempts and backwards-compatibility were made, speed trumped compatibility. Thus, as usual, check BackwardsIncompatibleChanges for the complete list of backwards-incompatible changes.

Thanks to Jeremy Dunck and Keith Busell for the bulk of the work; some ideas from Brian Herring's previous work (refs #4561) were incorporated.

Documentation is, sigh, still forthcoming.

Fixes #6814 and #3951 (with the new dispatch_uid argument to connect).


git-svn-id: http://code.djangoproject.com/svn/django/trunk@8223 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent d06b4742
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@
Creates permissions for all installed apps that need permissions.
"""

from django.dispatch import dispatcher
from django.db.models import get_models, signals
from django.contrib.auth import models as auth_app

@@ -16,7 +15,7 @@ def _get_all_permissions(opts):
        perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
    return perms + list(opts.permissions)

def create_permissions(app, created_models, verbosity):
def create_permissions(app, created_models, verbosity, **kwargs):
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.auth.models import Permission
    app_models = get_models(app)
@@ -45,7 +44,7 @@ def create_superuser(app, created_models, verbosity, **kwargs):
                call_command("createsuperuser", interactive=True)
            break

if 'create_permissions' not in [i.__name__ for i in dispatcher.getAllReceivers(signal=signals.post_syncdb)]:
    dispatcher.connect(create_permissions, signal=signals.post_syncdb)
if 'create_superuser' not in [i.__name__ for i in dispatcher.getAllReceivers(signal=signals.post_syncdb, sender=auth_app)]:
    dispatcher.connect(create_superuser, sender=auth_app, signal=signals.post_syncdb)
 No newline at end of file
signals.post_syncdb.connect(create_permissions,
    dispatch_uid = "django.contrib.auth.management.create_permissions")
signals.post_syncdb.connect(create_superuser,
    sender=auth_app, dispatch_uid = "django.contrib.auth.management.create_superuser")
+2 −3
Original line number Diff line number Diff line
@@ -8,7 +8,6 @@ from django.db import connection
from django.db.models import signals
from django.db.models.fields.related import RelatedField, Field, ManyToManyRel
from django.db.models.loading import get_model
from django.dispatch import dispatcher
from django.utils.functional import curry

class GenericForeignKey(object):
@@ -29,12 +28,12 @@ class GenericForeignKey(object):
        self.cache_attr = "_%s_cache" % name

        # For some reason I don't totally understand, using weakrefs here doesn't work.
        dispatcher.connect(self.instance_pre_init, signal=signals.pre_init, sender=cls, weak=False)
        signals.pre_init.connect(self.instance_pre_init, sender=cls, weak=False)

        # Connect myself as the descriptor for this field
        setattr(cls, name, self)

    def instance_pre_init(self, signal, sender, args, kwargs):
    def instance_pre_init(self, signal, sender, args, kwargs, **_kwargs):
        """
        Handles initializing an object with the generic FK instaed of
        content-type/object-id fields.
+2 −3
Original line number Diff line number Diff line
from django.contrib.contenttypes.models import ContentType
from django.dispatch import dispatcher
from django.db.models import get_apps, get_models, signals
from django.utils.encoding import smart_unicode

def update_contenttypes(app, created_models, verbosity=2):
def update_contenttypes(app, created_models, verbosity=2, **kwargs):
    """
    Creates content types for models in the given app, removing any model
    entries that no longer have a matching model class.
@@ -37,7 +36,7 @@ def update_all_contenttypes(verbosity=2):
    for app in get_apps():
        update_contenttypes(app, None, verbosity)

dispatcher.connect(update_contenttypes, signal=signals.post_syncdb)
signals.post_syncdb.connect(update_contenttypes)

if __name__ == "__main__":
    update_all_contenttypes()
+2 −3
Original line number Diff line number Diff line
@@ -2,12 +2,11 @@
Creates the default Site object.
"""

from django.dispatch import dispatcher
from django.db.models import signals
from django.contrib.sites.models import Site
from django.contrib.sites import models as site_app

def create_default_site(app, created_models, verbosity):
def create_default_site(app, created_models, verbosity, **kwargs):
    if Site in created_models:
        if verbosity >= 2:
            print "Creating example.com Site object"
@@ -15,4 +14,4 @@ def create_default_site(app, created_models, verbosity):
        s.save()
    Site.objects.clear_cache()

dispatcher.connect(create_default_site, sender=site_app, signal=signals.post_syncdb)
signals.post_syncdb.connect(create_default_site, sender=site_app)
+1 −2
Original line number Diff line number Diff line
@@ -2,7 +2,6 @@ import sys

from django import http
from django.core import signals
from django.dispatch import dispatcher
from django.utils.encoding import force_unicode

class BaseHandler(object):
@@ -122,7 +121,7 @@ class BaseHandler(object):
        except: # Handle everything else, including SuspiciousOperation, etc.
            # Get the exception info now, in case another exception is thrown later.
            exc_info = sys.exc_info()
            receivers = dispatcher.send(signal=signals.got_request_exception, request=request)
            receivers = signals.got_request_exception.send(sender=self.__class__, request=request)
            return self.handle_uncaught_exception(request, resolver, exc_info)

    def handle_uncaught_exception(self, request, resolver, exc_info):
Loading