Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[py3] Fixed 'iterable but non string' detection

In Python 3, the str type has an __iter__ attribute. Therefore, the
presence of an __iter__ attribute is not sufficient to distinguish
'standard' iterables (list, tuple) from strings.
  • Loading branch information...
commit db729266d6feb3b4b4519bd789c4693b9aac00d1 1 parent 0955d16
Claude Paroz authored August 08, 2012
2  django/contrib/admin/helpers.py
@@ -94,7 +94,7 @@ def __iter__(self):
94 94
 class Fieldline(object):
95 95
     def __init__(self, form, field, readonly_fields=None, model_admin=None):
96 96
         self.form = form # A django.forms.Form instance
97  
-        if not hasattr(field, "__iter__"):
  97
+        if not hasattr(field, "__iter__") or isinstance(field, six.text_type):
98 98
             self.fields = [field]
99 99
         else:
100 100
             self.fields = field
4  django/core/serializers/python.py
@@ -98,7 +98,7 @@ def Deserializer(object_list, **options):
98 98
             if field.rel and isinstance(field.rel, models.ManyToManyRel):
99 99
                 if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
100 100
                     def m2m_convert(value):
101  
-                        if hasattr(value, '__iter__'):
  101
+                        if hasattr(value, '__iter__') and not isinstance(value, six.text_type):
102 102
                             return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
103 103
                         else:
104 104
                             return smart_text(field.rel.to._meta.pk.to_python(value))
@@ -110,7 +110,7 @@ def m2m_convert(value):
110 110
             elif field.rel and isinstance(field.rel, models.ManyToOneRel):
111 111
                 if field_value is not None:
112 112
                     if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
113  
-                        if hasattr(field_value, '__iter__'):
  113
+                        if hasattr(field_value, '__iter__') and not isinstance(field_value, six.text_type):
114 114
                             obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
115 115
                             value = getattr(obj, field.rel.field_name)
116 116
                             # If this is a natural foreign key to an object that
2  django/forms/models.py
@@ -1035,6 +1035,6 @@ def clean(self, value):
1035 1035
         return qs
1036 1036
 
1037 1037
     def prepare_value(self, value):
1038  
-        if hasattr(value, '__iter__'):
  1038
+        if hasattr(value, '__iter__') and not isinstance(value, six.text_type):
1039 1039
             return [super(ModelMultipleChoiceField, self).prepare_value(v) for v in value]
1040 1040
         return super(ModelMultipleChoiceField, self).prepare_value(value)
2  django/http/__init__.py
@@ -656,7 +656,7 @@ def _get_content(self):
656 656
         return b''.join([smart_bytes(e, self._charset) for e in self._container])
657 657
 
658 658
     def _set_content(self, value):
659  
-        if hasattr(value, '__iter__'):
  659
+        if hasattr(value, '__iter__') and not isinstance(value, (bytes, six.text_type)):
660 660
             self._container = value
661 661
             self._base_content_is_iter = True
662 662
         else:

0 notes on commit db72926

Please sign in to comment.
Something went wrong with that request. Please try again.