We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Mandatory mB topic selection on bet.in ( US #1775)
All projects need a topic on bet.in now, even existing ones. Can we remove that requirement? We haven't yet thought about how to implement topics on bet.in and there are not shown anywhere, so it would probably be confusing for initiators.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `liqd_product/apps/projects/dashboard.py`
Content:
```
1 from django.urls import reverse
2 from django.utils.translation import ugettext_lazy as _
3 
4 from adhocracy4.dashboard import DashboardComponent
5 from adhocracy4.dashboard import ProjectFormComponent
6 from adhocracy4.dashboard import components
7 
8 from . import forms
9 from . import views
10 
11 
12 class ParticipantsComponent(DashboardComponent):
13     identifier = 'participants'
14     weight = 30
15     label = _('Participants')
16 
17     def is_effective(self, project):
18         return not project.is_draft and project.is_private
19 
20     def get_base_url(self, project):
21         return reverse('a4dashboard:dashboard-participants-edit', kwargs={
22             'project_slug': project.slug
23         })
24 
25     def get_urls(self):
26         return [(
27             r'^projects/(?P<project_slug>[-\w_]+)/participants/$',
28             views.DashboardProjectParticipantsView.as_view(component=self),
29             'dashboard-participants-edit'
30         )]
31 
32 
33 class ModeratorsComponent(DashboardComponent):
34     identifier = 'moderators'
35     weight = 32
36     label = _('Moderators')
37 
38     def is_effective(self, project):
39         return True
40 
41     def get_base_url(self, project):
42         return reverse('a4dashboard:dashboard-moderators-edit', kwargs={
43             'project_slug': project.slug
44         })
45 
46     def get_urls(self):
47         return [(
48             r'^projects/(?P<project_slug>[-\w_]+)/moderators/$',
49             views.DashboardProjectModeratorsView.as_view(component=self),
50             'dashboard-moderators-edit'
51         )]
52 
53 
54 class TopicComponent(ProjectFormComponent):
55     identifier = 'topics'
56     weight = 33
57     label = _('Topics')
58 
59     form_title = _('Edit topics')
60     form_class = forms.TopicForm
61     form_template_name = 'liqd_product_projects/project_topics.html'
62 
63 
64 components.register_project(ModeratorsComponent())
65 components.register_project(ParticipantsComponent())
66 components.register_project(TopicComponent())
67
```

Path: `liqd_product/apps/projects/forms.py`
Content:
```
1 from django import forms
2 from django.contrib.auth import get_user_model
3 from django.core.exceptions import ValidationError
4 from django.utils.translation import ugettext_lazy as _
5 
6 from adhocracy4.dashboard.forms import ProjectDashboardForm
7 from adhocracy4.projects.models import Project
8 from liqd_product.apps.users import fields as user_fields
9 
10 from .models import ModeratorInvite
11 from .models import ParticipantInvite
12 
13 User = get_user_model()
14 
15 
16 class InviteForm(forms.ModelForm):
17     accept = forms.CharField(required=False)
18     reject = forms.CharField(required=False)
19 
20     def clean(self):
21         data = self.data
22         if 'accept' not in data and 'reject' not in data:
23             raise ValidationError('Reject or accept')
24         return data
25 
26     def is_accepted(self):
27         data = self.data
28         return 'accept' in data and 'reject' not in data
29 
30 
31 class ParticipantInviteForm(InviteForm):
32 
33     class Meta:
34         model = ParticipantInvite
35         fields = ['accept', 'reject']
36 
37 
38 class ModeratorInviteForm(InviteForm):
39 
40     class Meta:
41         model = ModeratorInvite
42         fields = ['accept', 'reject']
43 
44 
45 class InviteUsersFromEmailForm(forms.Form):
46     add_users = user_fields.CommaSeparatedEmailField(
47         required=False,
48         label=_('Invite users via email')
49     )
50 
51     add_users_upload = user_fields.EmailFileField(
52         required=False,
53         label=_('Invite users via file upload'),
54         help_text=_('Upload a csv file containing email addresses.')
55     )
56 
57     def __init__(self, *args, **kwargs):
58         labels = kwargs.pop('labels', None)
59         super().__init__(*args, **kwargs)
60 
61         if labels:
62             self.fields['add_users'].label = labels[0]
63             self.fields['add_users_upload'].label = labels[1]
64 
65     def clean(self):
66         cleaned_data = super().clean()
67         add_users = self.data.get('add_users')
68         add_users_upload = self.files.get('add_users_upload')
69         if not self.errors and not add_users and not add_users_upload:
70             raise ValidationError(
71                 _('Please enter email addresses or upload a file'))
72         return cleaned_data
73 
74 
75 class TopicForm(ProjectDashboardForm):
76 
77     class Meta:
78         model = Project
79         fields = ['topics']
80         required_for_project_publish = ['topics']
81
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/liqd_product/apps/projects/dashboard.py b/liqd_product/apps/projects/dashboard.py
--- a/liqd_product/apps/projects/dashboard.py
+++ b/liqd_product/apps/projects/dashboard.py
@@ -2,10 +2,8 @@
 from django.utils.translation import ugettext_lazy as _
 
 from adhocracy4.dashboard import DashboardComponent
-from adhocracy4.dashboard import ProjectFormComponent
 from adhocracy4.dashboard import components
 
-from . import forms
 from . import views
 
 
@@ -51,16 +49,5 @@
         )]
 
 
-class TopicComponent(ProjectFormComponent):
-    identifier = 'topics'
-    weight = 33
-    label = _('Topics')
-
-    form_title = _('Edit topics')
-    form_class = forms.TopicForm
-    form_template_name = 'liqd_product_projects/project_topics.html'
-
-
 components.register_project(ModeratorsComponent())
 components.register_project(ParticipantsComponent())
-components.register_project(TopicComponent())
diff --git a/liqd_product/apps/projects/forms.py b/liqd_product/apps/projects/forms.py
--- a/liqd_product/apps/projects/forms.py
+++ b/liqd_product/apps/projects/forms.py
@@ -3,8 +3,6 @@
 from django.core.exceptions import ValidationError
 from django.utils.translation import ugettext_lazy as _
 
-from adhocracy4.dashboard.forms import ProjectDashboardForm
-from adhocracy4.projects.models import Project
 from liqd_product.apps.users import fields as user_fields
 
 from .models import ModeratorInvite
@@ -70,11 +68,3 @@
             raise ValidationError(
                 _('Please enter email addresses or upload a file'))
         return cleaned_data
-
-
-class TopicForm(ProjectDashboardForm):
-
-    class Meta:
-        model = Project
-        fields = ['topics']
-        required_for_project_publish = ['topics']

{"golden_diff": "diff --git a/liqd_product/apps/projects/dashboard.py b/liqd_product/apps/projects/dashboard.py\n--- a/liqd_product/apps/projects/dashboard.py\n+++ b/liqd_product/apps/projects/dashboard.py\n@@ -2,10 +2,8 @@\n from django.utils.translation import ugettext_lazy as _\n \n from adhocracy4.dashboard import DashboardComponent\n-from adhocracy4.dashboard import ProjectFormComponent\n from adhocracy4.dashboard import components\n \n-from . import forms\n from . import views\n \n \n@@ -51,16 +49,5 @@\n         )]\n \n \n-class TopicComponent(ProjectFormComponent):\n-    identifier = 'topics'\n-    weight = 33\n-    label = _('Topics')\n-\n-    form_title = _('Edit topics')\n-    form_class = forms.TopicForm\n-    form_template_name = 'liqd_product_projects/project_topics.html'\n-\n-\n components.register_project(ModeratorsComponent())\n components.register_project(ParticipantsComponent())\n-components.register_project(TopicComponent())\ndiff --git a/liqd_product/apps/projects/forms.py b/liqd_product/apps/projects/forms.py\n--- a/liqd_product/apps/projects/forms.py\n+++ b/liqd_product/apps/projects/forms.py\n@@ -3,8 +3,6 @@\n from django.core.exceptions import ValidationError\n from django.utils.translation import ugettext_lazy as _\n \n-from adhocracy4.dashboard.forms import ProjectDashboardForm\n-from adhocracy4.projects.models import Project\n from liqd_product.apps.users import fields as user_fields\n \n from .models import ModeratorInvite\n@@ -70,11 +68,3 @@\n             raise ValidationError(\n                 _('Please enter email addresses or upload a file'))\n         return cleaned_data\n-\n-\n-class TopicForm(ProjectDashboardForm):\n-\n-    class Meta:\n-        model = Project\n-        fields = ['topics']\n-        required_for_project_publish = ['topics']\n", "issue": "Mandatory mB topic selection on bet.in ( US #1775)\nAll projects need a topic on bet.in now, even existing ones. Can we remove that requirement? We haven't yet thought about how to implement topics on bet.in and there are not shown anywhere, so it would probably be confusing for initiators.\n", "before_files": [{"content": "from django.urls import reverse\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom adhocracy4.dashboard import DashboardComponent\nfrom adhocracy4.dashboard import ProjectFormComponent\nfrom adhocracy4.dashboard import components\n\nfrom . import forms\nfrom . import views\n\n\nclass ParticipantsComponent(DashboardComponent):\n    identifier = 'participants'\n    weight = 30\n    label = _('Participants')\n\n    def is_effective(self, project):\n        return not project.is_draft and project.is_private\n\n    def get_base_url(self, project):\n        return reverse('a4dashboard:dashboard-participants-edit', kwargs={\n            'project_slug': project.slug\n        })\n\n    def get_urls(self):\n        return [(\n            r'^projects/(?P<project_slug>[-\\w_]+)/participants/$',\n            views.DashboardProjectParticipantsView.as_view(component=self),\n            'dashboard-participants-edit'\n        )]\n\n\nclass ModeratorsComponent(DashboardComponent):\n    identifier = 'moderators'\n    weight = 32\n    label = _('Moderators')\n\n    def is_effective(self, project):\n        return True\n\n    def get_base_url(self, project):\n        return reverse('a4dashboard:dashboard-moderators-edit', kwargs={\n            'project_slug': project.slug\n        })\n\n    def get_urls(self):\n        return [(\n            r'^projects/(?P<project_slug>[-\\w_]+)/moderators/$',\n            views.DashboardProjectModeratorsView.as_view(component=self),\n            'dashboard-moderators-edit'\n        )]\n\n\nclass TopicComponent(ProjectFormComponent):\n    identifier = 'topics'\n    weight = 33\n    label = _('Topics')\n\n    form_title = _('Edit topics')\n    form_class = forms.TopicForm\n    form_template_name = 'liqd_product_projects/project_topics.html'\n\n\ncomponents.register_project(ModeratorsComponent())\ncomponents.register_project(ParticipantsComponent())\ncomponents.register_project(TopicComponent())\n", "path": "liqd_product/apps/projects/dashboard.py"}, {"content": "from django import forms\nfrom django.contrib.auth import get_user_model\nfrom django.core.exceptions import ValidationError\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom adhocracy4.dashboard.forms import ProjectDashboardForm\nfrom adhocracy4.projects.models import Project\nfrom liqd_product.apps.users import fields as user_fields\n\nfrom .models import ModeratorInvite\nfrom .models import ParticipantInvite\n\nUser = get_user_model()\n\n\nclass InviteForm(forms.ModelForm):\n    accept = forms.CharField(required=False)\n    reject = forms.CharField(required=False)\n\n    def clean(self):\n        data = self.data\n        if 'accept' not in data and 'reject' not in data:\n            raise ValidationError('Reject or accept')\n        return data\n\n    def is_accepted(self):\n        data = self.data\n        return 'accept' in data and 'reject' not in data\n\n\nclass ParticipantInviteForm(InviteForm):\n\n    class Meta:\n        model = ParticipantInvite\n        fields = ['accept', 'reject']\n\n\nclass ModeratorInviteForm(InviteForm):\n\n    class Meta:\n        model = ModeratorInvite\n        fields = ['accept', 'reject']\n\n\nclass InviteUsersFromEmailForm(forms.Form):\n    add_users = user_fields.CommaSeparatedEmailField(\n        required=False,\n        label=_('Invite users via email')\n    )\n\n    add_users_upload = user_fields.EmailFileField(\n        required=False,\n        label=_('Invite users via file upload'),\n        help_text=_('Upload a csv file containing email addresses.')\n    )\n\n    def __init__(self, *args, **kwargs):\n        labels = kwargs.pop('labels', None)\n        super().__init__(*args, **kwargs)\n\n        if labels:\n            self.fields['add_users'].label = labels[0]\n            self.fields['add_users_upload'].label = labels[1]\n\n    def clean(self):\n        cleaned_data = super().clean()\n        add_users = self.data.get('add_users')\n        add_users_upload = self.files.get('add_users_upload')\n        if not self.errors and not add_users and not add_users_upload:\n            raise ValidationError(\n                _('Please enter email addresses or upload a file'))\n        return cleaned_data\n\n\nclass TopicForm(ProjectDashboardForm):\n\n    class Meta:\n        model = Project\n        fields = ['topics']\n        required_for_project_publish = ['topics']\n", "path": "liqd_product/apps/projects/forms.py"}], "after_files": [{"content": "from django.urls import reverse\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom adhocracy4.dashboard import DashboardComponent\nfrom adhocracy4.dashboard import components\n\nfrom . import views\n\n\nclass ParticipantsComponent(DashboardComponent):\n    identifier = 'participants'\n    weight = 30\n    label = _('Participants')\n\n    def is_effective(self, project):\n        return not project.is_draft and project.is_private\n\n    def get_base_url(self, project):\n        return reverse('a4dashboard:dashboard-participants-edit', kwargs={\n            'project_slug': project.slug\n        })\n\n    def get_urls(self):\n        return [(\n            r'^projects/(?P<project_slug>[-\\w_]+)/participants/$',\n            views.DashboardProjectParticipantsView.as_view(component=self),\n            'dashboard-participants-edit'\n        )]\n\n\nclass ModeratorsComponent(DashboardComponent):\n    identifier = 'moderators'\n    weight = 32\n    label = _('Moderators')\n\n    def is_effective(self, project):\n        return True\n\n    def get_base_url(self, project):\n        return reverse('a4dashboard:dashboard-moderators-edit', kwargs={\n            'project_slug': project.slug\n        })\n\n    def get_urls(self):\n        return [(\n            r'^projects/(?P<project_slug>[-\\w_]+)/moderators/$',\n            views.DashboardProjectModeratorsView.as_view(component=self),\n            'dashboard-moderators-edit'\n        )]\n\n\ncomponents.register_project(ModeratorsComponent())\ncomponents.register_project(ParticipantsComponent())\n", "path": "liqd_product/apps/projects/dashboard.py"}, {"content": "from django import forms\nfrom django.contrib.auth import get_user_model\nfrom django.core.exceptions import ValidationError\nfrom django.utils.translation import ugettext_lazy as _\n\nfrom liqd_product.apps.users import fields as user_fields\n\nfrom .models import ModeratorInvite\nfrom .models import ParticipantInvite\n\nUser = get_user_model()\n\n\nclass InviteForm(forms.ModelForm):\n    accept = forms.CharField(required=False)\n    reject = forms.CharField(required=False)\n\n    def clean(self):\n        data = self.data\n        if 'accept' not in data and 'reject' not in data:\n            raise ValidationError('Reject or accept')\n        return data\n\n    def is_accepted(self):\n        data = self.data\n        return 'accept' in data and 'reject' not in data\n\n\nclass ParticipantInviteForm(InviteForm):\n\n    class Meta:\n        model = ParticipantInvite\n        fields = ['accept', 'reject']\n\n\nclass ModeratorInviteForm(InviteForm):\n\n    class Meta:\n        model = ModeratorInvite\n        fields = ['accept', 'reject']\n\n\nclass InviteUsersFromEmailForm(forms.Form):\n    add_users = user_fields.CommaSeparatedEmailField(\n        required=False,\n        label=_('Invite users via email')\n    )\n\n    add_users_upload = user_fields.EmailFileField(\n        required=False,\n        label=_('Invite users via file upload'),\n        help_text=_('Upload a csv file containing email addresses.')\n    )\n\n    def __init__(self, *args, **kwargs):\n        labels = kwargs.pop('labels', None)\n        super().__init__(*args, **kwargs)\n\n        if labels:\n            self.fields['add_users'].label = labels[0]\n            self.fields['add_users_upload'].label = labels[1]\n\n    def clean(self):\n        cleaned_data = super().clean()\n        add_users = self.data.get('add_users')\n        add_users_upload = self.files.get('add_users_upload')\n        if not self.errors and not add_users and not add_users_upload:\n            raise ValidationError(\n                _('Please enter email addresses or upload a file'))\n        return cleaned_data\n", "path": "liqd_product/apps/projects/forms.py"}]}