Ticket #3453: resolve_variable-correct-bitrot.patch
| File resolve_variable-correct-bitrot.patch, 19.5 kB (added by Brian Harring <ferringb@gmail.com>, 1 year ago) |
|---|
-
django/contrib/admin/templatetags/admin_modify.py
old new 72 72 default = None 73 73 74 74 def __init__(self, bound_field_var): 75 self.bound_field_var = bound_field_var75 self.bound_field_var = template.Variable(bound_field_var) 76 76 77 77 def get_nodelist(cls, klass): 78 78 if klass not in cls.nodelists: … … 96 96 get_nodelist = classmethod(get_nodelist) 97 97 98 98 def render(self, context): 99 bound_field = template.resolve_variable(self.bound_field_var,context)99 bound_field = self.bound_field_var.resolve(context) 100 100 101 101 context.push() 102 102 context['bound_field'] = bound_field … … 156 156 157 157 class EditInlineNode(template.Node): 158 158 def __init__(self, rel_var): 159 self.rel_var = rel_var159 self.rel_var = template.Variable(rel_var) 160 160 161 161 def render(self, context): 162 relation = template.resolve_variable(self.rel_var,context)162 relation = self.rel_var.resolve(context) 163 163 context.push() 164 164 if relation.field.rel.edit_inline == models.TABULAR: 165 165 bound_related_object_class = TabularBoundRelatedObject -
django/contrib/comments/templatetags/comments.py
old new 18 18 ratings_optional=False, ratings_required=False, rating_options='', 19 19 is_public=True): 20 20 self.content_type = content_type 21 if obj_id_lookup is not None: 22 obj_id_lookup = template.Variable 21 23 self.obj_id_lookup_var, self.obj_id, self.free = obj_id_lookup_var, obj_id, free 22 24 self.photos_optional, self.photos_required = photos_optional, photos_required 23 25 self.ratings_optional, self.ratings_required = ratings_optional, ratings_required … … 31 33 context.push() 32 34 if self.obj_id_lookup_var is not None: 33 35 try: 34 self.obj_id = template.resolve_variable(self.obj_id_lookup_var,context)36 self.obj_id = self.obj_id_lookup_var.resolve(context) 35 37 except template.VariableDoesNotExist: 36 38 return '' 37 39 # Validate that this object ID is valid for this content-type. … … 74 76 class CommentCountNode(template.Node): 75 77 def __init__(self, package, module, context_var_name, obj_id, var_name, free): 76 78 self.package, self.module = package, module 79 if context_var_name is not None: 80 context_var_name = template.Variable(context_var_name) 77 81 self.context_var_name, self.obj_id = context_var_name, obj_id 78 82 self.var_name, self.free = var_name, free 79 83 … … 81 85 from django.conf import settings 82 86 manager = self.free and FreeComment.objects or Comment.objects 83 87 if self.context_var_name is not None: 84 self.obj_id = template.resolve_variable(self.context_var_name,context)88 self.obj_id = self.context_var_name.resolve(context) 85 89 comment_count = manager.filter(object_id__exact=self.obj_id, 86 90 content_type__app_label__exact=self.package, 87 91 content_type__model__exact=self.module, site__id__exact=settings.SITE_ID).count() … … 91 95 class CommentListNode(template.Node): 92 96 def __init__(self, package, module, context_var_name, obj_id, var_name, free, ordering, extra_kwargs=None): 93 97 self.package, self.module = package, module 98 if context_var_name is not None: 99 context_var_name = template.Variable(context_var_name) 94 100 self.context_var_name, self.obj_id = context_var_name, obj_id 95 101 self.var_name, self.free = var_name, free 96 102 self.ordering = ordering … … 101 107 get_list_function = self.free and FreeComment.objects.filter or Comment.objects.get_list_with_karma 102 108 if self.context_var_name is not None: 103 109 try: 104 self.obj_id = template.resolve_variable(self.context_var_name,context)110 self.obj_id = self.context_var_name.resolve(context) 105 111 except template.VariableDoesNotExist: 106 112 return '' 107 113 kwargs = { -
django/template/__init__.py
old new 93 93 tag_re = re.compile('(%s.*?%s|%s.*?%s|%s.*?%s)' % (re.escape(BLOCK_TAG_START), re.escape(BLOCK_TAG_END), 94 94 re.escape(VARIABLE_TAG_START), re.escape(VARIABLE_TAG_END), 95 95 re.escape(COMMENT_TAG_START), re.escape(COMMENT_TAG_END))) 96 # matches if the string is valid number97 number_re = re.compile(r'[-+]?(\d+|\d*\.\d+)$')98 96 99 97 # global dictionary of libraries that have been loaded using get_library 100 98 libraries = {} … … 568 566 elif constant_arg is not None: 569 567 args.append((False, constant_arg.replace(r'\"', '"'))) 570 568 elif var_arg: 571 args.append((True, var_arg))569 args.append((True, Variable(var_arg))) 572 570 filter_func = parser.find_filter(filter_name) 573 571 self.args_check(filter_name,filter_func, args) 574 572 filters.append( (filter_func,args)) 575 573 upto = match.end() 576 574 if upto != len(token): 577 575 raise TemplateSyntaxError, "Could not parse the remainder: '%s' from '%s'" % (token[upto:], token) 578 self.var, self.filters = var, filters 576 self.filters = filters 577 self.var = Variable(var) 579 578 580 579 def resolve(self, context, ignore_failures=False): 581 580 try: 582 obj = resolve_variable(self.var,context)581 obj = self.var.resolve(context) 583 582 except VariableDoesNotExist: 584 583 if ignore_failures: 585 584 obj = None … … 599 598 if not lookup: 600 599 arg_vals.append(arg) 601 600 else: 602 arg_vals.append( resolve_variable(arg,context))601 arg_vals.append(arg.resolve(context)) 603 602 obj = func(obj, *arg_vals) 604 603 return obj 605 604 … … 658 657 659 658 (The example assumes VARIABLE_ATTRIBUTE_SEPARATOR is '.') 660 659 """ 661 if number_re.match(path): 662 number_type = '.' in path and float or int 663 current = number_type(path) 664 elif path[0] in ('"', "'") and path[0] == path[-1]: 665 current = path[1:-1] 666 else: 660 return Variable(path).resolve(context) 661 662 class LiteralVariable(object): 663 664 def __init__(self, val): 665 self.val = val 666 667 def resolve(self, context): 668 return self.val 669 670 def __str__(self): 671 return self.val 672 673 def Variable(val): 674 try: 675 # note we're not catching OverflowError here; point of debate on how best to handle that... 676 current = float(val) 677 if '.' not in val: 678 # downside to this approach is that 1e07 becomes an int; float may be preferable still. 679 current = int(current) 680 elif val[-1] == '.': 681 # 2. is invalid 682 raise ValueError 683 return LiteralVariable(current) 684 except ValueError: 685 pass 686 if val[0] in "\"'" and val[0] == val[-1]: 687 return LiteralVariable(val[1:-1]) 688 return ChainedLookupVariable(val) 689 690 class ChainedLookupVariable(object): 691 692 def __init__(self, val): 693 self.lookups = tuple(val.split(VARIABLE_ATTRIBUTE_SEPARATOR)) 694 695 def resolve(self, context): 667 696 current = context 668 bits = path.split(VARIABLE_ATTRIBUTE_SEPARATOR) 669 while bits: 697 for bit in self.lookups: 670 698 try: # dictionary lookup 671 current = current[bit s[0]]699 current = current[bit] 672 700 except (TypeError, AttributeError, KeyError): 673 701 try: # attribute lookup 674 current = getattr(current, bit s[0])702 current = getattr(current, bit) 675 703 if callable(current): 676 704 if getattr(current, 'alters_data', False): 677 705 current = settings.TEMPLATE_STRING_IF_INVALID … … 689 717 raise 690 718 except (TypeError, AttributeError): 691 719 try: # list-index lookup 692 current = current[int(bit s[0])]720 current = current[int(bit)] 693 721 except (IndexError, # list index out of range 694 722 ValueError, # invalid literal for int() 695 KeyError, # current is a dict without `int(bit s[0])` key723 KeyError, # current is a dict without `int(bit)` key 696 724 TypeError, # unsubscriptable object 697 725 ): 698 raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bit s[0], current)) # missing attribute726 raise VariableDoesNotExist("Failed lookup for key [%s] in %r", (bit, current)) # missing attribute 699 727 except Exception, e: 700 728 if getattr(e, 'silent_variable_failure', False): 701 729 current = settings.TEMPLATE_STRING_IF_INVALID 702 730 else: 703 731 raise 704 del bits[0] 705 if isinstance(current, (basestring, Promise)): 706 try: 707 current = force_unicode(current) 708 except UnicodeDecodeError: 709 # Failing to convert to unicode can happen sometimes (e.g. debug 710 # tracebacks). So we allow it in this particular instance. 711 pass 712 return current 732 733 if isinstance(current, (basestring, Promise)): 734 try: 735 current = force_unicode(current) 736 except UnicodeDecodeError: 737 # Failing to convert to unicode can happen sometimes (e.g. debug 738 # tracebacks). So we allow it in this particular instance. 739 pass 740 return current 741 742 def __str__(self): 743 return VARIABLE_ATTRIBUTE_SEPARATOR.join(self.lookups) 713 744 714 745 class Node(object): 715 746 def render(self, context): … … 865 896 866 897 class SimpleNode(Node): 867 898 def __init__(self, vars_to_resolve): 868 self.vars_to_resolve = vars_to_resolve899 self.vars_to_resolve = map(Variable, vars_to_resolve) 869 900 870 901 def render(self, context): 871 resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] 872 return func(*resolved_vars) 902 return func(*[var.resolve(context) for var in self.vars_to_resolve]) 873 903 874 904 compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode) 875 905 compile_func.__doc__ = func.__doc__ … … 887 917 888 918 class InclusionNode(Node): 889 919 def __init__(self, vars_to_resolve): 890 self.vars_to_resolve = vars_to_resolve920 self.vars_to_resolve = map(Variable, vars_to_resolve) 891 921 892 922 def render(self, context): 893 resolved_vars = [ resolve_variable(var,context) for var in self.vars_to_resolve]923 resolved_vars = [var.resolve(context) for var in self.vars_to_resolve] 894 924 if takes_context: 895 925 args = [context] + resolved_vars 896 926 else: -
django/template/defaultfilters.py
old new 1 1 "Default variable filters" 2 2 3 from django.template import resolve_variable, Library3 from django.template import Variable, Library 4 4 from django.conf import settings 5 5 from django.utils.translation import ugettext, ungettext 6 6 from django.utils.encoding import force_unicode, smart_str, iri_to_uri … … 290 290 Takes a list of dicts, returns that list sorted by the property given in 291 291 the argument. 292 292 """ 293 decorated = [(resolve_variable(u'var.' + arg, {u'var' : item}), item) for item in value] 293 var_resolve = Variable(arg).resolve 294 decorated = [(var_resolve(item), item) for item in value] 294 295 decorated.sort() 295 296 return [item[1] for item in decorated] 296 297 … … 299 300 Takes a list of dicts, returns that list sorted in reverse order by the 300 301 property given in the argument. 301 302 """ 302 decorated = [(resolve_variable(u'var.' + arg, {u'var' : item}), item) for item in value] 303 var_resolve = Variable(arg).resolve 304 decorated = [(var_resolve(item), item) for item in value] 303 305 decorated.sort() 304 306 decorated.reverse() 305 307 return [item[1] for item in decorated] -
django/template/defaulttags.py
old new 1 1 "Default tags used by the template system, available to all templates." 2 2 3 from django.template import Node, NodeList, Template, Context, resolve_variable3 from django.template import Node, NodeList, Template, Context, Variable 4 4 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END, SINGLE_BRACE_START, SINGLE_BRACE_END, COMMENT_TAG_START, COMMENT_TAG_END 5 5 from django.template import get_library, Library, InvalidTemplateLibrary 6 6 from django.conf import settings … … 56 56 57 57 class FirstOfNode(Node): 58 58 def __init__(self, vars): 59 self.vars = vars59 self.vars = map(Variable, vars) 60 60 61 61 def render(self, context): 62 62 for var in self.vars: 63 63 try: 64 value = resolve_variable(var,context)64 value = var.resolve(context) 65 65 except VariableDoesNotExist: 66 66 continue 67 67 if value: … … 146 146 def __init__(self, nodelist, *varlist): 147 147 self.nodelist = nodelist 148 148 self._last_seen = None 149 self._varlist = varlist149 self._varlist = map(Variable, varlist) 150 150 151 151 def render(self, context): 152 152 if 'forloop' in context and context['forloop']['first']: … … 155 155 if self._varlist: 156 156 # Consider multiple parameters. 157 157 # This automatically behaves like a OR evaluation of the multiple variables. 158 compare_to = [ resolve_variable(var,context) for var in self._varlist]158 compare_to = [var.resolve(context) for var in self._varlist] 159 159 else: 160 160 compare_to = self.nodelist.render(context) 161 161 except VariableDoesNotExist: … … 174 174 175 175 class IfEqualNode(Node): 176 176 def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): 177 self.var1, self.var2 = var1, var2177 self.var1, self.var2 = Variable(var1), Variable(var2) 178 178 self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false 179 179 self.negate = negate 180 180 … … 183 183 184 184 def render(self, context): 185 185 try: 186 val1 = resolve_variable(self.var1,context)186 val1 = self.var1.resolve(context) 187 187 except VariableDoesNotExist: 188 188 val1 = None 189 189 try: 190 val2 = resolve_variable(self.var2,context)190 val2 = self.var2.resolve(context) 191 191 except VariableDoesNotExist: 192 192 val2 = None 193 193 if (self.negate and val1 != val2) or (not self.negate and val1 == val2): -
django/template/loader_tags.py
old new 1 from django.template import TemplateSyntaxError, TemplateDoesNotExist, resolve_variable1 from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable 2 2 from django.template import Library, Node 3 3 from django.template.loader import get_template, get_template_from_string, find_template_source 4 4 from django.conf import settings … … 99 99 100 100 class IncludeNode(Node): 101 101 def __init__(self, template_name): 102 self.template_name = template_name102 self.template_name = Variable(template_name) 103 103 104 104 def render(self, context): 105 105 try: 106 template_name = resolve_variable(self.template_name,context)106 template_name = self.template_name.resolve(context) 107 107 t = get_template(template_name) 108 108 return t.render(context) 109 109 except TemplateSyntaxError, e: -
django/templatetags/i18n.py
old new 1 from django.template import Node, resolve_variable1 from django.template import Node, Variable 2 2 from django.template import TemplateSyntaxError, TokenParser, Library 3 3 from django.template import TOKEN_TEXT, TOKEN_VAR 4 4 from django.utils import translation … … 32 32 33 33 class TranslateNode(Node): 34 34 def __init__(self, value, noop): 35 self.value = value35 self.value = Variable(value) 36 36 self.noop = noop 37 37 38 38 def render(self, context): 39 value = resolve_variable(self.value,context)39 value = self.value.resolve(context) 40 40 if self.noop: 41 41 return value 42 42 else: -
docs/templates_python.txt
old new 864 864 865 865 You also have to change the renderer to retrieve the actual contents of the 866 866 ``date_updated`` property of the ``blog_entry`` object. This can be 867 accomplished by using the `` resolve_variable()`` function in868 ``django.template``. You pass ``resolve_variable()`` the variable name andthe869 current context , available in the ``render`` method::867 accomplished by using the ``Variable`` class in ``django.template``. 868 You pass ``Variable`` the variable name, and invoke the ``resolve`` method with the 869 current context:: 870 870 871 871 from django import template 872 from django.template import resolve_variable872 from django.template import Variable 873 873 import datetime 874 874 class FormatTimeNode(template.Node): 875 875 def __init__(self, date_to_be_formatted, format_string): 876 self.date_to_be_formatted = date_to_be_formatted876 self.date_to_be_formatted = Variable(date_to_be_formatted) 877 877 self.format_string = format_string 878 878 879 879 def render(self, context): 880 880 try: 881 actual_date = resolve_variable(self.date_to_be_formatted,context)881 actual_date = self.date_to_be_formatted.resolve(context) 882 882 return actual_date.strftime(self.format_string) 883 883 except template.VariableDoesNotExist: 884 884 return '' 885 885 886 ``re solve_variable`` will try to resolve ``blog_entry.date_updated`` and then887 format it accordingly.886 ``render`` will try to resolve ``blog_entry.date_updated`` via ``Variable.resolve``, 887 and then format it accordingly. 888 888 889 889 .. note:: 890 The `` resolve_variable()`` functionwill throw a ``VariableDoesNotExist``890 The ``Variable.resolve`` method will throw a ``VariableDoesNotExist`` 891 891 exception if it cannot resolve the string passed to it in the current 892 892 context of the page. 893 894 Additionally, ``resolve_variable(arg, context)`` is a function invoking 895 ``Variable(arg).resolve(context)``. The ``Variable`` should be used instead, 896 since ``resolve_variable`` is deprecated. 893 897 894 898 Shortcut for simple tags 895 899 ~~~~~~~~~~~~~~~~~~~~~~~~
