We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Enhance form rendering: Radio button list
This is a follow-on to #322, to enhance how forms are rendered in the [`page` template](https://github.com/cal-itp/benefits/blob/dev/benefits/core/templates/core/page.html)

@angela-tran [notes](https://github.com/cal-itp/benefits/pull/337#issuecomment-1076882758):

> `RadioSelect` in Django 3.2 renders as `<li>` elements. We probably don't want that? Should we add something to `page.html` so that we have more granular control over how radio buttons are shown? (Django docs have an [example](https://docs.djangoproject.com/en/3.2/ref/forms/widgets/#radioselect) of looping over the widgets.)

![image](https://user-images.githubusercontent.com/1783439/160215029-07dadd9d-e422-49ea-91b3-533485236daa.png)

The [State Template form components](https://template.webstandards.ca.gov/sample/form.html) has some example HTML for what might work here?

```html
<!--Bootstrap4 Custom Radios-->
<div class="form-check">
    <input class="form-check-input" type="radio" name="flexRadioDefault" id="customRadio1">
    <label class="form-check-label" for="customRadio1">
        Toggle this custom radio
    </label>
</div>
<div class="form-check">
    <input class="form-check-input" type="radio" name="flexRadioDefault" id="customRadio2" checked="">
    <label class="form-check-label" for="customRadio2">
        Or toggle this other custom radio
    </label>
</div>
```

The comment indicates this is just [Bootstrap 4 radios](https://getbootstrap.com/docs/4.0/components/forms/#radios)?

@angela-tran [suggests](https://github.com/cal-itp/benefits/pull/337#issuecomment-1076882758):

> Rendering the `selection_label_description` may involve adding some HTML to the display value in our `choices` tuple. My first step would be to try out the approach in https://stackoverflow.com/questions/2204696/setting-help-text-for-each-choice-in-a-radioselect.

![image](https://user-images.githubusercontent.com/1783439/160215069-abd2c18b-0ebf-4d78-a202-be7947e70ab5.png)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `benefits/core/widgets.py`
Content:
```
1 """
2 The core application: Helper form widgets.
3 """
4 from django.forms import widgets
5 
6 
7 class FormControlTextInput(widgets.TextInput):
8     """A styled text input."""
9 
10     def __init__(self, pattern=None, placeholder=None, **kwargs):
11         super().__init__(**kwargs)
12 
13         self.attrs.update({"class": "form-control form-control-lg"})
14         if pattern:
15             self.attrs.update({"pattern": pattern})
16         if placeholder:
17             self.attrs.update({"placeholder": placeholder})
18
```

Path: `benefits/eligibility/forms.py`
Content:
```
1 """
2 The eligibility application: Form definition for the eligibility verification flow.
3 """
4 import logging
5 
6 from django import forms
7 from django.utils.translation import gettext_lazy as _
8 
9 from benefits.core import models, recaptcha, widgets
10 
11 
12 logger = logging.getLogger(__name__)
13 
14 
15 class EligibilityVerifierSelectionForm(forms.Form):
16     """Form to capture eligibility verifier selection."""
17 
18     action_url = "eligibility:index"
19     method = "POST"
20 
21     verifier = forms.ChoiceField(label="", widget=forms.RadioSelect)
22 
23     submit_value = _("eligibility.buttons.continue")
24 
25     def __init__(self, agency: models.TransitAgency, *args, **kwargs):
26         super().__init__(*args, **kwargs)
27         choices = [(v.id, _(v.selection_label)) for v in agency.eligibility_verifiers.all()]
28         self.fields["verifier"].choices = choices
29 
30 
31 class EligibilityVerificationForm(forms.Form):
32     """Form to collect eligibility verification details."""
33 
34     action_url = "eligibility:confirm"
35     method = "POST"
36 
37     submit_value = _("eligibility.forms.confirm.submit")
38     submitting_value = _("eligibility.forms.confirm.submitting")
39 
40     _error_messages = {
41         "invalid": _("eligibility.forms.confirm.errors.invalid"),
42         "missing": _("eligibility.forms.confirm.errors.missing"),
43     }
44 
45     def __init__(self, verifier: models.EligibilityVerifier, *args, **kwargs):
46         super().__init__(*args, **kwargs)
47 
48         sub_widget = widgets.FormControlTextInput(placeholder=verifier.form_sub_placeholder)
49         if verifier.form_sub_pattern:
50             sub_widget.attrs.update({"pattern": verifier.form_sub_pattern})
51 
52         self.fields["sub"] = forms.CharField(label=_(verifier.form_sub_label), widget=sub_widget)
53 
54         name_widget = widgets.FormControlTextInput(placeholder=verifier.form_name_placeholder)
55         if verifier.form_name_max_length:
56             name_widget.attrs.update({"maxlength": verifier.form_name_max_length})
57 
58         self.fields["name"] = forms.CharField(label=_(verifier.form_name_label), widget=name_widget)
59 
60     def add_api_errors(self, form_errors):
61         """Handle errors passed back from API server related to submitted form values."""
62 
63         validation_errors = {
64             field: forms.ValidationError(self._error_messages.get(code, _("core.pages.error.title")), code=code)
65             for (field, code) in form_errors.items()
66             if field in self.fields
67         }
68 
69         if len(validation_errors) > 0:
70             logger.warning("Form fields are invalid")
71 
72         for (field, err) in validation_errors.items():
73             self.add_error(field, err)
74 
75     def clean(self):
76         if not recaptcha.verify(self.data):
77             raise forms.ValidationError("reCAPTCHA failed")
78
```
--- 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/benefits/core/widgets.py b/benefits/core/widgets.py
--- a/benefits/core/widgets.py
+++ b/benefits/core/widgets.py
@@ -1,6 +1,7 @@
 """
 The core application: Helper form widgets.
 """
+import copy
 from django.forms import widgets
 
 
@@ -15,3 +16,25 @@
             self.attrs.update({"pattern": pattern})
         if placeholder:
             self.attrs.update({"placeholder": placeholder})
+
+
+class RadioSelect(widgets.RadioSelect):
+    template_name = "core/widgets/radio_select.html"
+    option_template_name = "core/widgets/radio_select_option.html"
+
+    def __init__(self, choice_descriptions=(), *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.choice_descriptions = list(choice_descriptions)
+
+    def __deepcopy__(self, memo):
+        obj = super().__deepcopy__(memo)
+        obj.choice_descriptions = copy.copy(self.choice_descriptions)
+        return obj
+
+    def create_option(self, name, value, label, selected, index, subindex, attrs):
+        option = super().create_option(name, value, label, selected, index, subindex, attrs)
+        # this implementation does not support groups from ChoiceWidget.optgroups
+        if value in self.choice_descriptions:
+            option.update({"description": self.choice_descriptions[value]})
+
+        return option
diff --git a/benefits/eligibility/forms.py b/benefits/eligibility/forms.py
--- a/benefits/eligibility/forms.py
+++ b/benefits/eligibility/forms.py
@@ -18,14 +18,18 @@
     action_url = "eligibility:index"
     method = "POST"
 
-    verifier = forms.ChoiceField(label="", widget=forms.RadioSelect)
+    verifier = forms.ChoiceField(label="", widget=widgets.RadioSelect)
 
     submit_value = _("eligibility.buttons.continue")
 
     def __init__(self, agency: models.TransitAgency, *args, **kwargs):
         super().__init__(*args, **kwargs)
-        choices = [(v.id, _(v.selection_label)) for v in agency.eligibility_verifiers.all()]
-        self.fields["verifier"].choices = choices
+        verifiers = agency.eligibility_verifiers.all()
+
+        self.fields["verifier"].choices = [(v.id, _(v.selection_label)) for v in verifiers]
+        self.fields["verifier"].widget.choice_descriptions = {
+            v.id: _(v.selection_label_description) for v in verifiers if v.selection_label_description
+        }
 
 
 class EligibilityVerificationForm(forms.Form):

{"golden_diff": "diff --git a/benefits/core/widgets.py b/benefits/core/widgets.py\n--- a/benefits/core/widgets.py\n+++ b/benefits/core/widgets.py\n@@ -1,6 +1,7 @@\n \"\"\"\n The core application: Helper form widgets.\n \"\"\"\n+import copy\n from django.forms import widgets\n \n \n@@ -15,3 +16,25 @@\n             self.attrs.update({\"pattern\": pattern})\n         if placeholder:\n             self.attrs.update({\"placeholder\": placeholder})\n+\n+\n+class RadioSelect(widgets.RadioSelect):\n+    template_name = \"core/widgets/radio_select.html\"\n+    option_template_name = \"core/widgets/radio_select_option.html\"\n+\n+    def __init__(self, choice_descriptions=(), *args, **kwargs):\n+        super().__init__(*args, **kwargs)\n+        self.choice_descriptions = list(choice_descriptions)\n+\n+    def __deepcopy__(self, memo):\n+        obj = super().__deepcopy__(memo)\n+        obj.choice_descriptions = copy.copy(self.choice_descriptions)\n+        return obj\n+\n+    def create_option(self, name, value, label, selected, index, subindex, attrs):\n+        option = super().create_option(name, value, label, selected, index, subindex, attrs)\n+        # this implementation does not support groups from ChoiceWidget.optgroups\n+        if value in self.choice_descriptions:\n+            option.update({\"description\": self.choice_descriptions[value]})\n+\n+        return option\ndiff --git a/benefits/eligibility/forms.py b/benefits/eligibility/forms.py\n--- a/benefits/eligibility/forms.py\n+++ b/benefits/eligibility/forms.py\n@@ -18,14 +18,18 @@\n     action_url = \"eligibility:index\"\n     method = \"POST\"\n \n-    verifier = forms.ChoiceField(label=\"\", widget=forms.RadioSelect)\n+    verifier = forms.ChoiceField(label=\"\", widget=widgets.RadioSelect)\n \n     submit_value = _(\"eligibility.buttons.continue\")\n \n     def __init__(self, agency: models.TransitAgency, *args, **kwargs):\n         super().__init__(*args, **kwargs)\n-        choices = [(v.id, _(v.selection_label)) for v in agency.eligibility_verifiers.all()]\n-        self.fields[\"verifier\"].choices = choices\n+        verifiers = agency.eligibility_verifiers.all()\n+\n+        self.fields[\"verifier\"].choices = [(v.id, _(v.selection_label)) for v in verifiers]\n+        self.fields[\"verifier\"].widget.choice_descriptions = {\n+            v.id: _(v.selection_label_description) for v in verifiers if v.selection_label_description\n+        }\n \n \n class EligibilityVerificationForm(forms.Form):\n", "issue": "Enhance form rendering: Radio button list\nThis is a follow-on to #322, to enhance how forms are rendered in the [`page` template](https://github.com/cal-itp/benefits/blob/dev/benefits/core/templates/core/page.html)\r\n\r\n@angela-tran [notes](https://github.com/cal-itp/benefits/pull/337#issuecomment-1076882758):\r\n\r\n> `RadioSelect` in Django 3.2 renders as `<li>` elements. We probably don't want that? Should we add something to `page.html` so that we have more granular control over how radio buttons are shown? (Django docs have an [example](https://docs.djangoproject.com/en/3.2/ref/forms/widgets/#radioselect) of looping over the widgets.)\r\n\r\n![image](https://user-images.githubusercontent.com/1783439/160215029-07dadd9d-e422-49ea-91b3-533485236daa.png)\r\n\r\nThe [State Template form components](https://template.webstandards.ca.gov/sample/form.html) has some example HTML for what might work here?\r\n\r\n```html\r\n<!--Bootstrap4 Custom Radios-->\r\n<div class=\"form-check\">\r\n    <input class=\"form-check-input\" type=\"radio\" name=\"flexRadioDefault\" id=\"customRadio1\">\r\n    <label class=\"form-check-label\" for=\"customRadio1\">\r\n        Toggle this custom radio\r\n    </label>\r\n</div>\r\n<div class=\"form-check\">\r\n    <input class=\"form-check-input\" type=\"radio\" name=\"flexRadioDefault\" id=\"customRadio2\" checked=\"\">\r\n    <label class=\"form-check-label\" for=\"customRadio2\">\r\n        Or toggle this other custom radio\r\n    </label>\r\n</div>\r\n```\r\n\r\nThe comment indicates this is just [Bootstrap 4 radios](https://getbootstrap.com/docs/4.0/components/forms/#radios)?\r\n\r\n@angela-tran [suggests](https://github.com/cal-itp/benefits/pull/337#issuecomment-1076882758):\r\n\r\n> Rendering the `selection_label_description` may involve adding some HTML to the display value in our `choices` tuple. My first step would be to try out the approach in https://stackoverflow.com/questions/2204696/setting-help-text-for-each-choice-in-a-radioselect.\r\n\r\n![image](https://user-images.githubusercontent.com/1783439/160215069-abd2c18b-0ebf-4d78-a202-be7947e70ab5.png)\r\n\n", "before_files": [{"content": "\"\"\"\nThe core application: Helper form widgets.\n\"\"\"\nfrom django.forms import widgets\n\n\nclass FormControlTextInput(widgets.TextInput):\n    \"\"\"A styled text input.\"\"\"\n\n    def __init__(self, pattern=None, placeholder=None, **kwargs):\n        super().__init__(**kwargs)\n\n        self.attrs.update({\"class\": \"form-control form-control-lg\"})\n        if pattern:\n            self.attrs.update({\"pattern\": pattern})\n        if placeholder:\n            self.attrs.update({\"placeholder\": placeholder})\n", "path": "benefits/core/widgets.py"}, {"content": "\"\"\"\nThe eligibility application: Form definition for the eligibility verification flow.\n\"\"\"\nimport logging\n\nfrom django import forms\nfrom django.utils.translation import gettext_lazy as _\n\nfrom benefits.core import models, recaptcha, widgets\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass EligibilityVerifierSelectionForm(forms.Form):\n    \"\"\"Form to capture eligibility verifier selection.\"\"\"\n\n    action_url = \"eligibility:index\"\n    method = \"POST\"\n\n    verifier = forms.ChoiceField(label=\"\", widget=forms.RadioSelect)\n\n    submit_value = _(\"eligibility.buttons.continue\")\n\n    def __init__(self, agency: models.TransitAgency, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        choices = [(v.id, _(v.selection_label)) for v in agency.eligibility_verifiers.all()]\n        self.fields[\"verifier\"].choices = choices\n\n\nclass EligibilityVerificationForm(forms.Form):\n    \"\"\"Form to collect eligibility verification details.\"\"\"\n\n    action_url = \"eligibility:confirm\"\n    method = \"POST\"\n\n    submit_value = _(\"eligibility.forms.confirm.submit\")\n    submitting_value = _(\"eligibility.forms.confirm.submitting\")\n\n    _error_messages = {\n        \"invalid\": _(\"eligibility.forms.confirm.errors.invalid\"),\n        \"missing\": _(\"eligibility.forms.confirm.errors.missing\"),\n    }\n\n    def __init__(self, verifier: models.EligibilityVerifier, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        sub_widget = widgets.FormControlTextInput(placeholder=verifier.form_sub_placeholder)\n        if verifier.form_sub_pattern:\n            sub_widget.attrs.update({\"pattern\": verifier.form_sub_pattern})\n\n        self.fields[\"sub\"] = forms.CharField(label=_(verifier.form_sub_label), widget=sub_widget)\n\n        name_widget = widgets.FormControlTextInput(placeholder=verifier.form_name_placeholder)\n        if verifier.form_name_max_length:\n            name_widget.attrs.update({\"maxlength\": verifier.form_name_max_length})\n\n        self.fields[\"name\"] = forms.CharField(label=_(verifier.form_name_label), widget=name_widget)\n\n    def add_api_errors(self, form_errors):\n        \"\"\"Handle errors passed back from API server related to submitted form values.\"\"\"\n\n        validation_errors = {\n            field: forms.ValidationError(self._error_messages.get(code, _(\"core.pages.error.title\")), code=code)\n            for (field, code) in form_errors.items()\n            if field in self.fields\n        }\n\n        if len(validation_errors) > 0:\n            logger.warning(\"Form fields are invalid\")\n\n        for (field, err) in validation_errors.items():\n            self.add_error(field, err)\n\n    def clean(self):\n        if not recaptcha.verify(self.data):\n            raise forms.ValidationError(\"reCAPTCHA failed\")\n", "path": "benefits/eligibility/forms.py"}], "after_files": [{"content": "\"\"\"\nThe core application: Helper form widgets.\n\"\"\"\nimport copy\nfrom django.forms import widgets\n\n\nclass FormControlTextInput(widgets.TextInput):\n    \"\"\"A styled text input.\"\"\"\n\n    def __init__(self, pattern=None, placeholder=None, **kwargs):\n        super().__init__(**kwargs)\n\n        self.attrs.update({\"class\": \"form-control form-control-lg\"})\n        if pattern:\n            self.attrs.update({\"pattern\": pattern})\n        if placeholder:\n            self.attrs.update({\"placeholder\": placeholder})\n\n\nclass RadioSelect(widgets.RadioSelect):\n    template_name = \"core/widgets/radio_select.html\"\n    option_template_name = \"core/widgets/radio_select_option.html\"\n\n    def __init__(self, choice_descriptions=(), *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.choice_descriptions = list(choice_descriptions)\n\n    def __deepcopy__(self, memo):\n        obj = super().__deepcopy__(memo)\n        obj.choice_descriptions = copy.copy(self.choice_descriptions)\n        return obj\n\n    def create_option(self, name, value, label, selected, index, subindex, attrs):\n        option = super().create_option(name, value, label, selected, index, subindex, attrs)\n        # this implementation does not support groups from ChoiceWidget.optgroups\n        if value in self.choice_descriptions:\n            option.update({\"description\": self.choice_descriptions[value]})\n\n        return option\n", "path": "benefits/core/widgets.py"}, {"content": "\"\"\"\nThe eligibility application: Form definition for the eligibility verification flow.\n\"\"\"\nimport logging\n\nfrom django import forms\nfrom django.utils.translation import gettext_lazy as _\n\nfrom benefits.core import models, recaptcha, widgets\n\n\nlogger = logging.getLogger(__name__)\n\n\nclass EligibilityVerifierSelectionForm(forms.Form):\n    \"\"\"Form to capture eligibility verifier selection.\"\"\"\n\n    action_url = \"eligibility:index\"\n    method = \"POST\"\n\n    verifier = forms.ChoiceField(label=\"\", widget=widgets.RadioSelect)\n\n    submit_value = _(\"eligibility.buttons.continue\")\n\n    def __init__(self, agency: models.TransitAgency, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        verifiers = agency.eligibility_verifiers.all()\n\n        self.fields[\"verifier\"].choices = [(v.id, _(v.selection_label)) for v in verifiers]\n        self.fields[\"verifier\"].widget.choice_descriptions = {\n            v.id: _(v.selection_label_description) for v in verifiers if v.selection_label_description\n        }\n\n\nclass EligibilityVerificationForm(forms.Form):\n    \"\"\"Form to collect eligibility verification details.\"\"\"\n\n    action_url = \"eligibility:confirm\"\n    method = \"POST\"\n\n    submit_value = _(\"eligibility.forms.confirm.submit\")\n    submitting_value = _(\"eligibility.forms.confirm.submitting\")\n\n    _error_messages = {\n        \"invalid\": _(\"eligibility.forms.confirm.errors.invalid\"),\n        \"missing\": _(\"eligibility.forms.confirm.errors.missing\"),\n    }\n\n    def __init__(self, verifier: models.EligibilityVerifier, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n\n        sub_widget = widgets.FormControlTextInput(placeholder=verifier.form_sub_placeholder)\n        if verifier.form_sub_pattern:\n            sub_widget.attrs.update({\"pattern\": verifier.form_sub_pattern})\n\n        self.fields[\"sub\"] = forms.CharField(label=_(verifier.form_sub_label), widget=sub_widget)\n\n        name_widget = widgets.FormControlTextInput(placeholder=verifier.form_name_placeholder)\n        if verifier.form_name_max_length:\n            name_widget.attrs.update({\"maxlength\": verifier.form_name_max_length})\n\n        self.fields[\"name\"] = forms.CharField(label=_(verifier.form_name_label), widget=name_widget)\n\n    def add_api_errors(self, form_errors):\n        \"\"\"Handle errors passed back from API server related to submitted form values.\"\"\"\n\n        validation_errors = {\n            field: forms.ValidationError(self._error_messages.get(code, _(\"core.pages.error.title\")), code=code)\n            for (field, code) in form_errors.items()\n            if field in self.fields\n        }\n\n        if len(validation_errors) > 0:\n            logger.warning(\"Form fields are invalid\")\n\n        for (field, err) in validation_errors.items():\n            self.add_error(field, err)\n\n    def clean(self):\n        if not recaptcha.verify(self.data):\n            raise forms.ValidationError(\"reCAPTCHA failed\")\n", "path": "benefits/eligibility/forms.py"}]}