Opened 11 years ago

Closed 11 years ago

#7694 closed (invalid)

Models that are imported into (and utilize signals) result in parallel tests that break test cases

Reported by: Dave Naffziger Owned by: nobody
Component: Testing framework Version: master
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


In a sample file:

def MyModel(models.Model):
    >>> u=User.objects.create_user('test2','')
    anyfield = models.BooleanField()


def user_pre_save(sender, instance, signal, *args, **kwargs):
    global COUNT
    r = random.randint(1,50)
    print 'pre_save: count: %s random: %s' %(COUNT, r)
    COUNT +=1

dispatcher.connect(user_pre_save, signal=signals.pre_save,

Then create a and add this import (that's all you need):

from myproject.models import MyModel 

Here is what the test output looks like. Note that it looks like we're creating two duplicate threads each with their own state (COUNT doesn't increment between the runs of user_pre_save, but random is different.

pre_save: count: 0 random: 49
pre_save: count: 0 random: 23
Failed example:
Expected nothing
    pre_save: count: 1 random: 13
    pre_save: count: 1 random: 2

Failed example:
Expected nothing
    pre_save: count: 2 random: 18
    pre_save: count: 2 random: 49 

I've not been able to figure out what is causing this.

Change History (1)

comment:1 Changed 11 years ago by Russell Keith-Magee

Resolution: invalid
Status: newclosed

What you're seeing is the result of the signal handler getting installed twice. This is due to a quirk of Python's model importer; if one file has "from import whiz", and a second file has "from bar import whiz", the whiz module will be imported and processed twice, as long as the PYTHONPATH supports finding both locations.

In this case, I'm guessing that two locations are settings.INSTALLED_APPS and differ - one has the full project path, but the other only has the application name in the import. As a result, the module is getting imported twice, and the signal is getting installed twice. If you modify the import paths to be consistent, the problem will go away.

Note: See TracTickets for help on using tickets.
Back to Top