We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Additional context for `Mixed types x and y in attribute value sequence` warnings
**Is your feature request related to a problem?**
I'm getting a whole lot of warnings like

```
opentelemetry.attributes.Mixed types str and int in attribute value sequence
```

But they're missing context in order to resolve them. I'd like to know what attribute it is that has mixed types.

**Describe the solution you'd like**
Include `key` value in the message to add some more context and give a better chance to resolve the warning.

**Describe alternatives you've considered**

None

**Additional context**

Log is emitted from the lines below

https://github.com/open-telemetry/opentelemetry-python/blob/e0e6a3a940c16c1df6493e258ccfbc57ac38cf96/opentelemetry-api/src/opentelemetry/attributes/__init__.py#L86-L91

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `opentelemetry-api/src/opentelemetry/attributes/__init__.py`
Content:
```
1 # Copyright The OpenTelemetry Authors
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 # type: ignore
15 
16 import logging
17 import threading
18 from collections import OrderedDict
19 from collections.abc import MutableMapping
20 from typing import Optional, Sequence, Union
21 
22 from opentelemetry.util import types
23 
24 # bytes are accepted as a user supplied value for attributes but
25 # decoded to strings internally.
26 _VALID_ATTR_VALUE_TYPES = (bool, str, bytes, int, float)
27 
28 
29 _logger = logging.getLogger(__name__)
30 
31 
32 def _clean_attribute(
33     key: str, value: types.AttributeValue, max_len: Optional[int]
34 ) -> Optional[types.AttributeValue]:
35     """Checks if attribute value is valid and cleans it if required.
36 
37     The function returns the cleaned value or None if the value is not valid.
38 
39     An attribute value is valid if it is either:
40         - A primitive type: string, boolean, double precision floating
41             point (IEEE 754-1985) or integer.
42         - An array of primitive type values. The array MUST be homogeneous,
43             i.e. it MUST NOT contain values of different types.
44 
45     An attribute needs cleansing if:
46         - Its length is greater than the maximum allowed length.
47         - It needs to be encoded/decoded e.g, bytes to strings.
48     """
49 
50     if not (key and isinstance(key, str)):
51         _logger.warning("invalid key `%s`. must be non-empty string.", key)
52         return None
53 
54     if isinstance(value, _VALID_ATTR_VALUE_TYPES):
55         return _clean_attribute_value(value, max_len)
56 
57     if isinstance(value, Sequence):
58         sequence_first_valid_type = None
59         cleaned_seq = []
60 
61         for element in value:
62             element = _clean_attribute_value(element, max_len)
63             if element is None:
64                 cleaned_seq.append(element)
65                 continue
66 
67             element_type = type(element)
68             # Reject attribute value if sequence contains a value with an incompatible type.
69             if element_type not in _VALID_ATTR_VALUE_TYPES:
70                 _logger.warning(
71                     "Invalid type %s in attribute value sequence. Expected one of "
72                     "%s or None",
73                     element_type.__name__,
74                     [
75                         valid_type.__name__
76                         for valid_type in _VALID_ATTR_VALUE_TYPES
77                     ],
78                 )
79                 return None
80 
81             # The type of the sequence must be homogeneous. The first non-None
82             # element determines the type of the sequence
83             if sequence_first_valid_type is None:
84                 sequence_first_valid_type = element_type
85             # use equality instead of isinstance as isinstance(True, int) evaluates to True
86             elif element_type != sequence_first_valid_type:
87                 _logger.warning(
88                     "Mixed types %s and %s in attribute value sequence",
89                     sequence_first_valid_type.__name__,
90                     type(element).__name__,
91                 )
92                 return None
93 
94             cleaned_seq.append(element)
95 
96         # Freeze mutable sequences defensively
97         return tuple(cleaned_seq)
98 
99     _logger.warning(
100         "Invalid type %s for attribute '%s' value. Expected one of %s or a "
101         "sequence of those types",
102         type(value).__name__,
103         key,
104         [valid_type.__name__ for valid_type in _VALID_ATTR_VALUE_TYPES],
105     )
106     return None
107 
108 
109 def _clean_attribute_value(
110     value: types.AttributeValue, limit: Optional[int]
111 ) -> Union[types.AttributeValue, None]:
112     if value is None:
113         return None
114 
115     if isinstance(value, bytes):
116         try:
117             value = value.decode()
118         except UnicodeDecodeError:
119             _logger.warning("Byte attribute could not be decoded.")
120             return None
121 
122     if limit is not None and isinstance(value, str):
123         value = value[:limit]
124     return value
125 
126 
127 class BoundedAttributes(MutableMapping):
128     """An ordered dict with a fixed max capacity.
129 
130     Oldest elements are dropped when the dict is full and a new element is
131     added.
132     """
133 
134     def __init__(
135         self,
136         maxlen: Optional[int] = None,
137         attributes: types.Attributes = None,
138         immutable: bool = True,
139         max_value_len: Optional[int] = None,
140     ):
141         if maxlen is not None:
142             if not isinstance(maxlen, int) or maxlen < 0:
143                 raise ValueError(
144                     "maxlen must be valid int greater or equal to 0"
145                 )
146         self.maxlen = maxlen
147         self.dropped = 0
148         self.max_value_len = max_value_len
149         self._dict = OrderedDict()  # type: OrderedDict
150         self._lock = threading.Lock()  # type: threading.Lock
151         if attributes:
152             for key, value in attributes.items():
153                 self[key] = value
154         self._immutable = immutable
155 
156     def __repr__(self):
157         return (
158             f"{type(self).__name__}({dict(self._dict)}, maxlen={self.maxlen})"
159         )
160 
161     def __getitem__(self, key):
162         return self._dict[key]
163 
164     def __setitem__(self, key, value):
165         if getattr(self, "_immutable", False):
166             raise TypeError
167         with self._lock:
168             if self.maxlen is not None and self.maxlen == 0:
169                 self.dropped += 1
170                 return
171 
172             value = _clean_attribute(key, value, self.max_value_len)
173             if value is not None:
174                 if key in self._dict:
175                     del self._dict[key]
176                 elif (
177                     self.maxlen is not None and len(self._dict) == self.maxlen
178                 ):
179                     self._dict.popitem(last=False)
180                     self.dropped += 1
181 
182                 self._dict[key] = value
183 
184     def __delitem__(self, key):
185         if getattr(self, "_immutable", False):
186             raise TypeError
187         with self._lock:
188             del self._dict[key]
189 
190     def __iter__(self):
191         with self._lock:
192             return iter(self._dict.copy())
193 
194     def __len__(self):
195         return len(self._dict)
196 
197     def copy(self):
198         return self._dict.copy()
199
```
--- 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/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py
--- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py
+++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py
@@ -85,7 +85,8 @@
             # use equality instead of isinstance as isinstance(True, int) evaluates to True
             elif element_type != sequence_first_valid_type:
                 _logger.warning(
-                    "Mixed types %s and %s in attribute value sequence",
+                    "Attribute %r mixes types %s and %s in attribute value sequence",
+                    key,
                     sequence_first_valid_type.__name__,
                     type(element).__name__,
                 )

