Skip to content

Commit 805e258

Browse files
blueyedtimb07
authored andcommitted
Improve --fail-on-template-vars: use origin if available
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.
1 parent a1601ed commit 805e258

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

pytest_django/plugin.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -529,10 +529,24 @@ def __contains__(self, key):
529529
"""There is a test for '%s' in TEMPLATE_STRING_IF_INVALID."""
530530
return key == '%s'
531531

532-
def _get_template(self):
532+
def _get_origin(self):
533+
stack = inspect.stack()
534+
535+
# Try to use topmost `self.origin` first (Django 1.9+, and with
536+
# TEMPLATE_DEBUG)..
537+
for f in stack[2:]:
538+
func = f[3]
539+
if func == 'render':
540+
frame = f[0]
541+
try:
542+
origin = frame.f_locals['self'].origin
543+
except (AttributeError, KeyError):
544+
continue
545+
if origin is not None:
546+
return origin
547+
533548
from django.template import Template
534549

535-
stack = inspect.stack()
536550
# finding the ``render`` needle in the stack
537551
frame = reduce(
538552
lambda x, y: y[3] == 'render' and 'base.py' in y[1] and y or x,
@@ -548,14 +562,14 @@ def _get_template(self):
548562
# ``django.template.base.Template``
549563
template = f_locals['self']
550564
if isinstance(template, Template):
551-
return template
565+
return template.name
552566

553567
def __mod__(self, var):
554568
"""Handle TEMPLATE_STRING_IF_INVALID % var."""
555-
template = self._get_template()
556-
if template:
569+
origin = self._get_origin()
570+
if origin:
557571
msg = "Undefined template variable '%s' in '%s'" % (
558-
var, template.name)
572+
var, origin)
559573
else:
560574
msg = "Undefined template variable '%s'" % var
561575
if self.fail:

tests/test_environment.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,10 @@ def invalid_template(request):
7373
""", 'views.py')
7474
django_testdir.create_app_file(
7575
"<div>{{ invalid_var }}</div>",
76+
'templates/invalid_template_base.html'
77+
)
78+
django_testdir.create_app_file(
79+
"{% extends 'invalid_template_base.html' %}",
7680
'templates/invalid_template.html'
7781
)
7882
django_testdir.create_test_module('''
@@ -86,9 +90,14 @@ def test_ignore(client):
8690
client.get('/invalid_template/')
8791
''')
8892
result = django_testdir.runpytest_subprocess('-s', '--fail-on-template-vars')
93+
94+
if get_django_version() >= (1, 9):
95+
origin = "'*/tpkg/app/templates/invalid_template_base.html'"
96+
else:
97+
origin = "'invalid_template.html'"
8998
result.stdout.fnmatch_lines_random([
9099
"tpkg/test_the_test.py F.",
91-
"Undefined template variable 'invalid_var' in 'invalid_template.html'",
100+
"Undefined template variable 'invalid_var' in {}".format(origin)
92101
])
93102

94103

0 commit comments

Comments
 (0)