Missing DJANGO_SETTINGS_MODULE
jonashaag opened this issue · 24 comments
With empty .coveragerc
:
$ coverage run foo/manage.py test bar
[...works...]
With django-coverage-plugin in .coveragerc
:
[run]
plugins =
django_coverage_plugin
$ coverage run foo/manage.py test bar
[...]
django.core.exceptions.ImproperlyConfigured: Requested setting TEMPLATES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
manage.py
is unmodified (generated by Django).
Can you show the complete error report with traceback?
Sure. Actually from the traceback it looks more like django-coverage-plugin wants the use settings before manage.py
has loaded the environment variable; changing the title accordingly.
Traceback (most recent call last):
File "/my/project/.tox/py35-django18/bin/coverage", line 11, in <module>
sys.exit(main())
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/coverage/cmdline.py", line 741, in main
status = CoverageScript().command_line(argv)
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/coverage/cmdline.py", line 481, in command_line
return self.do_run(options, args)
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/coverage/cmdline.py", line 610, in do_run
self.coverage.erase()
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/coverage/control.py", line 709, in erase
self._init()
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/coverage/control.py", line 218, in _init
self.plugins = Plugins.load_plugins(self.config.plugins, self.config, self.debug)
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/coverage/plugin_support.py", line 49, in load_plugins
coverage_init(plugins, options)
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/django_coverage_plugin/__init__.py", line 11, in coverage_init
reg.add_file_tracer(DjangoTemplatePlugin())
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/django_coverage_plugin/plugin.py", line 122, in __init__
check_debug()
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/django_coverage_plugin/plugin.py", line 52, in check_debug
templates = getattr(settings, 'TEMPLATES', [])
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/django/conf/__init__.py", line 48, in __getattr__
self._setup(name)
File "/my/project/.tox/py35-django18/lib/python3.5/site-packages/django/conf/__init__.py", line 42, in _setup
% (desc, ENVIRONMENT_VARIABLE))
django.core.exceptions.ImproperlyConfigured: Requested setting TEMPLATES, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Note that this worked in 1.1 and broke in 1.2, I can bisect the commit for you if you want
@jonashaag more details about how reproduce this, or which commit it was, would be great.
Just use startproject
, startapp
, and then the settings I show above.
Bump
@jonashaag Did you manage to identify the exact commit that causes the error?
@keimlink Yes but I don't remember which one it was, you can simply run git bisect
to find it
bisect points at 0085fb8
I'll be able to jump into this more easily with a zipfile or specific instructions about how to reproduce it.
Steps to reproduce:
mkvirtualenv issue-18
pip install git+https://github.com/nedbat/django_coverage_plugin.git
django-admin startproject myprj
printf "[run]\nplugins = \n django_coverage_plugin\n" > .coveragerc
coverage run myprj/manage.py test
Actually, it works fine if you run from the directory where manage.py is located. I think that is expected. You should always run manage.py
from its direct parent directory. Otherwise, DJANGO_SETTINGS_MODULE
will point at the wrong target (unless you take some other measure to get your project into sys.path
).
@jonashaag: does it work if you cd into foo
and run ./manage.py test
?
Eh, sorry. My comment above about having to run manage.py
from its parent dir is wrong. DJANGO_SETTINGS_MODULE
is relative to the location of manage.py
. I really shouldn't debug things at this time of the day :-/
But at least I found out that the current directory has something to do with it. Happy debugging ;)
The working directory is a red herring: that's because there's no .coveragerc in the subdirectory. If you copy it there, the failure happens in either directory.
I think the fix is to move the plugin's access of settings to later, when it is actually needed.
Just chiming in to say I fixed this same bug when using pytest-cov
by just commenting out check_debug()
: emmalemma@e083da1 True, I won't get the nice warning if the settings are wrong, just 0% coverage; on the upside, when the settings are correct, the plugin actually works.
If anyone's trying to find a better solution, I can tell you that you need to find a way to raise this error after __init__
, since in this configuration that happens before settings have been loaded. Unfortunately coverage
seems to like to swallow all errors after that point. Good luck.
I'll make a new release. If you could test it out, that would be great.
Thanks! With my config, fdb0892 works but still doesn't log the error when template debugging is off. Nothing in the coverage debug log either. For the record I'm using:
coverage (4.1)
pytest (2.9.1)
pytest-cov (2.2.1)
pytest-django (2.9.1)
I'm not sure which of these is responsible for eating the exception.
@emmalemma Can you show me some output? When I run a project without a debug setting, I get this:
$ coverage run manage.py test
Coverage.py warning: Disabling plugin 'django_coverage_plugin.DjangoTemplatePlugin' due to an exception:
Traceback (most recent call last):
File "/usr/local/virtualenvs/django_coverage/lib/python2.7/site-packages/coverage/control.py", line 499, in _should_trace_internal
file_tracer = plugin.file_tracer(canonical)
File "/Users/ned/coverage/django_coverage_plugin/django_coverage_plugin/plugin.py", line 154, in file_tracer
check_debug()
File "/Users/ned/coverage/django_coverage_plugin/django_coverage_plugin/plugin.py", line 69, in check_debug
"Template debugging must be enabled in settings."
DjangoTemplatePluginException: Template debugging must be enabled in settings.
Creating test database for alias 'default'...
..........
----------------------------------------------------------------------
Ran 10 tests in 0.060s
OK
Destroying test database for alias 'default'...
$
Sure. I can reproduce this with a minimal pytest setup:
virtualenv -p python3 venv
source venv/bin/activate
pip install django pytest pytest-django pytest-cov
pip install -e "git+https://github.com/nedbat/django_coverage_plugin@fdb0892966362e2ded39e4124d095a999a28543e#egg=django_coverage_plugin"
django-admin startproject coverage_test
cd coverage_test
printf "[run]\nplugins=django_coverage_plugin\n" > .coveragerc
mkdir coverage_test/templates
printf "test\n" > coverage_test/templates/test.html
create tests.py
:
from django.template.loader import render_to_string
def test():
render_to_string('test.html')
edit settings.py:
INSTALLED_APPS.append('coverage_test')
TEMPLATES[0]['OPTIONS']['debug'] = True
Demonstrate it works:
> export DJANGO_SETTINGS_MODULE=coverage_test.settings
> py.test tests.py --cov coverage_test
====================================== test session starts =======================================
platform darwin -- Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
django settings: coverage_test.settings (from environment variable)
rootdir: /Users/emma/Dropbox/Projects/coverage_test/coverage_test, inifile:
plugins: cov-2.2.1, django-2.9.1
collected 1 items
tests.py .
------------------------ coverage: platform darwin, python 3.5.1-final-0 -------------------------
Name Stmts Miss Cover
-------------------------------------------------------
coverage_test/__init__.py 0 0 100%
coverage_test/settings.py 20 0 100%
coverage_test/templates/test.html 1 0 100%
coverage_test/urls.py 3 3 0%
coverage_test/wsgi.py 4 4 0%
-------------------------------------------------------
TOTAL 28 7 75%
==================================== 1 passed in 0.32 seconds ====================================
Then set TEMPLATES[0]['OPTIONS']['debug'] = False
, and demonstrate it fails silently:
> py.test tests.py --cov coverage_test
====================================== test session starts =======================================
platform darwin -- Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
django settings: coverage_test.settings (from environment variable)
rootdir: /Users/emma/Dropbox/Projects/coverage_test/coverage_test, inifile:
plugins: cov-2.2.1, django-2.9.1
collected 1 items
tests.py .
------------------------ coverage: platform darwin, python 3.5.1-final-0 -------------------------
Name Stmts Miss Cover
-----------------------------------------------
coverage_test/__init__.py 0 0 100%
coverage_test/settings.py 20 0 100%
coverage_test/urls.py 3 3 0%
coverage_test/wsgi.py 4 4 0%
-----------------------------------------------
TOTAL 27 7 74%
==================================== 1 passed in 0.27 seconds ====================================
If I run the same thing on emmalemma/django_coverage_plugin@e083da1, with check_debug
disabled, it shows 0% coverage:
> py.test tests.py --cov coverage_test
====================================== test session starts =======================================
platform darwin -- Python 3.5.1, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
django settings: coverage_test.settings (from environment variable)
rootdir: /Users/emma/Dropbox/Projects/coverage_test/coverage_test, inifile:
plugins: cov-2.2.1, django-2.9.1
collected 1 items
tests.py .
------------------------ coverage: platform darwin, python 3.5.1-final-0 -------------------------
Name Stmts Miss Cover
-------------------------------------------------------
coverage_test/__init__.py 0 0 100%
coverage_test/settings.py 20 0 100%
coverage_test/templates/test.html 1 0 100%
coverage_test/urls.py 3 3 0%
coverage_test/wsgi.py 4 4 0%
-------------------------------------------------------
TOTAL 28 7 75%
==================================== 1 passed in 0.23 seconds ====================================
Presumably, the check in fdb0892 is working properly, and killing the plugin; it's just not getting to stderr or stopping pytest.
The original issue is probably fixed by this patch. There might not be anything for the plugin to do about my problem, since it's probably something in pytest or pytest-cov. Or there might a configuration somewhere. I haven't spent much time hunting since the actual plugin is working just fine for me.
@emmalemma thanks for the detailed steps! I'm looking into what is hiding the exception. BTW: echo "[run]\nplugins=django_coverage_plugin" > .coveragerc
put a backslash-n into the rc file, but once I fixed that, the reproduction was easy. :)
Hah, whoops! I only use zsh, forgot that would happen in bash. I guess I need to use printf
instead :)
Thanks for taking the time to look into this, and especially thanks for your work on the plugin in the first place.
I was getting the following error:
django_coverage_plugin.plugin.DjangoTemplatePluginException: Template debugging must be enabled in settings.
I thought I had the setting enabled, but here's the thing:
The TEMPLATE_DEBUG setting is deprecated in Django 1.8. The new way to do it is described here: https://stackoverflow.com/a/32446043/2319697
DEBUG = True
TEMPLATES = [
{
...
'OPTIONS': {
'debug': DEBUG,
},
},
]
Error is gone 🎉