We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Setting `default` on multiselect widget that uses pandas.Series as `options` causes an error
### Summary

[`st.multiselect`](https://docs.streamlit.io/en/stable/api.html?highlight=options#streamlit.multiselect) is supposed to accept `pandas.Series` objects as labels for the select options. Setting a `default` value while using `options=pandas.Series` leads to:

> StreamlitAPIException : Every Multiselect default value must exist in options 

### Steps to reproduce
Run the below code snippet.

Code snippet:

```python
import streamlit as st
import pandas as pd

names = pd.DataFrame({'labels':["Green","Yellow","Red","Blue"]})
nameSelect = st.multiselect(
    "What are your favorite colors",
    options=names['labels'],
    default=["Yellow"]
)
```

### Is this a regression?

Possibly a core regression.

### Debug info

- Streamlit version: 0.82.0
- Python version: 3.8.5
- OS version: Ubuntu 20.04.2 LTS
- Browser version: Firefox 89.0 (64-bit)

### Additional information

Original source: https://discuss.streamlit.io/t/setting-default-value-on-multiselect-that-uses-a-series-for-the-options/13630


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lib/streamlit/elements/multiselect.py`
Content:
```
1 # Copyright 2018-2021 Streamlit Inc.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 from typing import cast, List
16 
17 import streamlit
18 from streamlit.errors import StreamlitAPIException
19 from streamlit.proto.MultiSelect_pb2 import MultiSelect as MultiSelectProto
20 from streamlit.state.widgets import register_widget
21 from streamlit.type_util import is_type, ensure_iterable
22 from .form import current_form_id
23 from .utils import check_callback_rules, check_session_state_rules
24 
25 
26 class MultiSelectMixin:
27     def multiselect(
28         self,
29         label,
30         options,
31         default=None,
32         format_func=str,
33         key=None,
34         help=None,
35         on_change=None,
36         args=None,
37         kwargs=None,
38     ):
39         """Display a multiselect widget.
40         The multiselect widget starts as empty.
41 
42         Parameters
43         ----------
44         label : str
45             A short label explaining to the user what this select widget is for.
46         options : list, tuple, numpy.ndarray, pandas.Series, or pandas.DataFrame
47             Labels for the select options. This will be cast to str internally
48             by default. For pandas.DataFrame, the first column is selected.
49         default: [str] or None
50             List of default values.
51         format_func : function
52             Function to modify the display of selectbox options. It receives
53             the raw option as an argument and should output the label to be
54             shown for that option. This has no impact on the return value of
55             the selectbox.
56         key : str
57             An optional string to use as the unique key for the widget.
58             If this is omitted, a key will be generated for the widget
59             based on its content. Multiple widgets of the same type may
60             not share the same key.
61         help : str
62             An optional tooltip that gets displayed next to the multiselect.
63         on_change : callable
64             An optional callback invoked when this multiselect's value changes.
65         args : tuple
66             An optional tuple of args to pass to the callback.
67         kwargs : dict
68             An optional dict of kwargs to pass to the callback.
69 
70         Returns
71         -------
72         list
73             A list with the selected options
74 
75         Example
76         -------
77         >>> options = st.multiselect(
78         ...     'What are your favorite colors',
79         ...     ['Green', 'Yellow', 'Red', 'Blue'],
80         ...     ['Yellow', 'Red'])
81         >>>
82         >>> st.write('You selected:', options)
83 
84         .. note::
85            User experience can be degraded for large lists of `options` (100+), as this widget
86            is not designed to handle arbitrary text search efficiently. See this
87            `thread <https://discuss.streamlit.io/t/streamlit-loading-column-data-takes-too-much-time/1791>`_
88            on the Streamlit community forum for more information and
89            `GitHub issue #1059 <https://github.com/streamlit/streamlit/issues/1059>`_ for updates on the issue.
90 
91         """
92         check_callback_rules(self.dg, on_change)
93         check_session_state_rules(default_value=default, key=key)
94 
95         options = ensure_iterable(options)
96 
97         # Perform validation checks and return indices base on the default values.
98         def _check_and_convert_to_indices(options, default_values):
99             if default_values is None and None not in options:
100                 return None
101 
102             if not isinstance(default_values, list):
103                 # This if is done before others because calling if not x (done
104                 # right below) when x is of type pd.Series() or np.array() throws a
105                 # ValueError exception.
106                 if is_type(default_values, "numpy.ndarray") or is_type(
107                     default_values, "pandas.core.series.Series"
108                 ):
109                     default_values = list(default_values)
110                 elif not default_values or default_values in options:
111                     default_values = [default_values]
112                 else:
113                     default_values = list(default_values)
114 
115             for value in default_values:
116                 if value not in options:
117                     raise StreamlitAPIException(
118                         "Every Multiselect default value must exist in options"
119                     )
120 
121             return [options.index(value) for value in default_values]
122 
123         indices = _check_and_convert_to_indices(options, default)
124         multiselect_proto = MultiSelectProto()
125         multiselect_proto.label = label
126         default_value = [] if indices is None else indices
127         multiselect_proto.default[:] = default_value
128         multiselect_proto.options[:] = [str(format_func(option)) for option in options]
129         multiselect_proto.form_id = current_form_id(self.dg)
130         if help is not None:
131             multiselect_proto.help = help
132 
133         def deserialize_multiselect(ui_value, widget_id="") -> List[str]:
134             current_value = ui_value if ui_value is not None else default_value
135             return [options[i] for i in current_value]
136 
137         def serialize_multiselect(value):
138             return _check_and_convert_to_indices(options, value)
139 
140         current_value, set_frontend_value = register_widget(
141             "multiselect",
142             multiselect_proto,
143             user_key=key,
144             on_change_handler=on_change,
145             args=args,
146             kwargs=kwargs,
147             deserializer=deserialize_multiselect,
148             serializer=serialize_multiselect,
149         )
150 
151         if set_frontend_value:
152             multiselect_proto.value[:] = _check_and_convert_to_indices(
153                 options, current_value
154             )
155             multiselect_proto.set_value = True
156 
157         self.dg._enqueue("multiselect", multiselect_proto)
158         return current_value
159 
160     @property
161     def dg(self) -> "streamlit.delta_generator.DeltaGenerator":
162         """Get our DeltaGenerator."""
163         return cast("streamlit.delta_generator.DeltaGenerator", self)
164
```
--- 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/lib/streamlit/elements/multiselect.py b/lib/streamlit/elements/multiselect.py
--- a/lib/streamlit/elements/multiselect.py
+++ b/lib/streamlit/elements/multiselect.py
@@ -19,6 +19,7 @@
 from streamlit.proto.MultiSelect_pb2 import MultiSelect as MultiSelectProto
 from streamlit.state.widgets import register_widget
 from streamlit.type_util import is_type, ensure_iterable
+
 from .form import current_form_id
 from .utils import check_callback_rules, check_session_state_rules
 
@@ -112,6 +113,9 @@
                 else:
                     default_values = list(default_values)
 
+            if not isinstance(options, list):
+                options = list(options)
+
             for value in default_values:
                 if value not in options:
                     raise StreamlitAPIException(

{"golden_diff": "diff --git a/lib/streamlit/elements/multiselect.py b/lib/streamlit/elements/multiselect.py\n--- a/lib/streamlit/elements/multiselect.py\n+++ b/lib/streamlit/elements/multiselect.py\n@@ -19,6 +19,7 @@\n from streamlit.proto.MultiSelect_pb2 import MultiSelect as MultiSelectProto\n from streamlit.state.widgets import register_widget\n from streamlit.type_util import is_type, ensure_iterable\n+\n from .form import current_form_id\n from .utils import check_callback_rules, check_session_state_rules\n \n@@ -112,6 +113,9 @@\n                 else:\n                     default_values = list(default_values)\n \n+            if not isinstance(options, list):\n+                options = list(options)\n+\n             for value in default_values:\n                 if value not in options:\n                     raise StreamlitAPIException(\n", "issue": "Setting `default` on multiselect widget that uses pandas.Series as `options` causes an error\n### Summary\r\n\r\n[`st.multiselect`](https://docs.streamlit.io/en/stable/api.html?highlight=options#streamlit.multiselect) is supposed to accept `pandas.Series` objects as labels for the select options. Setting a `default` value while using `options=pandas.Series` leads to:\r\n\r\n> StreamlitAPIException : Every Multiselect default value must exist in options \r\n\r\n### Steps to reproduce\r\nRun the below code snippet.\r\n\r\nCode snippet:\r\n\r\n```python\r\nimport streamlit as st\r\nimport pandas as pd\r\n\r\nnames = pd.DataFrame({'labels':[\"Green\",\"Yellow\",\"Red\",\"Blue\"]})\r\nnameSelect = st.multiselect(\r\n    \"What are your favorite colors\",\r\n    options=names['labels'],\r\n    default=[\"Yellow\"]\r\n)\r\n```\r\n\r\n### Is this a regression?\r\n\r\nPossibly a core regression.\r\n\r\n### Debug info\r\n\r\n- Streamlit version: 0.82.0\r\n- Python version: 3.8.5\r\n- OS version: Ubuntu 20.04.2 LTS\r\n- Browser version: Firefox 89.0 (64-bit)\r\n\r\n### Additional information\r\n\r\nOriginal source: https://discuss.streamlit.io/t/setting-default-value-on-multiselect-that-uses-a-series-for-the-options/13630\r\n\n", "before_files": [{"content": "# Copyright 2018-2021 Streamlit Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import cast, List\n\nimport streamlit\nfrom streamlit.errors import StreamlitAPIException\nfrom streamlit.proto.MultiSelect_pb2 import MultiSelect as MultiSelectProto\nfrom streamlit.state.widgets import register_widget\nfrom streamlit.type_util import is_type, ensure_iterable\nfrom .form import current_form_id\nfrom .utils import check_callback_rules, check_session_state_rules\n\n\nclass MultiSelectMixin:\n    def multiselect(\n        self,\n        label,\n        options,\n        default=None,\n        format_func=str,\n        key=None,\n        help=None,\n        on_change=None,\n        args=None,\n        kwargs=None,\n    ):\n        \"\"\"Display a multiselect widget.\n        The multiselect widget starts as empty.\n\n        Parameters\n        ----------\n        label : str\n            A short label explaining to the user what this select widget is for.\n        options : list, tuple, numpy.ndarray, pandas.Series, or pandas.DataFrame\n            Labels for the select options. This will be cast to str internally\n            by default. For pandas.DataFrame, the first column is selected.\n        default: [str] or None\n            List of default values.\n        format_func : function\n            Function to modify the display of selectbox options. It receives\n            the raw option as an argument and should output the label to be\n            shown for that option. This has no impact on the return value of\n            the selectbox.\n        key : str\n            An optional string to use as the unique key for the widget.\n            If this is omitted, a key will be generated for the widget\n            based on its content. Multiple widgets of the same type may\n            not share the same key.\n        help : str\n            An optional tooltip that gets displayed next to the multiselect.\n        on_change : callable\n            An optional callback invoked when this multiselect's value changes.\n        args : tuple\n            An optional tuple of args to pass to the callback.\n        kwargs : dict\n            An optional dict of kwargs to pass to the callback.\n\n        Returns\n        -------\n        list\n            A list with the selected options\n\n        Example\n        -------\n        >>> options = st.multiselect(\n        ...     'What are your favorite colors',\n        ...     ['Green', 'Yellow', 'Red', 'Blue'],\n        ...     ['Yellow', 'Red'])\n        >>>\n        >>> st.write('You selected:', options)\n\n        .. note::\n           User experience can be degraded for large lists of `options` (100+), as this widget\n           is not designed to handle arbitrary text search efficiently. See this\n           `thread <https://discuss.streamlit.io/t/streamlit-loading-column-data-takes-too-much-time/1791>`_\n           on the Streamlit community forum for more information and\n           `GitHub issue #1059 <https://github.com/streamlit/streamlit/issues/1059>`_ for updates on the issue.\n\n        \"\"\"\n        check_callback_rules(self.dg, on_change)\n        check_session_state_rules(default_value=default, key=key)\n\n        options = ensure_iterable(options)\n\n        # Perform validation checks and return indices base on the default values.\n        def _check_and_convert_to_indices(options, default_values):\n            if default_values is None and None not in options:\n                return None\n\n            if not isinstance(default_values, list):\n                # This if is done before others because calling if not x (done\n                # right below) when x is of type pd.Series() or np.array() throws a\n                # ValueError exception.\n                if is_type(default_values, \"numpy.ndarray\") or is_type(\n                    default_values, \"pandas.core.series.Series\"\n                ):\n                    default_values = list(default_values)\n                elif not default_values or default_values in options:\n                    default_values = [default_values]\n                else:\n                    default_values = list(default_values)\n\n            for value in default_values:\n                if value not in options:\n                    raise StreamlitAPIException(\n                        \"Every Multiselect default value must exist in options\"\n                    )\n\n            return [options.index(value) for value in default_values]\n\n        indices = _check_and_convert_to_indices(options, default)\n        multiselect_proto = MultiSelectProto()\n        multiselect_proto.label = label\n        default_value = [] if indices is None else indices\n        multiselect_proto.default[:] = default_value\n        multiselect_proto.options[:] = [str(format_func(option)) for option in options]\n        multiselect_proto.form_id = current_form_id(self.dg)\n        if help is not None:\n            multiselect_proto.help = help\n\n        def deserialize_multiselect(ui_value, widget_id=\"\") -> List[str]:\n            current_value = ui_value if ui_value is not None else default_value\n            return [options[i] for i in current_value]\n\n        def serialize_multiselect(value):\n            return _check_and_convert_to_indices(options, value)\n\n        current_value, set_frontend_value = register_widget(\n            \"multiselect\",\n            multiselect_proto,\n            user_key=key,\n            on_change_handler=on_change,\n            args=args,\n            kwargs=kwargs,\n            deserializer=deserialize_multiselect,\n            serializer=serialize_multiselect,\n        )\n\n        if set_frontend_value:\n            multiselect_proto.value[:] = _check_and_convert_to_indices(\n                options, current_value\n            )\n            multiselect_proto.set_value = True\n\n        self.dg._enqueue(\"multiselect\", multiselect_proto)\n        return current_value\n\n    @property\n    def dg(self) -> \"streamlit.delta_generator.DeltaGenerator\":\n        \"\"\"Get our DeltaGenerator.\"\"\"\n        return cast(\"streamlit.delta_generator.DeltaGenerator\", self)\n", "path": "lib/streamlit/elements/multiselect.py"}], "after_files": [{"content": "# Copyright 2018-2021 Streamlit Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#    http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nfrom typing import cast, List\n\nimport streamlit\nfrom streamlit.errors import StreamlitAPIException\nfrom streamlit.proto.MultiSelect_pb2 import MultiSelect as MultiSelectProto\nfrom streamlit.state.widgets import register_widget\nfrom streamlit.type_util import is_type, ensure_iterable\n\nfrom .form import current_form_id\nfrom .utils import check_callback_rules, check_session_state_rules\n\n\nclass MultiSelectMixin:\n    def multiselect(\n        self,\n        label,\n        options,\n        default=None,\n        format_func=str,\n        key=None,\n        help=None,\n        on_change=None,\n        args=None,\n        kwargs=None,\n    ):\n        \"\"\"Display a multiselect widget.\n        The multiselect widget starts as empty.\n\n        Parameters\n        ----------\n        label : str\n            A short label explaining to the user what this select widget is for.\n        options : list, tuple, numpy.ndarray, pandas.Series, or pandas.DataFrame\n            Labels for the select options. This will be cast to str internally\n            by default. For pandas.DataFrame, the first column is selected.\n        default: [str] or None\n            List of default values.\n        format_func : function\n            Function to modify the display of selectbox options. It receives\n            the raw option as an argument and should output the label to be\n            shown for that option. This has no impact on the return value of\n            the selectbox.\n        key : str\n            An optional string to use as the unique key for the widget.\n            If this is omitted, a key will be generated for the widget\n            based on its content. Multiple widgets of the same type may\n            not share the same key.\n        help : str\n            An optional tooltip that gets displayed next to the multiselect.\n        on_change : callable\n            An optional callback invoked when this multiselect's value changes.\n        args : tuple\n            An optional tuple of args to pass to the callback.\n        kwargs : dict\n            An optional dict of kwargs to pass to the callback.\n\n        Returns\n        -------\n        list\n            A list with the selected options\n\n        Example\n        -------\n        >>> options = st.multiselect(\n        ...     'What are your favorite colors',\n        ...     ['Green', 'Yellow', 'Red', 'Blue'],\n        ...     ['Yellow', 'Red'])\n        >>>\n        >>> st.write('You selected:', options)\n\n        .. note::\n           User experience can be degraded for large lists of `options` (100+), as this widget\n           is not designed to handle arbitrary text search efficiently. See this\n           `thread <https://discuss.streamlit.io/t/streamlit-loading-column-data-takes-too-much-time/1791>`_\n           on the Streamlit community forum for more information and\n           `GitHub issue #1059 <https://github.com/streamlit/streamlit/issues/1059>`_ for updates on the issue.\n\n        \"\"\"\n        check_callback_rules(self.dg, on_change)\n        check_session_state_rules(default_value=default, key=key)\n\n        options = ensure_iterable(options)\n\n        # Perform validation checks and return indices base on the default values.\n        def _check_and_convert_to_indices(options, default_values):\n            if default_values is None and None not in options:\n                return None\n\n            if not isinstance(default_values, list):\n                # This if is done before others because calling if not x (done\n                # right below) when x is of type pd.Series() or np.array() throws a\n                # ValueError exception.\n                if is_type(default_values, \"numpy.ndarray\") or is_type(\n                    default_values, \"pandas.core.series.Series\"\n                ):\n                    default_values = list(default_values)\n                elif not default_values or default_values in options:\n                    default_values = [default_values]\n                else:\n                    default_values = list(default_values)\n\n            if not isinstance(options, list):\n                options = list(options)\n\n            for value in default_values:\n                if value not in options:\n                    raise StreamlitAPIException(\n                        \"Every Multiselect default value must exist in options\"\n                    )\n\n            return [options.index(value) for value in default_values]\n\n        indices = _check_and_convert_to_indices(options, default)\n        multiselect_proto = MultiSelectProto()\n        multiselect_proto.label = label\n        default_value = [] if indices is None else indices\n        multiselect_proto.default[:] = default_value\n        multiselect_proto.options[:] = [str(format_func(option)) for option in options]\n        multiselect_proto.form_id = current_form_id(self.dg)\n        if help is not None:\n            multiselect_proto.help = help\n\n        def deserialize_multiselect(ui_value, widget_id=\"\") -> List[str]:\n            current_value = ui_value if ui_value is not None else default_value\n            return [options[i] for i in current_value]\n\n        def serialize_multiselect(value):\n            return _check_and_convert_to_indices(options, value)\n\n        current_value, set_frontend_value = register_widget(\n            \"multiselect\",\n            multiselect_proto,\n            user_key=key,\n            on_change_handler=on_change,\n            args=args,\n            kwargs=kwargs,\n            deserializer=deserialize_multiselect,\n            serializer=serialize_multiselect,\n        )\n\n        if set_frontend_value:\n            multiselect_proto.value[:] = _check_and_convert_to_indices(\n                options, current_value\n            )\n            multiselect_proto.set_value = True\n\n        self.dg._enqueue(\"multiselect\", multiselect_proto)\n        return current_value\n\n    @property\n    def dg(self) -> \"streamlit.delta_generator.DeltaGenerator\":\n        \"\"\"Get our DeltaGenerator.\"\"\"\n        return cast(\"streamlit.delta_generator.DeltaGenerator\", self)\n", "path": "lib/streamlit/elements/multiselect.py"}]}