Django

Code

Changeset 6641

Show
Ignore:
Timestamp:
11/03/07 21:05:56 (1 year ago)
Author:
gwilson
Message:

Style and import fixes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/template/defaultfilters.py

    r6399 r6641  
    1 "Default variable filters" 
     1"""Default variable filters.""" 
     2 
     3import re 
     4import random as random_module 
    25 
    36from django.template import Variable, Library 
    47from django.conf import settings 
    58from django.utils.translation import ugettext, ungettext 
    6 from django.utils.encoding import force_unicode, smart_str, iri_to_uri 
    7 import re 
    8 import random as random_module 
     9from django.utils.encoding import force_unicode, iri_to_uri 
    910 
    1011register = Library() 
     
    3738 
    3839def addslashes(value): 
    39     "Adds slashes - useful for passing strings to JavaScript, for example.
     40    """Adds slashes - useful for passing strings to JavaScript, for example.""
    4041    return value.replace('\\', '\\\\').replace('"', '\\"').replace("'", "\\'") 
    4142addslashes = stringfilter(addslashes) 
    4243 
    4344def capfirst(value): 
    44     "Capitalizes the first character of the value
     45    """Capitalizes the first character of the value.""
    4546    return value and value[0].upper() + value[1:] 
    4647capfirst = stringfilter(capfirst) 
    4748 
    4849def fix_ampersands(value): 
    49     "Replaces ampersands with ``&`` entities
     50    """Replaces ampersands with ``&`` entities.""
    5051    from django.utils.html import fix_ampersands 
    5152    return fix_ampersands(value) 
     
    8788 
    8889def iriencode(value): 
    89     "Escapes an IRI value for use in a URL
     90    """Escapes an IRI value for use in a URL.""
    9091    return force_unicode(iri_to_uri(value)) 
    9192iriencode = stringfilter(iriencode) 
    9293 
    9394def linenumbers(value): 
    94     "Displays text with line numbers
     95    """Displays text with line numbers.""
    9596    from django.utils.html import escape 
    9697    lines = value.split(u'\n') 
    97     # Find the maximum width of the line count, for use with zero padding string format command 
     98    # Find the maximum width of the line count, for use with zero padding 
     99    # string format command. 
    98100    width = unicode(len(unicode(len(lines)))) 
    99101    for i, line in enumerate(lines): 
     
    103105 
    104106def lower(value): 
    105     "Converts a string into all lowercase
     107    """Converts a string into all lowercase.""
    106108    return value.lower() 
    107109lower = stringfilter(lower) 
     
    109111def make_list(value): 
    110112    """ 
    111     Returns the value turned into a list. For an integer, it's a list of 
    112     digits. For a string, it's a list of characters. 
     113    Returns the value turned into a list. 
     114 
     115    For an integer, it's a list of digits. 
     116    For a string, it's a list of characters. 
    113117    """ 
    114118    return list(value) 
     
    117121def slugify(value): 
    118122    """ 
    119     Normalizes string, converts to lowercase, removes non-alpha chars and 
    120     converts spaces to hyphens. 
     123    Normalizes string, converts to lowercase, removes non-alpha characters, 
     124    and converts spaces to hyphens. 
    121125    """ 
    122126    import unicodedata 
     
    128132def stringformat(value, arg): 
    129133    """ 
    130     Formats the variable according to the argument, a string formatting specifier. 
     134    Formats the variable according to the arg, a string formatting specifier. 
     135 
    131136    This specifier uses Python string formating syntax, with the exception that 
    132137    the leading "%" is dropped. 
     
    141146 
    142147def title(value): 
    143     "Converts a string into titlecase
     148    """Converts a string into titlecase.""
    144149    return re.sub("([a-z])'([A-Z])", lambda m: m.group(0).lower(), value.title()) 
    145150title = stringfilter(title) 
     
    147152def truncatewords(value, arg): 
    148153    """ 
    149     Truncates a string after a certain number of words 
    150  
    151     Argument: Number of words to truncate after 
     154    Truncates a string after a certain number of words. 
     155 
     156    Argument: Number of words to truncate after. 
    152157    """ 
    153158    from django.utils.text import truncate_words 
    154159    try: 
    155160        length = int(arg) 
    156     except ValueError: # invalid literal for int() 
     161    except ValueError: # Invalid literal for int(). 
    157162        return value # Fail silently. 
    158163    return truncate_words(value, length) 
     
    161166def truncatewords_html(value, arg): 
    162167    """ 
    163     Truncates HTML after a certain number of words 
    164  
    165     Argument: Number of words to truncate after 
     168    Truncates HTML after a certain number of words. 
     169 
     170    Argument: Number of words to truncate after. 
    166171    """ 
    167172    from django.utils.text import truncate_html_words 
     
    174179 
    175180def upper(value): 
    176     "Converts a string into all uppercase
     181    """Converts a string into all uppercase.""
    177182    return value.upper() 
    178183upper = stringfilter(upper) 
    179184 
    180185def urlencode(value): 
    181     "Escapes a value for use in a URL
     186    """Escapes a value for use in a URL.""
    182187    from django.utils.http import urlquote 
    183188    return urlquote(value) 
     
    185190 
    186191def urlize(value): 
    187     "Converts URLs in plain text into clickable links
     192    """Converts URLs in plain text into clickable links.""
    188193    from django.utils.html import urlize 
    189194    return urlize(value, nofollow=True) 
     
    192197def urlizetrunc(value, limit): 
    193198    """ 
    194     Converts URLs into clickable links, truncating URLs to the given character limit, 
    195     and adding 'rel=nofollow' attribute to discourage spamming. 
     199    Converts URLs into clickable links, truncating URLs to the given character 
     200    limit, and adding 'rel=nofollow' attribute to discourage spamming. 
    196201 
    197202    Argument: Length to truncate URLs to. 
     
    202207 
    203208def wordcount(value): 
    204     "Returns the number of words
     209    """Returns the number of words.""
    205210    return len(value.split()) 
    206211wordcount = stringfilter(wordcount) 
     
    208213def wordwrap(value, arg): 
    209214    """ 
    210     Wraps words at specified line length 
     215    Wraps words at specified line length. 
    211216 
    212217    Argument: number of characters to wrap the text at. 
     
    218223def ljust(value, arg): 
    219224    """ 
    220     Left-aligns the value in a field of a given width 
    221  
    222     Argument: field size 
     225    Left-aligns the value in a field of a given width. 
     226 
     227    Argument: field size. 
    223228    """ 
    224229    return value.ljust(int(arg)) 
     
    227232def rjust(value, arg): 
    228233    """ 
    229     Right-aligns the value in a field of a given width 
    230  
    231     Argument: field size 
     234    Right-aligns the value in a field of a given width. 
     235 
     236    Argument: field size. 
    232237    """ 
    233238    return value.rjust(int(arg)) 
     
    235240 
    236241def center(value, arg): 
    237     "Centers the value in a field of a given width
     242    """Centers the value in a field of a given width.""
    238243    return value.center(int(arg)) 
    239244center = stringfilter(center) 
    240245 
    241246def cut(value, arg): 
    242     "Removes all values of arg from the given string
     247    """Removes all values of arg from the given string.""
    243248    return value.replace(arg, u'') 
    244249cut = stringfilter(cut) 
     
    273278 
    274279def removetags(value, tags): 
    275     "Removes a space separated list of [X]HTML tags from the output
     280    """Removes a space separated list of [X]HTML tags from the output.""
    276281    tags = [re.escape(tag) for tag in tags.split()] 
    277282    tags_re = u'(%s)' % u'|'.join(tags) 
     
    284289 
    285290def striptags(value): 
    286     "Strips all [X]HTML tags
     291    """Strips all [X]HTML tags.""
    287292    from django.utils.html import strip_tags 
    288293    return strip_tags(value) 
     
    315320 
    316321def first(value): 
    317     "Returns the first item in a list
     322    """Returns the first item in a list.""
    318323    try: 
    319324        return value[0] 
     
    322327 
    323328def join(value, arg): 
    324     "Joins a list with a string, like Python's ``str.join(list)``
     329    """Joins a list with a string, like Python's ``str.join(list)``.""
    325330    try: 
    326331        return arg.join(map(force_unicode, value)) 
     
    329334 
    330335def length(value): 
    331     "Returns the length of the value - useful for lists
     336    """Returns the length of the value - useful for lists.""
    332337    return len(value) 
    333338 
    334339def length_is(value, arg): 
    335     "Returns a boolean of whether the value's length is the argument
     340    """Returns a boolean of whether the value's length is the argument.""
    336341    return len(value) == int(arg) 
    337342 
    338343def random(value): 
    339     "Returns a random item from the list
     344    """Returns a random item from the list.""
    340345    return random_module.choice(value) 
    341346 
     
    417422            sublist_item = None 
    418423            if isinstance(title, (list, tuple)): 
    419                 sublist_item = title  
     424                sublist_item = title 
    420425                title = '' 
    421426            elif i < list_length - 1: 
     
    425430                    sublist_item = next_item 
    426431                    # We've processed the next item now too. 
    427                     i += 1  
     432                    i += 1 
    428433            if sublist_item: 
    429434                sublist = _helper(sublist_item, tabs+1) 
     
    434439            i += 1 
    435440        return '\n'.join(output) 
    436     value, converted = convert_old_style_list(value)  
     441    value, converted = convert_old_style_list(value) 
    437442    return _helper(value) 
    438443 
     
    442447 
    443448def add(value, arg): 
    444     "Adds the arg to the value
     449    """Adds the arg to the value.""
    445450    return int(value) + int(arg) 
    446451 
     
    469474 
    470475def date(value, arg=None): 
    471     "Formats a date according to the given format
     476    """Formats a date according to the given format.""
    472477    from django.utils.dateformat import format 
    473478    if not value: 
     
    478483 
    479484def time(value, arg=None): 
    480     "Formats a time according to the given format
     485    """Formats a time according to the given format.""
    481486    from django.utils.dateformat import time_format 
    482487    if value in (None, u''): 
     
    487492 
    488493def timesince(value, arg=None): 
    489     'Formats a date as the time since that date (i.e. "4 days, 6 hours")' 
     494    """Formats a date as the time since that date (i.e. "4 days, 6 hours").""" 
    490495    from django.utils.timesince import timesince 
    491496    if not value: 
     
    496501 
    497502def timeuntil(value, arg=None): 
    498     'Formats a date as the time until that date (i.e. "4 days, 6 hours")' 
     503    """Formats a date as the time until that date (i.e. "4 days, 6 hours").""" 
    499504    from django.utils.timesince import timesince 
    500505    from datetime import datetime 
     
    510515 
    511516def default(value, arg): 
    512     "If value is unavailable, use given default
     517    """If value is unavailable, use given default.""
    513518    return value or arg 
    514519 
    515520def default_if_none(value, arg): 
    516     "If value is None, use given default
     521    """If value is None, use given default.""
    517522    if value is None: 
    518523        return arg 
     
    520525 
    521526def divisibleby(value, arg): 
    522     "Returns true if the value is devisible by the argument
     527    """Returns True if the value is devisible by the argument.""
    523528    return int(value) % int(arg) == 0 
    524529 
     
    545550    try: 
    546551        yes, no, maybe = bits 
    547     except ValueError: # unpack list of wrong size (no "maybe" value provided) 
     552    except ValueError: 
     553        # Unpack list of wrong size (no "maybe" value provided). 
    548554        yes, no, maybe = bits[0], bits[1], bits[1] 
    549555    if value is None: 
     
    559565def filesizeformat(bytes): 
    560566    """ 
    561     Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102 
    562     bytes, etc). 
     567    Formats the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 
     568    102 bytes, etc). 
    563569    """ 
    564570    try: 
     
    592598        if int(value) != 1: 
    593599            return plural_suffix 
    594     except ValueError: # invalid string that's not a number 
     600    except ValueError: # Invalid string that's not a number. 
    595601        pass 
    596     except TypeError: # value isn't a string or a number; maybe it's a list? 
     602    except TypeError: # Value isn't a string or a number; maybe it's a list? 
    597603        try: 
    598604            if len(value) != 1: 
    599605                return plural_suffix 
    600         except TypeError: # len() of unsized object 
     606        except TypeError: # len() of unsized object. 
    601607            pass 
    602608    return singular_suffix 
    603609 
    604610def phone2numeric(value): 
    605     "Takes a phone number and converts it in to its numerical equivalent
     611    """Takes a phone number and converts it in to its numerical equivalent.""
    606612    from django.utils.text import phone2numeric 
    607613    return phone2numeric(value) 
    608614 
    609615def pprint(value): 
    610     "A wrapper around pprint.pprint -- for debugging, really
     616    """A wrapper around pprint.pprint -- for debugging, really.""
    611617    from pprint import pformat 
    612618    try: 
  • django/trunk/django/template/defaulttags.py

    r6636 r6641  
    1 "Default tags used by the template system, available to all templates." 
    2  
     1"""Default tags used by the template system, available to all templates.""" 
     2 
     3import sys 
     4import re 
    35from itertools import cycle as itertools_cycle 
     6try: 
     7    reversed 
     8except NameError: 
     9    from django.utils.itercompat import reversed     # Python 2.3 fallback 
    410 
    511from django.template import Node, NodeList, Template, Context, Variable 
     
    915from django.utils.encoding import smart_str, smart_unicode 
    1016from django.utils.itercompat import groupby 
    11 import sys 
    12 import re 
    13  
    14 try: 
    15     reversed 
    16 except NameError: 
    17     from django.utils.itercompat import reversed     # Python 2.3 fallback 
    1817 
    1918register = Library() 
     
    4948    def render(self, context): 
    5049        output = self.nodelist.render(context) 
    51         # apply filters 
     50        # Apply filters. 
    5251        context.update({'var': output}) 
    5352        filtered = self.filter_expr.resolve(context) 
     
    8180            reversed = '' 
    8281        return "<For Node: for %s in %s, tail_len: %d%s>" % \ 
    83             (', '.join( self.loopvars ), self.sequence, len(self.nodelist_loop), reversed) 
     82            (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop), 
     83             reversed) 
    8484 
    8585    def __iter__(self): 
     
    115115        for i, item in enumerate(values): 
    116116            context['forloop'] = { 
    117                 # shortcuts for current loop iteration number 
     117                # Shortcuts for current loop iteration number. 
    118118                'counter0': i, 
    119119                'counter': i+1, 
    120                 # reverse counter iteration numbers 
     120                # Reverse counter iteration numbers. 
    121121                'revcounter': len_values - i, 
    122122                'revcounter0': len_values - i - 1, 
    123                 # boolean values designating first and last times through loop 
     123                # Boolean values designating first and last times through loop. 
    124124                'first': (i == 0), 
    125125                'last': (i == len_values - 1), 
     
    127127            } 
    128128            if unpack: 
    129                 # If there are multiple loop variables, unpack the item into them. 
     129                # If there are multiple loop variables, unpack the item into 
     130                # them. 
    130131                context.update(dict(zip(self.loopvars, item))) 
    131132            else: 
     
    154155        try: 
    155156            if self._varlist: 
    156                 # Consider multiple parameters. 
    157                 # This automatically behaves like a OR evaluation of the multiple variables. 
     157                # Consider multiple parameters.  This automatically behaves 
     158                # like an OR evaluation of the multiple variables. 
    158159                compare_to = [var.resolve(context) for var in self._varlist] 
    159160            else: 
     
    249250    def render(self, context): 
    250251        obj_list = self.target.resolve(context, True) 
    251         if obj_list == None: # target_var wasn't found in context; fail silently 
     252        if obj_list == None: 
     253            # target variable wasn't found in context; fail silently. 
    252254            context[self.var_name] = [] 
    253255            return '' 
    254         # List of dictionaries in the format 
     256        # List of dictionaries in the format: 
    255257        # {'grouper': 'key', 'list': [list of contents]}. 
    256         context[self.var_name] = [{'grouper':key, 'list':list(val)} for key, val in 
    257             groupby(obj_list, lambda v, f=self.expression.resolve: f(v, True))] 
     258        context[self.var_name] = [ 
     259            {'grouper': key, 'list': list(val)} 
     260            for key, val in 
     261            groupby(obj_list, lambda v, f=self.expression.resolve: f(v, True)) 
     262        ] 
    258263        return '' 
    259264 
     
    339344        from django.core.urlresolvers import reverse, NoReverseMatch 
    340345        args = [arg.resolve(context) for arg in self.args] 
    341         kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) for k, v in self.kwargs.items()]) 
     346        kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) 
     347                       for k, v in self.kwargs.items()]) 
    342348        try: 
    343349            return reverse(self.view_name, args=args, kwargs=kwargs) 
     
    345351            try: 
    346352                project_name = settings.SETTINGS_MODULE.split('.')[0] 
    347                 return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs) 
     353                return reverse(project_name + '.' + self.view_name, 
     354                               args=args, kwargs=kwargs) 
    348355            except NoReverseMatch: 
    349356                return '' 
     
    389396def comment(parser, token): 
    390397    """ 
    391     Ignore everything between ``{% comment %}`` and ``{% endcomment %}`` 
     398    Ignores everything between ``{% comment %}`` and ``{% endcomment %}``. 
    392399    """ 
    393400    parser.skip_past('endcomment') 
     
    398405def cycle(parser, token): 
    399406    """ 
    400     Cycle among the given strings each time this tag is encountered 
     407    Cycles among the given strings each time this tag is encountered. 
    401408 
    402409    Within a loop, cycles among the given strings each time through 
     
    417424 
    418425    You can use any number of values, seperated by spaces. Commas can also 
    419     be used to separate values; if a comma is used, the cycle values are  
     426    be used to separate values; if a comma is used, the cycle values are 
    420427    interpreted as literal strings. 
    421428    """ 
    422429 
    423     # Note: This returns the exact same node on each {% cycle name %} call; that 
    424     # is, the node object returned from {% cycle a b c as name %} and the on
    425     # returned from {% cycle name %} are the exact same object.  This shouldn't 
    426     # cause problems (heh), but if it does, now you know. 
     430    # Note: This returns the exact same node on each {% cycle name %} call; 
     431    # that is, the node object returned from {% cycle a b c as name %} and th
     432    # one returned from {% cycle name %} are the exact same object.  This 
     433    # shouldn't cause problems (heh), but if it does, now you know. 
    427434    # 
    428435    # Ugly hack warning: this stuffs the named template dict into parser so 
     
    442449 
    443450    if len(args) == 2: 
    444         # {% cycle foo %} case 
     451        # {% cycle foo %} case. 
    445452        name = args[1] 
    446453        if not hasattr(parser, '_namedCycleNodes'): 
    447             raise TemplateSyntaxError("No named cycles in template: '%s' is not defined" % name) 
     454            raise TemplateSyntaxError("No named cycles in template." 
     455                                      " '%s' is not defined" % name) 
    448456        if not name in parser._namedCycleNodes: 
    449457            raise TemplateSyntaxError("Named cycle '%s' does not exist" % name) 
     
    463471def debug(parser, token): 
    464472    """ 
    465     Output a whole load of debugging information, including the current context and imported modules. 
     473    Outputs a whole load of debugging information, including the current 
     474    context and imported modules. 
    466475 
    467476    Sample usage:: 
     
    477486def do_filter(parser, token): 
    478487    """ 
    479     Filter the contents of the blog through variable filters. 
     488    Filters the contents of the blog through variable filters. 
    480489 
    481490    Filters can also be piped through each other, and they can have 
     
    526535    bits = token.split_contents()[1:] 
    527536    if len(bits) < 1: 
    528         raise TemplateSyntaxError, "'firstof' statement requires at least one argument" 
     537        raise TemplateSyntaxError("'firstof' statement requires at least one" 
     538                                  " argument") 
    529539    return FirstOfNode(bits) 
    530540firstof = register.tag(firstof) 
     
    533543def do_for(parser, token): 
    534544    """ 
    535     Loop over each item in an array. 
     545    Loops over each item in an array. 
    536546 
    537547    For example, to display a list of athletes given ``athlete_list``:: 
     
    545555    You can loop over a list in reverse by using 
    546556    ``{% for obj in list reversed %}``. 
    547      
     557 
    548558    You can also unpack multiple values from a two-dimensional array:: 
    549      
     559 
    550560        {% for key,value in dict.items %} 
    551561            {{ key }}: {{ value }} 
     
    572582    bits = token.contents.split() 
    573583    if len(bits) < 4: 
    574         raise TemplateSyntaxError, "'for' statements should have at least four words: %s" % token.contents 
     584        raise TemplateSyntaxError("'for' statements should have at least four" 
     585                                  " words: %s" % token.contents) 
    575586 
    576587    reversed = bits[-1] == 'reversed' 
    577588    in_index = reversed and -3 or -2 
    578589    if bits[in_index] != 'in': 
    579         raise TemplateSyntaxError, "'for' statements should use the format 'for x in y': %s" % token.contents 
     590        raise TemplateSyntaxError("'for' statements should use the format" 
     591                                  " 'for x in y': %s" % token.contents) 
    580592 
    581593    loopvars = re.sub(r' *, *', ',', ' '.join(bits[1:in_index])).split(',') 
    582594    for var in loopvars: 
    583595        if not var or ' ' in var: 
    584             raise TemplateSyntaxError, "'for' tag received an invalid argument: %s" % token.contents 
     596            raise TemplateSyntaxError("'for' tag received an invalid argument:" 
     597                                      " %s" % token.contents) 
    585598 
    586599    sequence = parser.compile_filter(bits[in_index+1]) 
     
    607620def ifequal(parser, token): 
    608621    """ 
    609     Output the contents of the block if the two arguments equal each other. 
     622    Outputs the contents of the block if the two arguments equal each other. 
    610623 
    611624    Examples:: 
     
    626639#@register.tag 
    627640def ifnotequal(parser, token): 
    628     """Output the contents of the block if the two arguments are not equal. See ifequal.""" 
     641    """ 
     642    Outputs the contents of the block if the two arguments are not equal. 
     643    See ifequal. 
     644    """ 
    629645    return do_ifequal(parser, token, True) 
    630646ifnotequal = register.tag(ifnotequal) 
     
    635651    The ``{% if %}`` tag evaluates a variable, and if that variable is "true" 
    636652    (i.e. exists, is not empty, and is not a false boolean value) the contents 
    637     of the block are output: 
    638  
    639     :: 
     653    of the block are output:: 
    640654 
    641655        {% if athlete_list %} 
     
    648662    be displayed by the ``{{ athlete_list|count }}`` variable. 
    649663 
    650     As you can see, the ``if`` tag can take an option ``{% else %}`` clause that 
    651     will be displayed if the test fails. 
     664    As you can see, the ``if`` tag can take an option ``{% else %}`` clause 
     665    that will be displayed if the test fails. 
    652666 
    653667    ``if`` tags may use ``or``, ``and`` or ``not`` to test a number of 
     
    674688        {% endif %} 
    675689 
    676     ``if`` tags do not allow ``and`` and ``or`` clauses with the same 
    677     tag, because the order of logic would be ambigous. For example, 
    678     this is invalid:: 
     690    ``if`` tags do not allow ``and`` and ``or`` clauses with the same tag, 
     691    because the order of logic would be ambigous. For example, this is 
     692    invalid:: 
    679693 
    680694        {% if athlete_list and coach_list or cheerleader_list %} 
     
    692706    del bits[0] 
    693707    if not bits: 
    694         raise TemplateSyntaxError, "'if' statement requires at least one argument" 
    695     # bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d'] 
     708        raise TemplateSyntaxError("'if' statement requires at least one argument") 
     709    # Bits now looks something like this: ['a', 'or', 'not', 'b', 'or', 'c.d'] 
    696710    bitstr = ' '.join(bits) 
    697711    boolpairs = bitstr.split(' and ') 
     
    728742def ifchanged(parser, token): 
    729743    """ 
    730     Check if a value has changed from the last iteration of a loop. 
     744    Checks if a value has changed from the last iteration of a loop. 
    731745 
    732746    The 'ifchanged' block tag is used within a loop. It has two possible uses. 
    733747 
    734748    1. Checks its own rendered contents against its previous state and only 
    735        displays the content if it has changed. For example, this displays a list of 
    736        days, only displaying the month if it changes:: 
     749       displays the content if it has changed. For example, this displays a 
     750       list of days, only displaying the month if it changes:: 
    737751 
    738752            <h1>Archive for {{ year }}</h1> 
     
    743757            {% endfor %} 
    744758 
    745     2. If given a variable, check whether that variable has changed. For example, the 
    746        following shows the date every time it changes, but only shows the hour if both 
    747        the hour and the date have changed:: 
     759    2. If given a variable, check whether that variable has changed. 
     760       For example, the following shows the date every time it changes, but 
     761       only shows the hour if both the hour and the date have changed:: 
    748762 
    749763            {% for date in days %} 
     
    763777def ssi(parser, token): 
    764778    """ 
    765     Output the contents of a given file into the page. 
     779    Outputs the contents of a given file into the page. 
    766780 
    767781    Like a simple "include" tag, the ``ssi`` tag includes the contents 
     
    779793    parsed = False 
    780794    if len(bits) not in (2, 3): 
    781         raise TemplateSyntaxError, "'ssi' tag takes one argument: the path to the file to be included" 
     795        raise TemplateSyntaxError("'ssi' tag takes one argument: the path to" 
     796                                  " the file to be included") 
    782797    if len(bits) == 3: 
    783798        if bits[2] == 'parsed': 
    784799            parsed = True 
    785800        else: 
    786             raise TemplateSyntaxError, "Second (optional) argument to %s tag must be 'parsed'" % bits[0] 
     801            raise TemplateSyntaxError("Second (optional) argument to %s tag" 
     802                                      " must be 'parsed'" % bits[0]) 
    787803    return SsiNode(bits[1], parsed) 
    788804ssi = register.tag(ssi) 
     
    791807def load(parser, token): 
    792808    """ 
    793     Load a custom template tag set. 
    794  
    795     For example, to load the template tags in ``django/templatetags/news/photos.py``:: 
     809    Loads a custom template tag set. 
     810 
     811    For example, to load the template tags in 
     812    ``django/templatetags/news/photos.py``:: 
    796813 
    797814        {% load news.photos %} 
     
    804821            parser.add_library(lib) 
    805822        except InvalidTemplateLibrary, e: 
    806             raise TemplateSyntaxError, "'%s' is not a valid tag library: %s" % (taglib, e) 
     823            raise TemplateSyntaxError("'%s' is not a valid tag library: %s" % 
     824                                      (taglib, e)) 
    807825    return LoadNode() 
    808826load = register.tag(load) 
     
    811829def now(parser, token): 
    812830    """ 
    813     Display the date, formatted according to the given string. 
     831    Displays the date, formatted according to the given string. 
    814832 
    815833    Uses the same format as PHP's ``date()`` function; see http://php.net/date 
     
    830848def regroup(parser, token): 
    831849    """ 
    832     Regroup a list of alike objects by a common attribute. 
     850    Regroups a list of alike objects by a common attribute. 
    833851 
    834852    This complex tag is best illustrated by use of an example:  say that 
     
    868886    Note that `{% regroup %}`` does not work when the list to be grouped is not 
    869887    sorted by the key you are grouping by!  This means that if your list of 
    870     people was not sorted by gender, you'd need to make sure it is sorted before 
    871     using it, i.e.:: 
     888    people was not sorted by gender, you'd need to make sure it is sorted 
     889    before using it, i.e.:: 
    872890 
    873891        {% regroup people|dictsort:"gender" by gender as grouped %} 
     
    879897    target = parser.compile_filter(firstbits[1]) 
    880898    if firstbits[2] != 'by': 
    881         raise TemplateSyntaxError, "second argument to 'regroup' tag must be 'by'" 
     899        raise TemplateSyntaxError("second argument to 'regroup' tag must be 'by'") 
    882900    lastbits_reversed = firstbits[3][::-1].split(None, 2) 
    883901    if lastbits_reversed[1][::-1] != 'as': 
    884         raise TemplateSyntaxError, "next-to-last argument to 'regroup' tag must be 'as'" 
     902        raise TemplateSyntaxError("next-to-last argument to 'regroup' tag must" 
     903                                  " be 'as'") 
    885904 
    886905    expression = parser.compile_filter(lastbits_reversed[2][::-1]) 
     
    892911def spaceless(parser, token): 
    893912    """ 
    894     Removes whitespace between HTML tags. This includes tab 
    895     characters and newlines. 
     913    Removes whitespace between HTML tags, including tab and newline characters. 
    896914 
    897915    Example usage:: 
     
    907925        <p><a href="foo/">Foo</a></p> 
    908926 
    909     Only space between *tags* is normalized -- not space between tags and text. In 
    910     this example, the space around ``Hello`` won't be stripped:: 
     927    Only space between *tags* is normalized -- not space between tags and text. 
     928    In this example, the space around ``Hello`` won't be stripped:: 
    911929 
    912930        {% spaceless %} 
     
    924942def templatetag(parser, token): 
    925943    """ 
    926     Output one of the bits used to compose template tags. 
     944    Outputs one of the bits used to compose template tags. 
    927945 
    928946    Since the template system has no concept of "escaping", to display one of 
     
    949967    tag = bits[1] 
    950968    if tag not in TemplateTagNode.mapping: 
    951         raise TemplateSyntaxError, "Invalid templatetag argument: '%s'. Must be one of: %s" % \ 
    952             (tag, TemplateTagNode.mapping.keys()) 
     969        raise TemplateSyntaxError("Invalid templatetag argument: '%s'." 
     970                                  " Must be one of: %s" % 
     971                                  (tag, TemplateTagNode.mapping.keys())) 
    953972    return TemplateTagNode(tag) 
    954973templatetag = register.tag(templatetag) 
     
    958977    Returns an absolute URL matching given view with its parameters. 
    959978 
    960     This is a way to define links that aren't tied to a particular URL configuration:: 
     979    This is a way to define links that aren't tied to a particular URL 
     980    configuration:: 
    961981 
    962982        {% url path.to.some_view arg1,arg2,name1=value1 %} 
     
    9861006    bits = token.contents.split(' ', 2) 
    9871007    if len(bits) < 2: 
    988         raise TemplateSyntaxError, "'%s' takes at least one argument (path to a view)" % bits[0] 
     1008        raise TemplateSyntaxError("'%s' takes at least one argument" 
     1009                                  " (path to a view)" % bits[0]) 
    9891010    args = [] 
    9901011    kwargs = {} 
     
    10111032 
    10121033    Above, if ``this_value`` is 175 and ``max_value`` is 200, the the image in 
    1013     the above example will be 88 pixels wide (because 175/200 = .875; .875 * 
    1014     100 = 87.5 which is rounded up to 88). 
     1034    the above example will be 88 pixels wide (because 175/200 = .875; 
     1035    .875 * 100 = 87.5 which is rounded up to 88). 
    10151036    """ 
    10161037    bits = token.contents.split() 
     
    10291050def do_with(parser, token): 
    10301051    """ 
    1031     Add a value to the context (inside of this block) for caching and easy 
     1052    Adds a value to the context (inside of this block) for caching and easy 
    10321053    access. 
    10331054 
     
    10401061    bits = list(token.split_contents()) 
    10411062    if len(bits) != 4 or bits[2] != "as": 
    1042         raise TemplateSyntaxError, "%r expected format is 'value as name'" % bits[0] 
     1063        raise TemplateSyntaxError("%r expected format is 'value as name'" % 
     1064                                  bits[0]) 
    10431065    var = parser.compile_filter(bits[1]) 
    10441066    name = bits[3]