{"golden_diff": "diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py\n--- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py\n+++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py\n@@ -85,7 +85,8 @@\n             # use equality instead of isinstance as isinstance(True, int) evaluates to True\n             elif element_type != sequence_first_valid_type:\n                 _logger.warning(\n-                    \"Mixed types %s and %s in attribute value sequence\",\n+                    \"Attribute %r mixes types %s and %s in attribute value sequence\",\n+                    key,\n                     sequence_first_valid_type.__name__,\n                     type(element).__name__,\n                 )\n", "issue": "Additional context for `Mixed types x and y in attribute value sequence` warnings\n**Is your feature request related to a problem?**\r\nI'm getting a whole lot of warnings like\r\n\r\n```\r\nopentelemetry.attributes.Mixed types str and int in attribute value sequence\r\n```\r\n\r\nBut they're missing context in order to resolve them. I'd like to know what attribute it is that has mixed types.\r\n\r\n**Describe the solution you'd like**\r\nInclude `key` value in the message to add some more context and give a better chance to resolve the warning.\r\n\r\n**Describe alternatives you've considered**\r\n\r\nNone\r\n\r\n**Additional context**\r\n\r\nLog is emitted from the lines below\r\n\r\nhttps://github.com/open-telemetry/opentelemetry-python/blob/e0e6a3a940c16c1df6493e258ccfbc57ac38cf96/opentelemetry-api/src/opentelemetry/attributes/__init__.py#L86-L91\n", "before_files": [{"content": "# Copyright The OpenTelemetry Authors\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# type: ignore\n\nimport logging\nimport threading\nfrom collections import OrderedDict\nfrom collections.abc import MutableMapping\nfrom typing import Optional, Sequence, Union\n\nfrom opentelemetry.util import types\n\n# bytes are accepted as a user supplied value for attributes but\n# decoded to strings internally.\n_VALID_ATTR_VALUE_TYPES = (bool, str, bytes, int, float)\n\n\n_logger = logging.getLogger(__name__)\n\n\ndef _clean_attribute(\n    key: str, value: types.AttributeValue, max_len: Optional[int]\n) -> Optional[types.AttributeValue]:\n    \"\"\"Checks if attribute value is valid and cleans it if required.\n\n    The function returns the cleaned value or None if the value is not valid.\n\n    An attribute value is valid if it is either:\n        - A primitive type: string, boolean, double precision floating\n            point (IEEE 754-1985) or integer.\n        - An array of primitive type values. The array MUST be homogeneous,\n            i.e. it MUST NOT contain values of different types.\n\n    An attribute needs cleansing if:\n        - Its length is greater than the maximum allowed length.\n        - It needs to be encoded/decoded e.g, bytes to strings.\n    \"\"\"\n\n    if not (key and isinstance(key, str)):\n        _logger.warning(\"invalid key `%s`. must be non-empty string.\", key)\n        return None\n\n    if isinstance(value, _VALID_ATTR_VALUE_TYPES):\n        return _clean_attribute_value(value, max_len)\n\n    if isinstance(value, Sequence):\n        sequence_first_valid_type = None\n        cleaned_seq = []\n\n        for element in value:\n            element = _clean_attribute_value(element, max_len)\n            if element is None:\n                cleaned_seq.append(element)\n                continue\n\n            element_type = type(element)\n            # Reject attribute value if sequence contains a value with an incompatible type.\n            if element_type not in _VALID_ATTR_VALUE_TYPES:\n                _logger.warning(\n                    \"Invalid type %s in attribute value sequence. Expected one of \"\n                    \"%s or None\",\n                    element_type.__name__,\n                    [\n                        valid_type.__name__\n                        for valid_type in _VALID_ATTR_VALUE_TYPES\n                    ],\n                )\n                return None\n\n            # The type of the sequence must be homogeneous. The first non-None\n            # element determines the type of the sequence\n            if sequence_first_valid_type is None:\n                sequence_first_valid_type = element_type\n            # use equality instead of isinstance as isinstance(True, int) evaluates to True\n            elif element_type != sequence_first_valid_type:\n                _logger.warning(\n                    \"Mixed types %s and %s in attribute value sequence\",\n                    sequence_first_valid_type.__name__,\n                    type(element).__name__,\n                )\n                return None\n\n            cleaned_seq.append(element)\n\n        # Freeze mutable sequences defensively\n        return tuple(cleaned_seq)\n\n    _logger.warning(\n        \"Invalid type %s for attribute '%s' value. Expected one of %s or a \"\n        \"sequence of those types\",\n        type(value).__name__,\n        key,\n        [valid_type.__name__ for valid_type in _VALID_ATTR_VALUE_TYPES],\n    )\n    return None\n\n\ndef _clean_attribute_value(\n    value: types.AttributeValue, limit: Optional[int]\n) -> Union[types.AttributeValue, None]:\n    if value is None:\n        return None\n\n    if isinstance(value, bytes):\n        try:\n            value = value.decode()\n        except UnicodeDecodeError:\n            _logger.warning(\"Byte attribute could not be decoded.\")\n            return None\n\n    if limit is not None and isinstance(value, str):\n        value = value[:limit]\n    return value\n\n\nclass BoundedAttributes(MutableMapping):\n    \"\"\"An ordered dict with a fixed max capacity.\n\n    Oldest elements are dropped when the dict is full and a new element is\n    added.\n    \"\"\"\n\n    def __init__(\n        self,\n        maxlen: Optional[int] = None,\n        attributes: types.Attributes = None,\n        immutable: bool = True,\n        max_value_len: Optional[int] = None,\n    ):\n        if maxlen is not None:\n            if not isinstance(maxlen, int) or maxlen < 0:\n                raise ValueError(\n                    \"maxlen must be valid int greater or equal to 0\"\n                )\n        self.maxlen = maxlen\n        self.dropped = 0\n        self.max_value_len = max_value_len\n        self._dict = OrderedDict()  # type: OrderedDict\n        self._lock = threading.Lock()  # type: threading.Lock\n        if attributes:\n            for key, value in attributes.items():\n                self[key] = value\n        self._immutable = immutable\n\n    def __repr__(self):\n        return (\n            f\"{type(self).__name__}({dict(self._dict)}, maxlen={self.maxlen})\"\n        )\n\n    def __getitem__(self, key):\n        return self._dict[key]\n\n    def __setitem__(self, key, value):\n        if getattr(self, \"_immutable\", False):\n            raise TypeError\n        with self._lock:\n            if self.maxlen is not None and self.maxlen == 0:\n                self.dropped += 1\n                return\n\n            value = _clean_attribute(key, value, self.max_value_len)\n            if value is not None:\n                if key in self._dict:\n                    del self._dict[key]\n                elif (\n                    self.maxlen is not None and len(self._dict) == self.maxlen\n                ):\n                    self._dict.popitem(last=False)\n                    self.dropped += 1\n\n                self._dict[key] = value\n\n    def __delitem__(self, key):\n        if getattr(self, \"_immutable\", False):\n            raise TypeError\n        with self._lock:\n            del self._dict[key]\n\n    def __iter__(self):\n        with self._lock:\n            return iter(self._dict.copy())\n\n    def __len__(self):\n        return len(self._dict)\n\n    def copy(self):\n        return self._dict.copy()\n", "path": "opentelemetry-api/src/opentelemetry/attributes/__init__.py"}], "after_files": [{"content": "# Copyright The OpenTelemetry Authors\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# type: ignore\n\nimport logging\nimport threading\nfrom collections import OrderedDict\nfrom collections.abc import MutableMapping\nfrom typing import Optional, Sequence, Union\n\nfrom opentelemetry.util import types\n\n# bytes are accepted as a user supplied value for attributes but\n# decoded to strings internally.\n_VALID_ATTR_VALUE_TYPES = (bool, str, bytes, int, float)\n\n\n_logger = logging.getLogger(__name__)\n\n\ndef _clean_attribute(\n    key: str, value: types.AttributeValue, max_len: Optional[int]\n) -> Optional[types.AttributeValue]:\n    \"\"\"Checks if attribute value is valid and cleans it if required.\n\n    The function returns the cleaned value or None if the value is not valid.\n\n    An attribute value is valid if it is either:\n        - A primitive type: string, boolean, double precision floating\n            point (IEEE 754-1985) or integer.\n        - An array of primitive type values. The array MUST be homogeneous,\n            i.e. it MUST NOT contain values of different types.\n\n    An attribute needs cleansing if:\n        - Its length is greater than the maximum allowed length.\n        - It needs to be encoded/decoded e.g, bytes to strings.\n    \"\"\"\n\n    if not (key and isinstance(key, str)):\n        _logger.warning(\"invalid key `%s`. must be non-empty string.\", key)\n        return None\n\n    if isinstance(value, _VALID_ATTR_VALUE_TYPES):\n        return _clean_attribute_value(value, max_len)\n\n    if isinstance(value, Sequence):\n        sequence_first_valid_type = None\n        cleaned_seq = []\n\n        for element in value:\n            element = _clean_attribute_value(element, max_len)\n            if element is None:\n                cleaned_seq.append(element)\n                continue\n\n            element_type = type(element)\n            # Reject attribute value if sequence contains a value with an incompatible type.\n            if element_type not in _VALID_ATTR_VALUE_TYPES:\n                _logger.warning(\n                    \"Invalid type %s in attribute value sequence. Expected one of \"\n                    \"%s or None\",\n                    element_type.__name__,\n                    [\n                        valid_type.__name__\n                        for valid_type in _VALID_ATTR_VALUE_TYPES\n                    ],\n                )\n                return None\n\n            # The type of the sequence must be homogeneous. The first non-None\n            # element determines the type of the sequence\n            if sequence_first_valid_type is None:\n                sequence_first_valid_type = element_type\n            # use equality instead of isinstance as isinstance(True, int) evaluates to True\n            elif element_type != sequence_first_valid_type:\n                _logger.warning(\n                    \"Attribute %r mixes types %s and %s in attribute value sequence\",\n                    key,\n                    sequence_first_valid_type.__name__,\n                    type(element).__name__,\n                )\n                return None\n\n            cleaned_seq.append(element)\n\n        # Freeze mutable sequences defensively\n        return tuple(cleaned_seq)\n\n    _logger.warning(\n        \"Invalid type %s for attribute '%s' value. Expected one of %s or a \"\n        \"sequence of those types\",\n        type(value).__name__,\n        key,\n        [valid_type.__name__ for valid_type in _VALID_ATTR_VALUE_TYPES],\n    )\n    return None\n\n\ndef _clean_attribute_value(\n    value: types.AttributeValue, limit: Optional[int]\n) -> Union[types.AttributeValue, None]:\n    if value is None:\n        return None\n\n    if isinstance(value, bytes):\n        try:\n            value = value.decode()\n        except UnicodeDecodeError:\n            _logger.warning(\"Byte attribute could not be decoded.\")\n            return None\n\n    if limit is not None and isinstance(value, str):\n        value = value[:limit]\n    return value\n\n\nclass BoundedAttributes(MutableMapping):\n    \"\"\"An ordered dict with a fixed max capacity.\n\n    Oldest elements are dropped when the dict is full and a new element is\n    added.\n    \"\"\"\n\n    def __init__(\n        self,\n        maxlen: Optional[int] = None,\n        attributes: types.Attributes = None,\n        immutable: bool = True,\n        max_value_len: Optional[int] = None,\n    ):\n        if maxlen is not None:\n            if not isinstance(maxlen, int) or maxlen < 0:\n                raise ValueError(\n                    \"maxlen must be valid int greater or equal to 0\"\n                )\n        self.maxlen = maxlen\n        self.dropped = 0\n        self.max_value_len = max_value_len\n        self._dict = OrderedDict()  # type: OrderedDict\n        self._lock = threading.Lock()  # type: threading.Lock\n        if attributes:\n            for key, value in attributes.items():\n                self[key] = value\n        self._immutable = immutable\n\n    def __repr__(self):\n        return (\n            f\"{type(self).__name__}({dict(self._dict)}, maxlen={self.maxlen})\"\n        )\n\n    def __getitem__(self, key):\n        return self._dict[key]\n\n    def __setitem__(self, key, value):\n        if getattr(self, \"_immutable\", False):\n            raise TypeError\n        with self._lock:\n            if self.maxlen is not None and self.maxlen == 0:\n                self.dropped += 1\n                return\n\n            value = _clean_attribute(key, value, self.max_value_len)\n            if value is not None:\n                if key in self._dict:\n                    del self._dict[key]\n                elif (\n                    self.maxlen is not None and len(self._dict) == self.maxlen\n                ):\n                    self._dict.popitem(last=False)\n                    self.dropped += 1\n\n                self._dict[key] = value\n\n    def __delitem__(self, key):\n        if getattr(self, \"_immutable\", False):\n            raise TypeError\n        with self._lock:\n            del self._dict[key]\n\n    def __iter__(self):\n        with self._lock:\n            return iter(self._dict.copy())\n\n    def __len__(self):\n        return len(self._dict)\n\n    def copy(self):\n        return self._dict.copy()\n", "path": "opentelemetry-api/src/opentelemetry/attributes/__init__.py"}]}