Opened 4 years ago

Closed 4 years ago

#18850 closed Bug (duplicate)

After doing some recursive import, the gobal value of `X` that defined with value `1` is automatically set to `None`, if class derived from `models.Model`

Reported by: OmidRaha Owned by: nobody
Component: Database layer (models, ORM) Version: 1.4
Severity: Normal Keywords:
Cc: apollo13 Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


I attached a sample project(test_dj),
this project can run with django 1.4 or later,
the problem I found is that after doing some recursive import,
the gobal value of X that defined with value 1 is automatically set to None, if class derived from models.Model

You can test this issue:

  1. Extract test_dj project
  2. run python shell
  3. doing test:

In [1]: from test_dj.package_A.models import X_IS_OK,X_IS_None

In [2]: X_IS_OK()
Ok, X is 1

In [3]: X_IS_None()
Wow ! why X is None ?

Attachments (1)

test_dj.tar (24.0 KB) - added by OmidRaha 4 years ago.
Sample test project

Download all attachments as: .zip

Change History (6)

Changed 4 years ago by OmidRaha

Sample test project

comment:1 Changed 4 years ago by OmidRaha

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

To simplify the problem, i print X in constructor of model(without call supper of it),
but if you change the 'init' to another method, This problem still occurs ,for example:

class X_IS_None(models.Model):

def test(self):

print 'Wow ! why X is {0} ?'.format(X)

comment:2 Changed 4 years ago by apollo13

  • Cc apollo13 added

Stack from the importError in get_models from django.db.models.loading:

Traceback (most recent call last):
File "", line 2, in <module>
File "/home/florian/sources/django.git/django/db/models/", line 192, in get_models
File "/home/florian/sources/django.git/django/db/models/", line 72, in _populate
self.load_app(app_name, True)
File "/home/florian/sources/django.git/django/db/models/", line 98, in load_app
models = import_module('.models', app_name)
File "/home/florian/sources/django.git/django/utils/", line 35, in import_module
File "/home/florian/dev/test_dj/test_dj/package_B/", line 2, in <module>
from test_dj.package_B.package_BA.module_BA import Unit_BA
File "/home/florian/dev/test_dj/test_dj/package_B/package_BA/", line 1, in <module>
from test_dj.module_D import Unit_D
File "/home/florian/dev/test_dj/test_dj/", line 5, in <module>
from test_dj.package_A.models import Unit_A
File "/home/florian/dev/test_dj/test_dj/package_A/", line 21, in <module>
from test_dj.package_C.package_CA.module_CA import Unit_CA
File "/home/florian/dev/test_dj/test_dj/package_C/package_CA/", line 1, in <module>
from test_dj.package_C.models import Unit_C
File "/home/florian/dev/test_dj/test_dj/package_C/", line 2, in <module>
from test_dj.package_B.models import Unit_B
ImportError: cannot import name Unit_B

So this is Code doesn't work in Python at all, and Django silences the import errors :/ Restructuring INSTALLED_APPS might help in that specific case.

comment:3 Changed 4 years ago by OmidRaha

Yes, i know that with reordering the app in INSTALLED_APPS, the problem can be solved, but why django silences the import errors? can say django, doesn't do that, and raise import errors?
and in this specific case why X is None and at least isn't undefined.

Last edited 4 years ago by OmidRaha (previous) (diff)

comment:4 Changed 4 years ago by lrekucki

Sadly in Python, at the time of writing, you can't easily tell if the ImportError was raised because the module you tried did not exist, failed to execute or tried to import something else that raised an ImportError. What Django could do is to check if the module exists and reraise when appropriate (like does).

As for X is None, that's a puzzle. I'm not yet sure if it's legitimate behavior or a bug in Python's import mechanics, but if you check the module by hand, the X has value 1, so that other X must come from some different deinitialized version of the module.

comment:5 Changed 4 years ago by aaugustin

  • Resolution set to duplicate
  • Status changed from new to closed

As explained by lrekucki, short of restructuring the app import machinery, there isn't much we can do in Django to provide a better error message in this case. This restructuring is actually a work in progress, it's the app-loading branch, see #3591.

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