Opened 18 years ago
Closed 18 years ago
#3441 closed (fixed)
django.template.VariableDoesNotExist.__init__ prototype forces work to be done up front that is typically thrown away
Reported by: | (removed) | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | Template system | Version: | dev |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Design decision needed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | yes | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Kind of a cornercase, but VariableDoesNotExist derives from Exception, overriding nothing- meaning the str/repr for it must be done up front. Thus django.template.resolve_variable raises it via
raise VariableDoesNotExist, "Failed lookup for key [%s] in %r" % (bits[0], current)
So... it's effectively raising VariableDoesNotExist(msg). Problem here is that a rather large amount of code just catches the exception, and substitutes a different value, TEMPLATE_STRING_IF_INVALID for example- in other words, they don't even *care* about the msg, the exception is just a passing mechanism. Thus the msg creation is pure overhead to most codeblocks I've found in django.
Said overhead can add up; a context level lookup ( {{ foo }} for example), raising VariableDoesNotExist results in repr(context), repr'ing all mappings in context- if say your base template is just checking for a var, if so, outputing a queryset, else not outputting it, the current code forces a repr on context, in other words forcing the query to be executed.
Which is fairly daft, if pretty much all code just throws out the exception, substituting a different value in.
Attached is a patch changing VariableDoesNotExist's init to (self, msg, params=()); via that, can delay the actual msg creation until it's required, making catching the exception just to substitute a different value far cheaper.
Within the code, only resolve_variable throws the exception- google code search, nobody else is throwing it, thus it looks pretty safe to change the init to delay the cost.
Alternative, just derive NewStyleVariableDoesNotExist from VariableDoesNotExist, and have resolve_variable throw that; either way, it's work being done that isn't needed so should be tweaked.
Attachments (1)
Change History (3)
by , 18 years ago
Attachment: | VariableDoesNotExist.patch added |
---|
comment:1 by , 18 years ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Design decision needed |
VariableDoesNotExist.init refactoring.