Skip to content
42 changes: 20 additions & 22 deletions django_coverage_plugin/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

import django
import django.template
from django.core.exceptions import ImproperlyConfigured
from django.template.base import (
Lexer, TextNode, NodeList, Template,
TOKEN_BLOCK, TOKEN_MAPPING, TOKEN_TEXT, TOKEN_VAR,
Expand Down Expand Up @@ -43,28 +42,24 @@ def check_debug():
to do its work. Check that the setting is correct, and raise an exception
if it is not.

Returns True if the debug check was performed, False otherwise
"""
# The settings for templates changed in Django 1.8 from TEMPLATE_DEBUG to
# TEMPLATES[..]['debug']. Django 1.9 tolerated both forms, 1.10 insists on
# the new form. Don't try to be version-specific here. If the new
# settings exist, use them, otherwise use the old.

from django.conf import settings

try:
templates = getattr(settings, 'TEMPLATES', [])
except ImproperlyConfigured:
# Maybe there are no settings at all. We are fine with this. Our
# code will need settings, but if this program we're in runs without
# settings, then it must be that it never uses templates, and our code
# will never try to use the settings anyway.
return

if templates:
for template_settings in templates:
if template_settings['BACKEND'] != 'django.template.backends.django.DjangoTemplates':
raise DjangoTemplatePluginException("Can't use non-Django templates.")
if not template_settings.get('OPTIONS', {}).get('debug', False):
if not settings.configured:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's how we defer check_debug until settings are configured. Note that we can't really encounter the case where we'd be tracing a template until after settings have been configured because the template can't be run without configured settings.

return False

if django.VERSION >= (1, 8):
# Django 1.8+ handles both old and new-style settings and converts them
# into template engines, so we don't need to depend on settings values
# directly and can look at the resulting configured objects
for engine in django.template.engines.all():
if not isinstance(engine, django.template.backends.django.DjangoTemplates):
raise DjangoTemplatePluginException(
"Can't use non-Django templates. Found '%s': %s" %
(engine.name, engine)
)
if not engine.engine.debug:
raise DjangoTemplatePluginException(
"Template debugging must be enabled in settings."
)
Expand All @@ -75,6 +70,8 @@ def check_debug():
"Template debugging must be enabled in settings."
)

return True


if django.VERSION >= (1, 9):
# Since we are grabbing at internal details, we have to adapt as they
Expand Down Expand Up @@ -151,8 +148,9 @@ def sys_info(self):
def file_tracer(self, filename):
if filename.startswith(self.django_template_dir):
if not self.debug_checked:
check_debug()
self.debug_checked = True
# Keep calling check_debug until it returns True, which it
# will only do after settings have been configured
self.debug_checked = check_debug()

return self
return None
Expand Down
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def index(request):
"""A bogus view to use in the urls below."""
pass


urlpatterns = [
url(r'^home$', index, name='index'),
]
1 change: 1 addition & 0 deletions tests/plugin_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ def test_settings():

return the_settings


settings.configure(**test_settings())

if hasattr(django, "setup"):
Expand Down