Repository: translate/pootle

Issue:
Permission form breaks (with latest django)
Attempting to use the permission form on current master creates the following error:

```
TypeError: object.__new__(generator) is not safe, use generator.__new__()
```

it appears to be caused by how the choices are set on PermissionSetForm



Discussion:
not entirely clear what changed - but im wondering if it was this commit that broke support https://github.com/django/django/commit/2788c46d46bc4d7afb906765ce1f484faef180c5

This is happening on my side with an error mentioning that generator objects cannot be pickled. Converting it into an iterator should work (this is what Django does with regular `ModelChoiceField`s). I'll PR a fix.


Resolving patch:
diff --git a/pootle/apps/pootle_app/views/admin/permissions.py b/pootle/apps/pootle_app/views/admin/permissions.py
--- a/pootle/apps/pootle_app/views/admin/permissions.py
+++ b/pootle/apps/pootle_app/views/admin/permissions.py
@@ -57,11 +57,11 @@ def admin_permissions(request, current_directory, template, ctx):
     base_queryset = User.objects.filter(is_active=1).exclude(
         id__in=current_directory.permission_sets.values_list('user_id',
                                                              flat=True),)
-    querysets = [(None, base_queryset.filter(
+    choice_groups = [(None, base_queryset.filter(
         username__in=('nobody', 'default')
     ))]
 
-    querysets.append((
+    choice_groups.append((
         _('All Users'),
         base_queryset.exclude(username__in=('nobody',
                                             'default')).order_by('username'),
@@ -81,7 +81,7 @@ class Meta(object):
         )
         user = GroupedModelChoiceField(
             label=_('Username'),
-            querysets=querysets,
+            choice_groups=choice_groups,
             queryset=User.objects.all(),
             required=True,
             widget=forms.Select(attrs={
diff --git a/pootle/apps/pootle_misc/forms.py b/pootle/apps/pootle_misc/forms.py
--- a/pootle/apps/pootle_misc/forms.py
+++ b/pootle/apps/pootle_misc/forms.py
@@ -8,33 +8,43 @@
 
 from django import forms
 from django.core.validators import EMPTY_VALUES
+from django.forms.models import ModelChoiceIterator
 
 from pootle.i18n.gettext import ugettext_lazy as _
 
 
+class GroupedModelChoiceIterator(ModelChoiceIterator):
+    def __init__(self, field):
+        self.field = field
+        self.choice_groups = field.choice_groups
+
+    def __iter__(self):
+        if self.field.empty_label is not None:
+            yield (u'', self.field.empty_label)
+
+        for title, queryset in self.choice_groups:
+            if title is not None:
+                yield (title, [self.choice(choice) for choice in queryset])
+            else:
+                for choice in queryset:
+                    yield self.choice(choice)
+
+
 class GroupedModelChoiceField(forms.ModelChoiceField):
-    def __init__(self, querysets, *args, **kwargs):
+    """A `ModelChoiceField` with grouping capabilities.
+
+    :param choice_groups: List of tuples including the `title` and `queryset` of
+        each individual choice group.
+    """
+
+    def __init__(self, choice_groups, *args, **kwargs):
+        self.choice_groups = choice_groups
         super(GroupedModelChoiceField, self).__init__(*args, **kwargs)
-        self.querysets = querysets
 
     def _get_choices(self):
-        orig_queryset = self.queryset
-        orig_empty_label = self.empty_label
-        if self.empty_label is not None:
-            yield (u"", self.empty_label)
-            self.empty_label = None
-
-        for title, queryset in self.querysets:
-            self.queryset = queryset
-            if title is None:
-                for choice in super(GroupedModelChoiceField, self).choices:
-                    yield choice
-            else:
-                yield (title, [choice for choice in
-                               super(GroupedModelChoiceField, self).choices])
-
-        self.queryset = orig_queryset
-        self.empty_label = orig_empty_label
+        if hasattr(self, '_choices'):
+            return self._choices
+        return GroupedModelChoiceIterator(self)
     choices = property(_get_choices, forms.ModelChoiceField._set_choices)
 
 


Test patch: