Skip to content

Commit 7896631

Browse files
blueyeddulacp
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 78250f2 commit 7896631

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
@@ -488,10 +488,24 @@ def __contains__(self, key):
488488
"""There is a test for '%s' in TEMPLATE_STRING_IF_INVALID."""
489489
return key == '%s'
490490

491-
def _get_template(self):
491+
def _get_origin(self):
492+
stack = inspect.stack()
493+
494+
# Try to use topmost `self.origin` first (Django 1.9+, and with
495+
# TEMPLATE_DEBUG)..
496+
for f in stack[2:]:
497+
func = f[3]
498+
if func == 'render':
499+
frame = f[0]
500+
try:
501+
origin = frame.f_locals['self'].origin
502+
except (AttributeError, KeyError):
503+
continue
504+
if origin is not None:
505+
return origin
506+
492507
from django.template import Template
493508

494-
stack = inspect.stack()
495509
# finding the ``render`` needle in the stack
496510
frame = reduce(
497511
lambda x, y: y[3] == 'render' and 'base.py' in y[1] and y or x,
@@ -507,14 +521,14 @@ def _get_template(self):
507521
# ``django.template.base.Template``
508522
template = f_locals['self']
509523
if isinstance(template, Template):
510-
return template
524+
return template.name
511525

512526
def __mod__(self, var):
513527
"""Handle TEMPLATE_STRING_IF_INVALID % var."""
514-
template = self._get_template()
515-
if template:
528+
origin = self._get_origin()
529+
if origin:
516530
msg = "Undefined template variable '%s' in '%s'" % (
517-
var, template.name)
531+
var, origin)
518532
else:
519533
msg = "Undefined template variable '%s'" % var
520534
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)