We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
OT Trace propagator fails with exception when no headers are present
**Describe your environment**
Latest version (main branch) of both opentelemetry-python and opentelemetry-python-contrib

**Steps to reproduce**
```python
from opentelemetry.propagators.ot_trace import OTTracePropagator
from opentelemetry.propagators.textmap import DictGetter

getter = DictGetter()
carrier = {}

propagator = OTTracePropagator()
propagator.extract(getter, carrier)
```
results in:
```
Traceback (most recent call last):
  File "repro.py", line 8, in <module>
    propagator.extract(getter, {})
  File "(...)/opentelemetry-python-contrib/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py", line 76, in extract
    and _valid_extract_traceid.fullmatch(traceid) is not None
TypeError: expected string or bytes-like object
```
**What is the expected behavior?**
Propagator extraction returns an unmodified context due to lack of relevant headers in the carrier.
> If a value can not be parsed from the carrier, for a cross-cutting concern, the implementation MUST NOT throw an exception and MUST NOT store a new value in the Context, in order to preserve any previously existing valid value.

_from [OTel specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md#extract)_

**What is the actual behavior?**
Propagator extraction fails with an exception when no headers are present in the carrier.

**Additional context**
N/A


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__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 
15 from re import compile as re_compile
16 from typing import Iterable, Optional
17 
18 from opentelemetry.baggage import get_all, set_baggage
19 from opentelemetry.context import Context
20 from opentelemetry.propagators.textmap import (
21     Getter,
22     Setter,
23     TextMapPropagator,
24     TextMapPropagatorT,
25 )
26 from opentelemetry.trace import (
27     INVALID_SPAN_ID,
28     INVALID_TRACE_ID,
29     NonRecordingSpan,
30     SpanContext,
31     TraceFlags,
32     get_current_span,
33     set_span_in_context,
34 )
35 
36 OT_TRACE_ID_HEADER = "ot-tracer-traceid"
37 OT_SPAN_ID_HEADER = "ot-tracer-spanid"
38 OT_SAMPLED_HEADER = "ot-tracer-sampled"
39 OT_BAGGAGE_PREFIX = "ot-baggage-"
40 
41 _valid_header_name = re_compile(r"[\w_^`!#$%&'*+.|~]+")
42 _valid_header_value = re_compile(r"[\t\x20-\x7e\x80-\xff]+")
43 _valid_extract_traceid = re_compile(r"[0-9a-f]{1,32}")
44 _valid_extract_spanid = re_compile(r"[0-9a-f]{1,16}")
45 
46 
47 class OTTracePropagator(TextMapPropagator):
48     """Propagator for the OTTrace HTTP header format"""
49 
50     def extract(
51         self,
52         getter: Getter[TextMapPropagatorT],
53         carrier: TextMapPropagatorT,
54         context: Optional[Context] = None,
55     ) -> Context:
56 
57         traceid = _extract_first_element(
58             getter.get(carrier, OT_TRACE_ID_HEADER)
59         )
60 
61         spanid = _extract_first_element(getter.get(carrier, OT_SPAN_ID_HEADER))
62 
63         sampled = _extract_first_element(
64             getter.get(carrier, OT_SAMPLED_HEADER)
65         )
66 
67         if sampled == "true":
68             traceflags = TraceFlags.SAMPLED
69         else:
70             traceflags = TraceFlags.DEFAULT
71 
72         if (
73             traceid != INVALID_TRACE_ID
74             and _valid_extract_traceid.fullmatch(traceid) is not None
75             and spanid != INVALID_SPAN_ID
76             and _valid_extract_spanid.fullmatch(spanid) is not None
77         ):
78             context = set_span_in_context(
79                 NonRecordingSpan(
80                     SpanContext(
81                         trace_id=int(traceid, 16),
82                         span_id=int(spanid, 16),
83                         is_remote=True,
84                         trace_flags=traceflags,
85                     )
86                 ),
87                 context,
88             )
89 
90             baggage = get_all(context) or {}
91 
92             for key in getter.keys(carrier):
93 
94                 if not key.startswith(OT_BAGGAGE_PREFIX):
95                     continue
96 
97                 baggage[
98                     key[len(OT_BAGGAGE_PREFIX) :]
99                 ] = _extract_first_element(getter.get(carrier, key))
100 
101             for key, value in baggage.items():
102                 context = set_baggage(key, value, context)
103 
104         return context
105 
106     def inject(
107         self,
108         set_in_carrier: Setter[TextMapPropagatorT],
109         carrier: TextMapPropagatorT,
110         context: Optional[Context] = None,
111     ) -> None:
112 
113         span_context = get_current_span(context).get_span_context()
114 
115         if span_context.trace_id == INVALID_TRACE_ID:
116             return
117 
118         set_in_carrier(
119             carrier, OT_TRACE_ID_HEADER, hex(span_context.trace_id)[2:][-16:]
120         )
121         set_in_carrier(
122             carrier, OT_SPAN_ID_HEADER, hex(span_context.span_id)[2:][-16:],
123         )
124 
125         if span_context.trace_flags == TraceFlags.SAMPLED:
126             traceflags = "true"
127         else:
128             traceflags = "false"
129 
130         set_in_carrier(carrier, OT_SAMPLED_HEADER, traceflags)
131 
132         baggage = get_all(context)
133 
134         if not baggage:
135             return
136 
137         for header_name, header_value in baggage.items():
138 
139             if (
140                 _valid_header_name.fullmatch(header_name) is None
141                 or _valid_header_value.fullmatch(header_value) is None
142             ):
143                 continue
144 
145             set_in_carrier(
146                 carrier,
147                 "".join([OT_BAGGAGE_PREFIX, header_name]),
148                 header_value,
149             )
150 
151     @property
152     def fields(self):
153         """Returns a set with the fields set in `inject`.
154 
155         See
156         `opentelemetry.propagators.textmap.TextMapPropagator.fields`
157         """
158         return {
159             OT_TRACE_ID_HEADER,
160             OT_SPAN_ID_HEADER,
161             OT_SAMPLED_HEADER,
162         }
163 
164 
165 def _extract_first_element(
166     items: Iterable[TextMapPropagatorT],
167 ) -> Optional[TextMapPropagatorT]:
168     if items is None:
169         return None
170     return next(iter(items), None)
171
```
--- 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/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py
--- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py
+++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 from re import compile as re_compile
-from typing import Iterable, Optional
+from typing import Any, Iterable, Optional
 
 from opentelemetry.baggage import get_all, set_baggage
 from opentelemetry.context import Context
@@ -55,10 +55,12 @@
     ) -> Context:
 
         traceid = _extract_first_element(
-            getter.get(carrier, OT_TRACE_ID_HEADER)
+            getter.get(carrier, OT_TRACE_ID_HEADER), INVALID_TRACE_ID
         )
 
-        spanid = _extract_first_element(getter.get(carrier, OT_SPAN_ID_HEADER))
+        spanid = _extract_first_element(
+            getter.get(carrier, OT_SPAN_ID_HEADER), INVALID_SPAN_ID
+        )
 
         sampled = _extract_first_element(
             getter.get(carrier, OT_SAMPLED_HEADER)
@@ -163,8 +165,8 @@
 
 
 def _extract_first_element(
-    items: Iterable[TextMapPropagatorT],
+    items: Iterable[TextMapPropagatorT], default: Any = None,
 ) -> Optional[TextMapPropagatorT]:
     if items is None:
-        return None
+        return default
     return next(iter(items), None)

{"golden_diff": "diff --git a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py\n--- a/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py\n+++ b/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py\n@@ -13,7 +13,7 @@\n # limitations under the License.\n \n from re import compile as re_compile\n-from typing import Iterable, Optional\n+from typing import Any, Iterable, Optional\n \n from opentelemetry.baggage import get_all, set_baggage\n from opentelemetry.context import Context\n@@ -55,10 +55,12 @@\n     ) -> Context:\n \n         traceid = _extract_first_element(\n-            getter.get(carrier, OT_TRACE_ID_HEADER)\n+            getter.get(carrier, OT_TRACE_ID_HEADER), INVALID_TRACE_ID\n         )\n \n-        spanid = _extract_first_element(getter.get(carrier, OT_SPAN_ID_HEADER))\n+        spanid = _extract_first_element(\n+            getter.get(carrier, OT_SPAN_ID_HEADER), INVALID_SPAN_ID\n+        )\n \n         sampled = _extract_first_element(\n             getter.get(carrier, OT_SAMPLED_HEADER)\n@@ -163,8 +165,8 @@\n \n \n def _extract_first_element(\n-    items: Iterable[TextMapPropagatorT],\n+    items: Iterable[TextMapPropagatorT], default: Any = None,\n ) -> Optional[TextMapPropagatorT]:\n     if items is None:\n-        return None\n+        return default\n     return next(iter(items), None)\n", "issue": "OT Trace propagator fails with exception when no headers are present\n**Describe your environment**\r\nLatest version (main branch) of both opentelemetry-python and opentelemetry-python-contrib\r\n\r\n**Steps to reproduce**\r\n```python\r\nfrom opentelemetry.propagators.ot_trace import OTTracePropagator\r\nfrom opentelemetry.propagators.textmap import DictGetter\r\n\r\ngetter = DictGetter()\r\ncarrier = {}\r\n\r\npropagator = OTTracePropagator()\r\npropagator.extract(getter, carrier)\r\n```\r\nresults in:\r\n```\r\nTraceback (most recent call last):\r\n  File \"repro.py\", line 8, in <module>\r\n    propagator.extract(getter, {})\r\n  File \"(...)/opentelemetry-python-contrib/propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py\", line 76, in extract\r\n    and _valid_extract_traceid.fullmatch(traceid) is not None\r\nTypeError: expected string or bytes-like object\r\n```\r\n**What is the expected behavior?**\r\nPropagator extraction returns an unmodified context due to lack of relevant headers in the carrier.\r\n> If a value can not be parsed from the carrier, for a cross-cutting concern, the implementation MUST NOT throw an exception and MUST NOT store a new value in the Context, in order to preserve any previously existing valid value.\r\n\r\n_from [OTel specification](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/context/api-propagators.md#extract)_\r\n\r\n**What is the actual behavior?**\r\nPropagator extraction fails with an exception when no headers are present in the carrier.\r\n\r\n**Additional context**\r\nN/A\r\n\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\nfrom re import compile as re_compile\nfrom typing import Iterable, Optional\n\nfrom opentelemetry.baggage import get_all, set_baggage\nfrom opentelemetry.context import Context\nfrom opentelemetry.propagators.textmap import (\n    Getter,\n    Setter,\n    TextMapPropagator,\n    TextMapPropagatorT,\n)\nfrom opentelemetry.trace import (\n    INVALID_SPAN_ID,\n    INVALID_TRACE_ID,\n    NonRecordingSpan,\n    SpanContext,\n    TraceFlags,\n    get_current_span,\n    set_span_in_context,\n)\n\nOT_TRACE_ID_HEADER = \"ot-tracer-traceid\"\nOT_SPAN_ID_HEADER = \"ot-tracer-spanid\"\nOT_SAMPLED_HEADER = \"ot-tracer-sampled\"\nOT_BAGGAGE_PREFIX = \"ot-baggage-\"\n\n_valid_header_name = re_compile(r\"[\\w_^`!#$%&'*+.|~]+\")\n_valid_header_value = re_compile(r\"[\\t\\x20-\\x7e\\x80-\\xff]+\")\n_valid_extract_traceid = re_compile(r\"[0-9a-f]{1,32}\")\n_valid_extract_spanid = re_compile(r\"[0-9a-f]{1,16}\")\n\n\nclass OTTracePropagator(TextMapPropagator):\n    \"\"\"Propagator for the OTTrace HTTP header format\"\"\"\n\n    def extract(\n        self,\n        getter: Getter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: Optional[Context] = None,\n    ) -> Context:\n\n        traceid = _extract_first_element(\n            getter.get(carrier, OT_TRACE_ID_HEADER)\n        )\n\n        spanid = _extract_first_element(getter.get(carrier, OT_SPAN_ID_HEADER))\n\n        sampled = _extract_first_element(\n            getter.get(carrier, OT_SAMPLED_HEADER)\n        )\n\n        if sampled == \"true\":\n            traceflags = TraceFlags.SAMPLED\n        else:\n            traceflags = TraceFlags.DEFAULT\n\n        if (\n            traceid != INVALID_TRACE_ID\n            and _valid_extract_traceid.fullmatch(traceid) is not None\n            and spanid != INVALID_SPAN_ID\n            and _valid_extract_spanid.fullmatch(spanid) is not None\n        ):\n            context = set_span_in_context(\n                NonRecordingSpan(\n                    SpanContext(\n                        trace_id=int(traceid, 16),\n                        span_id=int(spanid, 16),\n                        is_remote=True,\n                        trace_flags=traceflags,\n                    )\n                ),\n                context,\n            )\n\n            baggage = get_all(context) or {}\n\n            for key in getter.keys(carrier):\n\n                if not key.startswith(OT_BAGGAGE_PREFIX):\n                    continue\n\n                baggage[\n                    key[len(OT_BAGGAGE_PREFIX) :]\n                ] = _extract_first_element(getter.get(carrier, key))\n\n            for key, value in baggage.items():\n                context = set_baggage(key, value, context)\n\n        return context\n\n    def inject(\n        self,\n        set_in_carrier: Setter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: Optional[Context] = None,\n    ) -> None:\n\n        span_context = get_current_span(context).get_span_context()\n\n        if span_context.trace_id == INVALID_TRACE_ID:\n            return\n\n        set_in_carrier(\n            carrier, OT_TRACE_ID_HEADER, hex(span_context.trace_id)[2:][-16:]\n        )\n        set_in_carrier(\n            carrier, OT_SPAN_ID_HEADER, hex(span_context.span_id)[2:][-16:],\n        )\n\n        if span_context.trace_flags == TraceFlags.SAMPLED:\n            traceflags = \"true\"\n        else:\n            traceflags = \"false\"\n\n        set_in_carrier(carrier, OT_SAMPLED_HEADER, traceflags)\n\n        baggage = get_all(context)\n\n        if not baggage:\n            return\n\n        for header_name, header_value in baggage.items():\n\n            if (\n                _valid_header_name.fullmatch(header_name) is None\n                or _valid_header_value.fullmatch(header_value) is None\n            ):\n                continue\n\n            set_in_carrier(\n                carrier,\n                \"\".join([OT_BAGGAGE_PREFIX, header_name]),\n                header_value,\n            )\n\n    @property\n    def fields(self):\n        \"\"\"Returns a set with the fields set in `inject`.\n\n        See\n        `opentelemetry.propagators.textmap.TextMapPropagator.fields`\n        \"\"\"\n        return {\n            OT_TRACE_ID_HEADER,\n            OT_SPAN_ID_HEADER,\n            OT_SAMPLED_HEADER,\n        }\n\n\ndef _extract_first_element(\n    items: Iterable[TextMapPropagatorT],\n) -> Optional[TextMapPropagatorT]:\n    if items is None:\n        return None\n    return next(iter(items), None)\n", "path": "propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__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\nfrom re import compile as re_compile\nfrom typing import Any, Iterable, Optional\n\nfrom opentelemetry.baggage import get_all, set_baggage\nfrom opentelemetry.context import Context\nfrom opentelemetry.propagators.textmap import (\n    Getter,\n    Setter,\n    TextMapPropagator,\n    TextMapPropagatorT,\n)\nfrom opentelemetry.trace import (\n    INVALID_SPAN_ID,\n    INVALID_TRACE_ID,\n    NonRecordingSpan,\n    SpanContext,\n    TraceFlags,\n    get_current_span,\n    set_span_in_context,\n)\n\nOT_TRACE_ID_HEADER = \"ot-tracer-traceid\"\nOT_SPAN_ID_HEADER = \"ot-tracer-spanid\"\nOT_SAMPLED_HEADER = \"ot-tracer-sampled\"\nOT_BAGGAGE_PREFIX = \"ot-baggage-\"\n\n_valid_header_name = re_compile(r\"[\\w_^`!#$%&'*+.|~]+\")\n_valid_header_value = re_compile(r\"[\\t\\x20-\\x7e\\x80-\\xff]+\")\n_valid_extract_traceid = re_compile(r\"[0-9a-f]{1,32}\")\n_valid_extract_spanid = re_compile(r\"[0-9a-f]{1,16}\")\n\n\nclass OTTracePropagator(TextMapPropagator):\n    \"\"\"Propagator for the OTTrace HTTP header format\"\"\"\n\n    def extract(\n        self,\n        getter: Getter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: Optional[Context] = None,\n    ) -> Context:\n\n        traceid = _extract_first_element(\n            getter.get(carrier, OT_TRACE_ID_HEADER), INVALID_TRACE_ID\n        )\n\n        spanid = _extract_first_element(\n            getter.get(carrier, OT_SPAN_ID_HEADER), INVALID_SPAN_ID\n        )\n\n        sampled = _extract_first_element(\n            getter.get(carrier, OT_SAMPLED_HEADER)\n        )\n\n        if sampled == \"true\":\n            traceflags = TraceFlags.SAMPLED\n        else:\n            traceflags = TraceFlags.DEFAULT\n\n        if (\n            traceid != INVALID_TRACE_ID\n            and _valid_extract_traceid.fullmatch(traceid) is not None\n            and spanid != INVALID_SPAN_ID\n            and _valid_extract_spanid.fullmatch(spanid) is not None\n        ):\n            context = set_span_in_context(\n                NonRecordingSpan(\n                    SpanContext(\n                        trace_id=int(traceid, 16),\n                        span_id=int(spanid, 16),\n                        is_remote=True,\n                        trace_flags=traceflags,\n                    )\n                ),\n                context,\n            )\n\n            baggage = get_all(context) or {}\n\n            for key in getter.keys(carrier):\n\n                if not key.startswith(OT_BAGGAGE_PREFIX):\n                    continue\n\n                baggage[\n                    key[len(OT_BAGGAGE_PREFIX) :]\n                ] = _extract_first_element(getter.get(carrier, key))\n\n            for key, value in baggage.items():\n                context = set_baggage(key, value, context)\n\n        return context\n\n    def inject(\n        self,\n        set_in_carrier: Setter[TextMapPropagatorT],\n        carrier: TextMapPropagatorT,\n        context: Optional[Context] = None,\n    ) -> None:\n\n        span_context = get_current_span(context).get_span_context()\n\n        if span_context.trace_id == INVALID_TRACE_ID:\n            return\n\n        set_in_carrier(\n            carrier, OT_TRACE_ID_HEADER, hex(span_context.trace_id)[2:][-16:]\n        )\n        set_in_carrier(\n            carrier, OT_SPAN_ID_HEADER, hex(span_context.span_id)[2:][-16:],\n        )\n\n        if span_context.trace_flags == TraceFlags.SAMPLED:\n            traceflags = \"true\"\n        else:\n            traceflags = \"false\"\n\n        set_in_carrier(carrier, OT_SAMPLED_HEADER, traceflags)\n\n        baggage = get_all(context)\n\n        if not baggage:\n            return\n\n        for header_name, header_value in baggage.items():\n\n            if (\n                _valid_header_name.fullmatch(header_name) is None\n                or _valid_header_value.fullmatch(header_value) is None\n            ):\n                continue\n\n            set_in_carrier(\n                carrier,\n                \"\".join([OT_BAGGAGE_PREFIX, header_name]),\n                header_value,\n            )\n\n    @property\n    def fields(self):\n        \"\"\"Returns a set with the fields set in `inject`.\n\n        See\n        `opentelemetry.propagators.textmap.TextMapPropagator.fields`\n        \"\"\"\n        return {\n            OT_TRACE_ID_HEADER,\n            OT_SPAN_ID_HEADER,\n            OT_SAMPLED_HEADER,\n        }\n\n\ndef _extract_first_element(\n    items: Iterable[TextMapPropagatorT], default: Any = None,\n) -> Optional[TextMapPropagatorT]:\n    if items is None:\n        return default\n    return next(iter(items), None)\n", "path": "propagator/opentelemetry-propagator-ot-trace/src/opentelemetry/propagators/ot_trace/__init__.py"}]}