Skip to content

Commit

Permalink
Improve --fail-on-template-vars: use origin if available
Browse files Browse the repository at this point in the history
This will be there with Django 1.9+ always, and in case of
`settings.TEMPLATE_DEBUG` before.
It stops going up to the Template, but uses the nearest location (which
is required when extending templates).

Using `django.template.base.Origin` also gives the benefit of having the
full/absolute path.
  • Loading branch information
blueyed authored and dulacp committed Dec 2, 2017
1 parent 78250f2 commit 7896631
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 7 deletions.
26 changes: 20 additions & 6 deletions pytest_django/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,24 @@ def __contains__(self, key):
"""There is a test for '%s' in TEMPLATE_STRING_IF_INVALID."""
return key == '%s'

def _get_template(self):
def _get_origin(self):
stack = inspect.stack()

# Try to use topmost `self.origin` first (Django 1.9+, and with
# TEMPLATE_DEBUG)..
for f in stack[2:]:
func = f[3]
if func == 'render':
frame = f[0]
try:
origin = frame.f_locals['self'].origin
except (AttributeError, KeyError):
continue
if origin is not None:
return origin

from django.template import Template

stack = inspect.stack()
# finding the ``render`` needle in the stack
frame = reduce(
lambda x, y: y[3] == 'render' and 'base.py' in y[1] and y or x,
Expand All @@ -507,14 +521,14 @@ def _get_template(self):
# ``django.template.base.Template``
template = f_locals['self']
if isinstance(template, Template):
return template
return template.name

def __mod__(self, var):
"""Handle TEMPLATE_STRING_IF_INVALID % var."""
template = self._get_template()
if template:
origin = self._get_origin()
if origin:
msg = "Undefined template variable '%s' in '%s'" % (
var, template.name)
var, origin)
else:
msg = "Undefined template variable '%s'" % var
if self.fail:
Expand Down
11 changes: 10 additions & 1 deletion tests/test_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ def invalid_template(request):
""", 'views.py')
django_testdir.create_app_file(
"<div>{{ invalid_var }}</div>",
'templates/invalid_template_base.html'
)
django_testdir.create_app_file(
"{% extends 'invalid_template_base.html' %}",
'templates/invalid_template.html'
)
django_testdir.create_test_module('''
Expand All @@ -86,9 +90,14 @@ def test_ignore(client):
client.get('/invalid_template/')
''')
result = django_testdir.runpytest_subprocess('-s', '--fail-on-template-vars')

if get_django_version() >= (1, 9):
origin = "'*/tpkg/app/templates/invalid_template_base.html'"
else:
origin = "'invalid_template.html'"
result.stdout.fnmatch_lines_random([
"tpkg/test_the_test.py F.",
"Undefined template variable 'invalid_var' in 'invalid_template.html'",
"Undefined template variable 'invalid_var' in {}".format(origin)
])


Expand Down

0 comments on commit 7896631

Please sign in to comment.