Opened 7 years ago

Closed 7 years ago

#7694 closed (invalid)

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

Reported by: davenaff 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: UI/UX:


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 7 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

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