Using Django with Jinja2 and TEMPLATE_DEBUG=True

45 views
Skip to first unread message

Rick van Hattem

unread,
Jan 6, 2010, 1:54:46 PM1/6/10
to django-d...@googlegroups.com
Hi,

Maybe this question has already been asked, but I am wondering why Jinja2
compatibility can't be fixed in a clean way. Currently the code assumes that
if an exception has a "source" attribute that it's a Django exception and can
be processed as such. (the code:
http://code.djangoproject.com/browser/django/trunk/django/views/debug.py#L87 )

However, if all template exceptions have the same base exception (as they
logically should) wouldn't it automatically work if you simply test for the
exception?

There has been a previous ticket with a hacky solution:
http://code.djangoproject.com/ticket/10216

But I feel that testing for specific exceptions (as any try/except should)
would make the code cleaner and fix this problem. Assuming that any exception
with a source attribute can be processed as the expected Django exception is
simply wrong.

Right now you can break the entire debugging system by simply raising an
exception like this:
class MyException(Exception):
source = 'Breaking the Django template debugger'

~Rick

signature.asc

Russell Keith-Magee

unread,
Jan 6, 2010, 7:35:50 PM1/6/10
to django-d...@googlegroups.com
On Thu, Jan 7, 2010 at 2:54 AM, Rick van Hattem <Rick.va...@fawo.nl> wrote:
> Hi,
>
> Maybe this question has already been asked, but I am wondering why Jinja2
> compatibility can't be fixed in a clean way. Currently the code assumes that
> if an exception has a "source" attribute that it's a Django exception and can
> be processed as such. (the code:
> http://code.djangoproject.com/browser/django/trunk/django/views/debug.py#L87 )

There is an important difference between "can't" and "hasn't". The
Django core's development priority is Django, and Django is a
'batteries included' framework. As a result, our development priority
is in making Django's template language better.

We are open to making any changes that make it easier to plug in
different template engines or ORMs (or any other external component).
We (the core) just haven't spent a lot of development time trying to
reach that particular goal.

If someone in the community wants to pursue this goal, they are
welcome to do so. Propose a patch, and as long as it doesn't
fundamentally compromise the design of Django, it stands a good chance
of getting into trunk.

> However, if all template exceptions have the same base exception (as they
> logically should) wouldn't it automatically work if you simply test for the
> exception?

No, it wouldn't (at least, not completely). Jinja wouldn't extend
Django's TemplateSyntaxError class, so using the approach you
describe, Jinja's TemplateSyntaxErrors wouldn't break the debug page,
but you wouldn't get good template error feedback either.

> There has been a previous ticket with a hacky solution:
> http://code.djangoproject.com/ticket/10216
>
> But I feel that testing for specific exceptions (as any try/except should)
> would make the code cleaner and fix this problem. Assuming that any exception
> with a source attribute can be processed as the expected Django exception is
> simply wrong.

I disagree. Checking for capabilities rather than types is the
cornerstone of duck typing. In this case, Jinja's TemplateSyntaxError
doesn't quack in quite the same way as Django's duck. I can see three
possible solutions:

1) The capability check isn't rigorous enough. Modify the capability
check to make it more specific.
2) Push the problem back to Jinja. As Malcolm's comment on #10216
notes, Django has a protocol for template errors and doesn't make any
claim to having Jinja compatibility. If Jinja makes claims to Django
compatibility but doesn't adhere to that protocol, then it's up to
Jinja to fix the problem.
3) Come up with a new capability that can be used instead.

From a cursory inspection, I'm not sure there is much we can do with
(1) - there isn't a lot of detail on Exception that can be used for a
capability check, and the only attribute that is actually needed is
'source' (albeit in a particular format that evidently Jinja doesn't
use).

(2) isn't Django's problem to fix.

(3) Seems like the most promising option. For example, most of the
call to ExceptionReporter .get_template_exception_info() could be
deferred to the exception itself. If we refactored that code into a
method on the exception itself, we could use that method as the
capability that we check for. It would be less ambiguous (not many
exceptions would have a 'get_template_exception_info' method), and it
would allow *any* exception (template or otherwise) to raise an
embedded exception that provided template details on the technical 500
page.

However, as I said originally - the existing setup works for Django at
present. If you want to improve support for Jinja... patches are
accepted :-)

Yours
Russ Magee %-)

Michael Elsdörfer

unread,
Jan 7, 2010, 6:39:17 AM1/7/10
to Django developers
> No, it wouldn't (at least, not completely). Jinja wouldn't extend
> Django's TemplateSyntaxError class, so using the approach you
> describe, Jinja's TemplateSyntaxErrors wouldn't break the debug page,
> but you wouldn't get good template error feedback either.

FWIW, I don't think that's an issue; Jinja 2 has it's own debug mode
it which it rewrites an exception's stack trace with line numbers from
the raw template, so I don't think TEMPLATE_DEBUG would give any
additional benefit anyway.

Michael

Rick van Hattem

unread,
Jan 8, 2010, 10:21:57 AM1/8/10
to django-d...@googlegroups.com, Russell Keith-Magee
On Thursday 07 January 2010 01:35:50 Russell Keith-Magee wrote:
> From a cursory inspection, I'm not sure there is much we can do with
> (1) - there isn't a lot of detail on Exception that can be used for a
> capability check, and the only attribute that is actually needed is
> 'source' (albeit in a particular format that evidently Jinja doesn't
> use).

Agreed, that is why the patch in the referenced ticket was denied.
http://code.djangoproject.com/attachment/ticket/10216/10216.diff

> (2) isn't Django's problem to fix.

If it would just be a problem with Jinja than I would agree. However, Django
breaks on every Exception with a source attribute that doesn't follow the
Django style completely.

> (3) Seems like the most promising option. For example, most of the
> call to ExceptionReporter .get_template_exception_info() could be
> deferred to the exception itself. If we refactored that code into a
> method on the exception itself, we could use that method as the
> capability that we check for. It would be less ambiguous (not many
> exceptions would have a 'get_template_exception_info' method), and it
> would allow *any* exception (template or otherwise) to raise an
> embedded exception that provided template details on the technical 500
> page.

Agreed, that would probably be the best solution. Although I do think that
duck typing for catching exceptions is generally not the way to go.

Exceptions should always be caught explicitly

> However, as I said originally - the existing setup works for Django at
> present. If you want to improve support for Jinja... patches are
> accepted :-)

As soon as I get back to the latest trunk release (I'm currently working on a
revision that's about a year old) I will write a patch for this problem.
Patching the old release and merging it with the current changes looks like
it is going to be quite a tedious process.

~Rick

signature.asc
Reply all
Reply to author
Forward
0 new messages