Django

Code

Ticket #7568: 0001-started-to-move-newforms-closer-to-pep8-standards.diff

File 0001-started-to-move-newforms-closer-to-pep8-standards.diff, 30.2 kB (added by stevemilner, 2 years ago)
  • a/django/newforms/extras/widgets.py

    old new  
    99from django.utils.dates import MONTHS 
    1010from django.utils.safestring import mark_safe 
    1111 
    12 __all__ = ('SelectDateWidget',
     12__all__ = ('SelectDateWidget', 
    1313 
    1414RE_DATE = re.compile(r'(\d{4})-(\d\d?)-(\d\d?)$') 
    1515 
     16 
    1617class SelectDateWidget(Widget): 
    1718    """ 
    1819    A Widget that splits date input into three <select> boxes. 
     
    2526    year_field = '%s_year' 
    2627 
    2728    def __init__(self, attrs=None, years=None): 
    28         # years is an optional list/tuple of years to use in the "year" select box. 
     29        # years is an optional list/tuple of years to use in the 
     30        # "year" select box. 
    2931        self.attrs = attrs or {} 
    3032        if years: 
    3133            self.years = years 
     
    4143            if isinstance(value, basestring): 
    4244                match = RE_DATE.match(value) 
    4345                if match: 
    44                     year_val, month_val, day_val = [int(v) for v in match.groups()] 
     46                    year_val, month_val, day_val = [ 
     47                           int(v) for v in match.groups()] 
    4548 
    4649        output = [] 
    4750 
     
    5356        month_choices = MONTHS.items() 
    5457        month_choices.sort() 
    5558        local_attrs = self.build_attrs(id=self.month_field % id_) 
    56         select_html = Select(choices=month_choices).render(self.month_field % name, month_val, local_attrs) 
     59        select_html = Select(choices=month_choices).render( 
     60               self.month_field % name, month_val, local_attrs) 
    5761        output.append(select_html) 
    5862 
    5963        day_choices = [(i, i) for i in range(1, 32)] 
    6064        local_attrs['id'] = self.day_field % id_ 
    61         select_html = Select(choices=day_choices).render(self.day_field % name, day_val, local_attrs) 
     65        select_html = Select(choices=day_choices).render( 
     66               self.day_field % name, day_val, local_attrs) 
    6267        output.append(select_html) 
    6368 
    6469        year_choices = [(i, i) for i in self.years] 
    6570        local_attrs['id'] = self.year_field % id_ 
    66         select_html = Select(choices=year_choices).render(self.year_field % name, year_val, local_attrs) 
     71        select_html = Select(choices=year_choices).render( 
     72               self.year_field % name, year_val, local_attrs) 
    6773        output.append(select_html) 
    6874 
    6975        return mark_safe(u'\n'.join(output)) 
     
    7379    id_for_label = classmethod(id_for_label) 
    7480 
    7581    def value_from_datadict(self, data, files, name): 
    76         y, m, d = data.get(self.year_field % name), data.get(self.month_field % name), data.get(self.day_field % name) 
     82        y = data.get(self.year_field % name) 
     83        m = data.get(self.month_field % name) 
     84        d = data.get(self.day_field % name) 
    7785        if y and m and d: 
    7886            return '%s-%s-%s' % (y, m, d) 
    7987        return data.get(name, None) 
  • a/django/newforms/fields.py

    old new  
    2121from django.utils.encoding import StrAndUnicode, smart_unicode, smart_str 
    2222 
    2323from util import ErrorList, ValidationError 
    24 from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, FileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, DateTimeInput 
     24from widgets import TextInput, PasswordInput, HiddenInput 
     25from widgets import MultipleHiddenInput, FileInput, CheckboxInput, Select 
     26from widgets import NullBooleanSelect, SelectMultiple, DateTimeInput 
    2527 
    2628 
    2729__all__ = ( 
     
    4042 
    4143 
    4244class Field(object): 
    43     widget = TextInput # Default widget to use when rendering this type of Field. 
    44     hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden". 
     45    # Default widget to use when rendering this type of Field. 
     46    widget = TextInput 
     47    # Default widget to use when rendering this as "hidden". 
     48    hidden_widget = HiddenInput 
    4549    default_error_messages = { 
    4650        'required': _(u'This field is required.'), 
    4751        'invalid': _(u'Enter a valid value.'), 
     
    119123        result.widget = copy.deepcopy(self.widget, memo) 
    120124        return result 
    121125 
     126 
    122127class CharField(Field): 
    123128    default_error_messages = { 
    124129        'max_length': _(u'Ensure this value has at most %(max)d characters (it has %(length)d).'), 
  • a/django/newforms/forms.py

    old new  
    1717 
    1818NON_FIELD_ERRORS = '__all__' 
    1919 
     20 
    2021def pretty_name(name): 
    2122    "Converts 'first_name' to 'First name'" 
    2223    name = name[0].upper() + name[1:] 
    2324    return name.replace('_', ' ') 
    2425 
     26 
    2527def get_declared_fields(bases, attrs, with_base_fields=True): 
    2628    """ 
    2729    Create a list of form field instances from the passed in 'attrs', plus any 
     
    3234    Otherwise, only fields in the 'declared_fields' attribute on the bases are 
    3335    used. The distinction is useful in ModelForm subclassing. 
    3436    """ 
    35     fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] 
     37    fields = [(field_name, attrs.pop(field_name)) \ 
     38              for field_name, obj in attrs.items() if isinstance(obj, Field)] 
    3639    fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) 
    3740 
    3841    # If this class is subclassing another Form, add that Form's fields. 
     
    4952 
    5053    return SortedDict(fields) 
    5154 
     55 
    5256class DeclarativeFieldsMetaclass(type): 
    5357    """ 
    5458    Metaclass that converts Field attributes to a dictionary called 
    5559    'base_fields', taking into account parent class 'base_fields' as well. 
    5660    """ 
     61 
    5762    def __new__(cls, name, bases, attrs): 
    5863        attrs['base_fields'] = get_declared_fields(bases, attrs) 
    5964        return type.__new__(cls, name, bases, attrs) 
    6065 
     66 
    6167class BaseForm(StrAndUnicode): 
    62     # This is the main implementation of all the Form logic. Note that this 
    63     # class is different than Form. See the comments by the Form class for more 
    64     # information. Any improvements to the form API should be made to *this* 
    65     # class, not to the Form class. 
     68    """ 
     69    This is the main implementation of all the Form logic. Note that this 
     70    class is different than Form. See the comments by the Form class for more 
     71    information. Any improvements to the form API should be made to *this* 
     72    class, not to the Form class. 
     73    """ 
     74 
    6675    def __init__(self, data=None, files=None, auto_id='id_%s', prefix=None, 
    6776                 initial=None, error_class=ErrorList, label_suffix=':'): 
    6877        self.is_bound = data is not None or files is not None 
     
    118127 
    119128        Subclasses may wish to override. 
    120129        """ 
    121         return self.prefix and ('%s-%s' % (self.prefix, field_name)) or field_name 
     130        return self.prefix and ('%s-%s' % (self.prefix, field_name)) or \ 
     131                               field_name 
    122132 
    123     def _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row): 
    124         "Helper function for outputting HTML. Used by as_table(), as_ul(), as_p()." 
    125         top_errors = self.non_field_errors() # Errors that should be displayed above all fields. 
     133    def _html_output(self, normal_row, error_row, row_ender, 
     134                           help_text_html, errors_on_separate_row): 
     135        """ 
     136        Helper function for outputting HTML. Used by as_table(), 
     137        as_ul(), as_p(). 
     138        """ 
     139        # Errors that should be displayed above all fields. 
     140        top_errors = self.non_field_errors() 
    126141        output, hidden_fields = [], [] 
    127142        for name, field in self.fields.items(): 
    128143            bf = BoundField(self, field, name) 
    129             bf_errors = self.error_class([escape(error) for error in bf.errors]) # Escape and cache in local variable. 
     144            # Escape and cache in local variable. 
     145            bf_errors = self.error_class([escape(error) \ 
     146                        for error in bf.errors]) 
    130147            if bf.is_hidden: 
    131148                if bf_errors: 
    132                     top_errors.extend([u'(Hidden field %s) %s' % (name, force_unicode(e)) for e in bf_errors]) 
     149                    top_errors.extend([u'(Hidden field %s) %s' % ( 
     150                           name, force_unicode(e)) for e in bf_errors]) 
    133151                hidden_fields.append(unicode(bf)) 
    134152            else: 
    135153                if errors_on_separate_row and bf_errors: 
     
    148166                    help_text = help_text_html % force_unicode(field.help_text) 
    149167                else: 
    150168                    help_text = u'' 
    151                 output.append(normal_row % {'errors': force_unicode(bf_errors), 'label': force_unicode(label), 'field': unicode(bf), 'help_text': help_text}) 
     169                output.append(normal_row % { 
     170                           'errors': force_unicode(bf_errors), 
     171                           'label': force_unicode(label), 
     172                           'field': unicode(bf), 
     173                           'help_text': help_text}) 
    152174        if top_errors: 
    153175            output.insert(0, error_row % force_unicode(top_errors)) 
    154176        if hidden_fields: # Insert any hidden fields in the last row. 
     
    157179                last_row = output[-1] 
    158180                # Chop off the trailing row_ender (e.g. '</td></tr>') and 
    159181                # insert the hidden fields. 
    160                 output[-1] = last_row[:-len(row_ender)] + str_hidden + row_ender 
     182                output[-1] = last_row[:-len(row_ender)] + str_hidden + \ 
     183                               row_ender 
    161184            else: 
    162185                # If there aren't any rows in the output, just append the 
    163186                # hidden fields. 
     
    165188        return mark_safe(u'\n'.join(output)) 
    166189 
    167190    def as_table(self): 
    168         "Returns this form rendered as HTML <tr>s -- excluding the <table></table>." 
    169         return self._html_output(u'<tr><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s</td></tr>', u'<tr><td colspan="2">%s</td></tr>', '</td></tr>', u'<br />%s', False) 
     191        """ 
     192        Returns this form rendered as HTML <tr>s -- excluding the 
     193        <table></table>. 
     194        """ 
     195        return self._html_output( 
     196            u'<tr><th>%(label)s</th><td>%(errors)s%(field)s%(help_text)s\ 
     197</td></tr>', 
     198            u'<tr><td colspan="2">%s</td></tr>', 
     199            '</td></tr>', 
     200            u'<br />%s', 
     201            False) 
    170202 
    171203    def as_ul(self): 
    172204        "Returns this form rendered as HTML <li>s -- excluding the <ul></ul>." 
    173         return self._html_output(u'<li>%(errors)s%(label)s %(field)s%(help_text)s</li>', u'<li>%s</li>', '</li>', u' %s', False) 
     205        return self._html_output( 
     206            u'<li>%(errors)s%(label)s %(field)s%(help_text)s</li>', 
     207            u'<li>%s</li>', 
     208            '</li>', 
     209            u' %s', 
     210            False) 
    174211 
    175212    def as_p(self): 
    176213        "Returns this form rendered as HTML <p>s." 
    177         return self._html_output(u'<p>%(label)s %(field)s%(help_text)s</p>', u'%s', '</p>', u' %s', True) 
     214        return self._html_output( 
     215            u'<p>%(label)s %(field)s%(help_text)s</p>', 
     216            u'%s', 
     217            '</p>', 
     218            u' %s', 
     219            True) 
    178220 
    179221    def non_field_errors(self): 
    180222        """ 
     
    197239            # value_from_datadict() gets the data from the data dictionaries. 
    198240            # Each widget type knows how to retrieve its own data, because some 
    199241            # widgets split data over several HTML fields. 
    200             value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name)) 
     242            value = field.widget.value_from_datadict(self.data, 
     243                           self.files, self.add_prefix(name)) 
    201244            try: 
    202245                if isinstance(field, FileField): 
    203246                    initial = self.initial.get(name, field.initial) 
     
    238281                return True 
    239282        return False 
    240283 
     284 
    241285class Form(BaseForm): 
    242286    "A collection of Fields, plus their associated data." 
    243287    # This is a separate class from BaseForm in order to abstract the way 
     
    247291    # BaseForm itself has no way of designating self.fields. 
    248292    __metaclass__ = DeclarativeFieldsMetaclass 
    249293 
     294 
    250295class BoundField(StrAndUnicode): 
    251296    "A Field plus data" 
     297 
    252298    def __init__(self, form, field, name): 
    253299        self.form = form 
    254300        self.field = field 
     
    294340 
    295341    def as_text(self, attrs=None): 
    296342        """ 
    297         Returns a string of HTML for representing this as an <input type="text">. 
     343        Returns a string of HTML for representing this as 
     344        an <input type="text">. 
    298345        """ 
    299346        return self.as_widget(TextInput(), attrs) 
    300347 
     
    304351 
    305352    def as_hidden(self, attrs=None): 
    306353        """ 
    307         Returns a string of HTML for representing this as an <input type="hidden">. 
     354        Returns a string of HTML for representing this as an 
     355        <input type="hidden">. 
    308356        """ 
    309357        return self.as_widget(self.field.hidden_widget(), attrs) 
    310358 
     
    312360        """ 
    313361        Returns the data for this BoundField, or None if it wasn't given. 
    314362        """ 
    315         return self.field.widget.value_from_datadict(self.form.data, self.form.files, self.html_name) 
     363        return self.field.widget.value_from_datadict( 
     364                   self.form.data, self.form.files, self.html_name) 
    316365    data = property(_data) 
    317366 
    318367    def label_tag(self, contents=None, attrs=None): 
    319368        """ 
    320         Wraps the given contents in a <label>, if the field has an ID attribute. 
    321         Does not HTML-escape the contents. If contents aren't given, uses the 
    322         field's HTML-escaped label. 
     369        Wraps the given contents in a <label>, if the field has an ID 
     370        attribute. Does not HTML-escape the contents. If contents aren't 
     371        given, uses the field's HTML-escaped label. 
    323372 
    324         If attrs are given, they're used as HTML attributes on the <label> tag. 
     373        If attrs are given, they're used as HTML attributes on the 
     374        <label> tag. 
    325375        """ 
    326376        contents = contents or escape(self.label) 
    327377        widget = self.field.widget 
    328378        id_ = widget.attrs.get('id') or self.auto_id 
    329379        if id_: 
    330380            attrs = attrs and flatatt(attrs) or '' 
    331             contents = '<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, contents) 
     381            contents = '<label for="%s"%s>%s</label>' % ( 
     382                   widget.id_for_label(id_), attrs, contents) 
    332383        return mark_safe(contents) 
    333384 
    334385    def _is_hidden(self): 
     
    339390    def _auto_id(self): 
    340391        """ 
    341392        Calculates and returns the ID attribute for this BoundField, if the 
    342         associated Form has specified auto_id. Returns an empty string otherwise. 
     393        associated Form has specified auto_id. Returns an empty string 
     394        otherwise. 
    343395        """ 
    344396        auto_id = self.form.auto_id 
    345397        if auto_id and '%s' in smart_unicode(auto_id): 
  • a/django/newforms/widgets.py

    old new  
    2525    'CheckboxSelectMultiple', 'MultiWidget', 'SplitDateTimeWidget', 
    2626) 
    2727 
     28 
    2829class Widget(object): 
    29     is_hidden = False          # Determines whether this corresponds to an <input type="hidden">. 
    30     needs_multipart_form = False # Determines does this widget need multipart-encrypted form 
     30    is_hidden = False # Determines whether this corresponds to 
     31                      #an <input type="hidden">. 
     32    needs_multipart_form = False # Determines does this widget 
     33                                 # need multipart-encrypted form 
    3134 
    3235    def __init__(self, attrs=None): 
    3336        if attrs is not None: 
     
    7780        return id_ 
    7881    id_for_label = classmethod(id_for_label) 
    7982 
     83 
    8084class Input(Widget): 
    8185    """ 
    8286    Base class for all <input> widgets (except type='checkbox' and 
     
    8589    input_type = None # Subclasses must define this. 
    8690 
    8791    def render(self, name, value, attrs=None): 
    88         if value is None: value = '' 
     92        if value is None: 
     93            value = '' 
    8994        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) 
    9095        if value != '': 
    9196            # Only add the 'value' attribute if a value is non-empty. 
    9297            final_attrs['value'] = force_unicode(value) 
    9398        return mark_safe(u'<input%s />' % flatatt(final_attrs)) 
    9499 
     100 
    95101class TextInput(Input): 
    96102    input_type = 'text' 
    97103 
     104 
    98105class PasswordInput(Input): 
    99106    input_type = 'password' 
    100107 
     
    103110        self.render_value = render_value 
    104111 
    105112    def render(self, name, value, attrs=None): 
    106         if not self.render_value: value=None 
     113        if not self.render_value: 
     114            value=None 
    107115        return super(PasswordInput, self).render(name, value, attrs) 
    108116 
     117 
    109118class HiddenInput(Input): 
    110119    input_type = 'hidden' 
    111120    is_hidden = True 
    112121 
     122 
    113123class MultipleHiddenInput(HiddenInput): 
    114124    """ 
    115125    A widget that handles <input type="hidden"> for fields that have a list 
    116126    of values. 
    117127    """ 
     128 
    118129    def __init__(self, attrs=None, choices=()): 
    119130        super(MultipleHiddenInput, self).__init__(attrs) 
    120131        # choices can be any iterable 
    121132        self.choices = choices 
    122133 
    123134    def render(self, name, value, attrs=None, choices=()): 
    124         if value is None: value = [] 
     135        if value is None: 
     136            value = [] 
    125137        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name) 
    126138        return mark_safe(u'\n'.join([(u'<input%s />' % 
    127139            flatatt(dict(value=force_unicode(v), **final_attrs))) 
     
    132144            return data.getlist(name) 
    133145        return data.get(name, None) 
    134146 
     147 
    135148class FileInput(Input): 
    136149    input_type = 'file' 
    137150    needs_multipart_form = True 
     
    143156        "File widgets take data from FILES, not POST" 
    144157        return files.get(name, None) 
    145158 
     159 
    146160class Textarea(Widget): 
     161 
    147162    def __init__(self, attrs=None): 
    148163        # The 'rows' and 'cols' attributes are required for HTML correctness. 
    149164        self.attrs = {'cols': '40', 'rows': '10'} 
     
    151166            self.attrs.update(attrs) 
    152167 
    153168    def render(self, name, value, attrs=None): 
    154         if value is None: value = '' 
     169        if value is None: 
     170            value = '' 
    155171        value = force_unicode(value) 
    156172        final_attrs = self.build_attrs(attrs, name=name) 
    157173        return mark_safe(u'<textarea%s>%s</textarea>' % (flatatt(final_attrs), 
    158174                conditional_escape(force_unicode(value)))) 
    159175 
     176 
    160177class DateTimeInput(Input): 
    161178    input_type = 'text' 
    162179    format = '%Y-%m-%d %H:%M:%S'     # '2006-10-25 14:30:59' 
     
    173190            value = value.strftime(self.format) 
    174191        return super(DateTimeInput, self).render(name, value, attrs) 
    175192 
     193 
    176194class CheckboxInput(Widget): 
     195 
    177196    def __init__(self, attrs=None, check_test=bool): 
    178197        super(CheckboxInput, self).__init__(attrs) 
    179198        # check_test is a callable that takes a value and returns True 
     
    198217            # A missing value means False because HTML form submission does not 
    199218            # send results for unselected checkboxes. 
    200219            return False 
    201         return super(CheckboxInput, self).value_from_datadict(data, files, name) 
     220        return super(CheckboxInput, self).value_from_datadict( 
     221                                           data, files, name) 
     222 
    202223 
    203224class Select(Widget): 
     225 
    204226    def __init__(self, attrs=None, choices=()): 
    205227        super(Select, self).__init__(attrs) 
    206228        # choices can be any iterable, but we may need to render this widget 
     
    209231        self.choices = list(choices) 
    210232 
    211233    def render(self, name, value, attrs=None, choices=()): 
    212         if value is None: value = '' 
     234        if value is None: 
     235            value = '' 
    213236        final_attrs = self.build_attrs(attrs, name=name) 
    214237        output = [u'<select%s>' % flatatt(final_attrs)] 
    215238        # Normalize to string. 
    216239        str_value = force_unicode(value) 
    217240        for option_value, option_label in chain(self.choices, choices): 
    218241            option_value = force_unicode(option_value) 
    219             selected_html = (option_value == str_value) and u' selected="selected"' or '' 
     242            selected_html = (option_value == str_value) and \ 
     243                               u' selected="selected"' or '' 
    220244            output.append(u'<option value="%s"%s>%s</option>' % ( 
    221245                    escape(option_value), selected_html, 
    222246                    conditional_escape(force_unicode(option_label)))) 
    223247        output.append(u'</select>') 
    224248        return mark_safe(u'\n'.join(output)) 
    225249 
     250 
    226251class NullBooleanSelect(Select): 
    227252    """ 
    228253    A Select Widget intended to be used with NullBooleanField. 
    229254    """ 
     255 
    230256    def __init__(self, attrs=None): 
    231         choices = ((u'1', ugettext('Unknown')), (u'2', ugettext('Yes')), (u'3', ugettext('No'))) 
     257        choices = ((u'1', ugettext('Unknown')), (u'2', ugettext('Yes')), 
     258                   (u'3', ugettext('No'))) 
    232259        super(NullBooleanSelect, self).__init__(attrs, choices) 
    233260 
    234261    def render(self, name, value, attrs=None, choices=()): 
     
    236263            value = {True: u'2', False: u'3', u'2': u'2', u'3': u'3'}[value] 
    237264        except KeyError: 
    238265            value = u'1' 
    239         return super(NullBooleanSelect, self).render(name, value, attrs, choices) 
     266        return super(NullBooleanSelect, self).render( 
     267                               name, value, attrs, choices) 
    240268 
    241269    def value_from_datadict(self, data, files, name): 
    242270        value = data.get(name, None) 
    243         return {u'2': True, u'3': False, True: True, False: False}.get(value, None) 
     271        return {u'2': True, u'3': False, True: True, False: False}.get( 
     272                               value, None) 
     273 
    244274 
    245275class SelectMultiple(Widget): 
     276 
    246277    def __init__(self, attrs=None, choices=()): 
    247278        super(SelectMultiple, self).__init__(attrs) 
    248279        # choices can be any iterable 
    249280        self.choices = choices 
    250281 
    251282    def render(self, name, value, attrs=None, choices=()): 
    252         if value is None: value = [] 
     283        if value is None: 
     284            value = [] 
    253285        final_attrs = self.build_attrs(attrs, name=name) 
    254286        output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)] 
    255         str_values = set([force_unicode(v) for v in value]) # Normalize to strings. 
     287        # Normalize to strings. 
     288        str_values = set([force_unicode(v) for v in value]) 
    256289        for option_value, option_label in chain(self.choices, choices): 
    257290            option_value = force_unicode(option_value) 
    258             selected_html = (option_value in str_values) and ' selected="selected"' or '' 
     291            selected_html = (option_value in str_values) and \ 
     292                               ' selected="selected"' or '' 
    259293            output.append(u'<option value="%s"%s>%s</option>' % ( 
    260294                    escape(option_value), selected_html, 
    261295                    conditional_escape(force_unicode(option_label)))) 
     
    267301            return data.getlist(name) 
    268302        return data.get(name, None) 
    269303 
     304 
    270305class RadioInput(StrAndUnicode): 
    271306    """ 
    272307    An object used by RadioFieldRenderer that represents a single 
     
    286321        else: 
    287322            label_for = '' 
    288323        choice_label = conditional_escape(force_unicode(self.choice_label)) 
    289         return mark_safe(u'<label%s>%s %s</label>' % (label_for, self.tag(), choice_label)) 
     324        return mark_safe(u'<label%s>%s %s</label>' % ( 
     325                               label_for, self.tag(), choice_label)) 
    290326 
    291327    def is_checked(self): 
    292328        return self.value == self.choice_value 
     
    294330    def tag(self): 
    295331        if 'id' in self.attrs: 
    296332            self.attrs['id'] = '%s_%s' % (self.attrs['id'], self.index) 
    297         final_attrs = dict(self.attrs, type='radio', name=self.name, value=self.choice_value) 
     333        final_attrs = dict(self.attrs, type='radio', 
     334                           name=self.name, value=self.choice_value) 
    298335        if self.is_checked(): 
    299336            final_attrs['checked'] = 'checked' 
    300337        return mark_safe(u'<input%s />' % flatatt(final_attrs)) 
    301338 
     339 
    302340class RadioFieldRenderer(StrAndUnicode): 
    303341    """ 
    304342    An object used by RadioSelect to enable customization of radio widgets. 
     
    310348 
    311349    def __iter__(self): 
    312350        for i, choice in enumerate(self.choices): 
    313             yield RadioInput(self.name, self.value, self.attrs.copy(), choice, i) 
     351            yield RadioInput(self.name, self.value, self.attrs.copy(), 
     352                               choice, i) 
    314353 
    315354    def __getitem__(self, idx): 
    316355        choice = self.choices[idx] # Let the IndexError propogate 
    317         return RadioInput(self.name, self.value, self.attrs.copy(), choice, idx) 
     356        return RadioInput(self.name, self.value, self.attrs.copy(), 
     357                           choice, idx) 
    318358 
    319359    def __unicode__(self): 
    320360        return self.render() 
     
    324364        return mark_safe(u'<ul>\n%s\n</ul>' % u'\n'.join([u'<li>%s</li>' 
    325365                % force_unicode(w) for w in self])) 
    326366 
     367 
    327368class RadioSelect(Select): 
    328369    renderer = RadioFieldRenderer 
    329370 
     
    336377 
    337378    def get_renderer(self, name, value, attrs=None, choices=()): 
    338379        """Returns an instance of the renderer.""" 
    339         if value is None: value = '' 
     380        if value is None: 
     381            value = '' 
    340382        str_value = force_unicode(value) # Normalize to string. 
    341383        final_attrs = self.build_attrs(attrs) 
    342384        choices = list(chain(self.choices, choices)) 
     
    355397        return id_ 
    356398    id_for_label = classmethod(id_for_label) 
    357399 
     400 
    358401class CheckboxSelectMultiple(SelectMultiple): 
     402 
    359403    def render(self, name, value, attrs=None, choices=()): 
    360         if value is None: value = [] 
     404        if value is None: 
     405            value = [] 
    361406        has_id = attrs and 'id' in attrs 
    362407        final_attrs = self.build_attrs(attrs, name=name) 
    363408        output = [u'<ul>'] 
    364409        # Normalize to strings 
    365410        str_values = set([force_unicode(v) for v in value]) 
    366         for i, (option_value, option_label) in enumerate(chain(self.choices, choices)): 
     411        for i, (option_value, option_label) in enumerate(chain( 
     412                           self.choices, choices)): 
    367413            # If an ID attribute was given, add a numeric index as a suffix, 
    368414            # so that the checkboxes don't all have the same ID attribute. 
    369415            if has_id: 
     
    371417                label_for = u' for="%s"' % final_attrs['id'] 
    372418            else: 
    373419                label_for = '' 
    374                  
    375             cb = CheckboxInput(final_attrs, check_test=lambda value: value in str_values) 
     420 
     421            cb = CheckboxInput(final_attrs, 
     422                               check_test=lambda value: value in str_values) 
    376423            option_value = force_unicode(option_value) 
    377424            rendered_cb = cb.render(name, option_value) 
    378425            option_label = conditional_escape(force_unicode(option_label)) 
    379             output.append(u'<li><label%s>%s %s</label></li>' % (label_for, rendered_cb, option_label)) 
     426            output.append(u'<li><label%s>%s %s</label></li>' % ( 
     427                           label_for, rendered_cb, option_label)) 
    380428        output.append(u'</ul>') 
    381429        return mark_safe(u'\n'.join(output)) 
    382430 
     
    387435        return id_ 
    388436    id_for_label = classmethod(id_for_label) 
    389437 
     438 
    390439class MultiWidget(Widget): 
    391440    """ 
    392441    A widget that is composed of multiple widgets. 
     
    414463 
    415464    You'll probably want to use this class with MultiValueField. 
    416465    """ 
     466 
    417467    def __init__(self, widgets, attrs=None): 
    418468        self.widgets = [isinstance(w, type) and w() or w for w in widgets] 
    419469        super(MultiWidget, self).__init__(attrs) 
     
    433483                widget_value = None 
    434484            if id_: 
    435485                final_attrs = dict(final_attrs, id='%s_%s' % (id_, i)) 
    436             output.append(widget.render(name + '_%s' % i, widget_value, final_attrs)) 
     486            output.append(widget.render(name + '_%s' % i, widget_value, 
     487                                       final_attrs)) 
    437488        return mark_safe(self.format_output(output)) 
    438489 
    439490    def id_for_label(self, id_): 
     
    444495    id_for_label = classmethod(id_for_label) 
    445496 
    446497    def value_from_datadict(self, data, files, name): 
    447         return [widget.value_from_datadict(data, files, name + '_%s' % i) for i, widget in enumerate(self.widgets)] 
     498        return [widget.value_from_datadict(data, files, name + '_%s' % i) \ 
     499               for i, widget in enumerate(self.widgets)] 
    448500 
    449501    def format_output(self, rendered_widgets): 
    450502        """ 
     
    464516        """ 
    465517        raise NotImplementedError('Subclasses must implement this method.') 
    466518 
     519 
    467520class SplitDateTimeWidget(MultiWidget): 
    468521    """ 
    469522    A Widget that splits datetime input into two <input type="text"> boxes. 
    470523    """ 
     524 
    471525    def __init__(self, attrs=None): 
    472526        widgets = (TextInput(attrs=attrs), TextInput(attrs=attrs)) 
    473527        super(SplitDateTimeWidget, self).__init__(widgets, attrs) 
     
    476530        if value: 
    477531            return [value.date(), value.time().replace(microsecond=0)] 
    478532        return [None, None] 
    479