Opened 10 years ago
Closed 5 years ago
#11264 closed Bug (invalid)
"from django.db import models" clobbered in functions inside __init__.py of installed apps
Reported by: | Antti Kaihola | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | master |
Severity: | Normal | Keywords: | importing |
Cc: | miracle2k | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
If an app myapp
has the following __init__.py
:
from django.db import models def myfunc(): assert models.__package__ == 'django.db.models', ( 'models is %r instead of django.db.models' % models)
then calling myapp.myfunc()
throws:
AssertionError: models is <module 'myapp.models' from 'myapp/models.pyc'> instead of django.db.models
This happens only if
myapp
is in INSTALLED_APPSmyfunc
is inmyapp/__init__.py
, not some other module in it- Django is r10088 or later (thanks, git bisect)
This breaks at least Satchmo from a few months back for me, probably trunk too.
r10088 claims to have fixed all dynamic imports in Django by backporting importlib
from Python 2.7.
Attachments (1)
Change History (10)
Changed 10 years ago by
Attachment: | 11264_models_clobber_test_project.zip added |
---|
comment:1 Changed 10 years ago by
Replying to akaihola:
Messed up the assertion error -- for myapp
it's of course
AssertionError: models is <module 'myapp.models' from 'myapp/models.pyc'> instead of django.db.models
So what happens is that inside the function models
points to the app's own models.py
instead of django.db.models
.
comment:2 Changed 10 years ago by
The issue this causes in Satchmo was reported in a thread on the Satchmo users Google Group.
comment:3 Changed 9 years ago by
Triage Stage: | Unreviewed → Accepted |
---|
Some extra debug: If your test case invokes
import myapp myapp.myfunc()
or
import myapp from myapp import model myapp.myfunc()
everything works as expected. It's only when you run
import myapp from myapp.models import * myapp.myfunc()
that you get a problem.
comment:4 Changed 9 years ago by
Cc: | miracle2k added |
---|
comment:5 Changed 8 years ago by
Severity: | → Normal |
---|---|
Type: | → Bug |
comment:6 Changed 8 years ago by
Description: | modified (diff) |
---|---|
Easy pickings: | unset |
UI/UX: | unset |
comment:7 Changed 6 years ago by
This bug still exists in master.
After adjusting settings.py and manage.py for Django 1.6 in the test project, I was able to reproduce it:
>>> import models_clobber_test_app >>> models_clobber_test_app.assert_models_package() Traceback (most recent call last): File "<console>", line 1, in <module> File "/Users/myk/Documents/dev/django/models_clobber_test_project/models_clobber_test_app/__init__.py", line 11, in assert_models_package 'models is %r instead of django.db.models' % models) AssertionError: models is <module 'models_clobber_test_app.models' from '/Users/myk/Documents/dev/django/models_clobber_test_project/models_clobber_test_app/models.py'> instead of django.db.models
comment:8 Changed 6 years ago by
Component: | Core (Other) → Database layer (models, ORM) |
---|
comment:9 Changed 5 years ago by
Resolution: | → invalid |
---|---|
Status: | new → closed |
It turns out that this has nothing to do with Django. This surprising behavior can be reproduced with plain Python modules.
% cat foo/__init__.py
bar = 42 def print_bar(): print(bar)
% cat foo/bar.py
# Empty module.
% python
>>> from foo import print_bar >>> print_bar() 42 >>> import foo.bar >>> print_bar() <module 'foo.bar' from 'foo/bar.py'>
a minimal test project to reproduce "models" clobbering