We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
urllib instrumentation fails for local file access
When reading local files the status code is not specified and is None. This isn't handled by the instrumentation and causes an exception.

https://github.com/open-telemetry/opentelemetry-python-contrib/blob/444e0a13127304d3a04ccd44445b2e6caed3f770/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py#L212-L217
urllib instrumentation fails for local file access
When reading local files the status code is not specified and is None. This isn't handled by the instrumentation and causes an exception.

https://github.com/open-telemetry/opentelemetry-python-contrib/blob/444e0a13127304d3a04ccd44445b2e6caed3f770/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py#L212-L217

--- 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-instrumentation/src/opentelemetry/instrumentation/utils.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 typing import Dict, Sequence
16 
17 from wrapt import ObjectProxy
18 
19 from opentelemetry import context, trace
20 
21 # pylint: disable=unused-import
22 # pylint: disable=E0611
23 from opentelemetry.context import _SUPPRESS_INSTRUMENTATION_KEY  # noqa: F401
24 from opentelemetry.propagate import extract
25 from opentelemetry.trace import StatusCode
26 
27 
28 def extract_attributes_from_object(
29     obj: any, attributes: Sequence[str], existing: Dict[str, str] = None
30 ) -> Dict[str, str]:
31     extracted = {}
32     if existing:
33         extracted.update(existing)
34     for attr in attributes:
35         value = getattr(obj, attr, None)
36         if value is not None:
37             extracted[attr] = str(value)
38     return extracted
39 
40 
41 def http_status_to_status_code(
42     status: int,
43     allow_redirect: bool = True,
44     server_span: bool = False,
45 ) -> StatusCode:
46     """Converts an HTTP status code to an OpenTelemetry canonical status code
47 
48     Args:
49         status (int): HTTP status code
50     """
51     # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status
52     if status < 100:
53         return StatusCode.ERROR
54     if status <= 299:
55         return StatusCode.UNSET
56     if status <= 399 and allow_redirect:
57         return StatusCode.UNSET
58     if status <= 499 and server_span:
59         return StatusCode.UNSET
60     return StatusCode.ERROR
61 
62 
63 def unwrap(obj, attr: str):
64     """Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it
65 
66     Args:
67         obj: Object that holds a reference to the wrapped function
68         attr (str): Name of the wrapped function
69     """
70     func = getattr(obj, attr, None)
71     if func and isinstance(func, ObjectProxy) and hasattr(func, "__wrapped__"):
72         setattr(obj, attr, func.__wrapped__)
73 
74 
75 def _start_internal_or_server_span(
76     tracer, span_name, start_time, context_carrier, context_getter
77 ):
78     """Returns internal or server span along with the token which can be used by caller to reset context
79 
80 
81     Args:
82         tracer : tracer in use by given instrumentation library
83         name (string): name of the span
84         start_time : start time of the span
85         context_carrier : object which contains values that are
86             used to construct a Context. This object
87             must be paired with an appropriate getter
88             which understands how to extract a value from it.
89         context_getter : an object which contains a get function that can retrieve zero
90             or more values from the carrier and a keys function that can get all the keys
91             from carrier.
92     """
93 
94     token = ctx = span_kind = None
95     if trace.get_current_span() is trace.INVALID_SPAN:
96         ctx = extract(context_carrier, getter=context_getter)
97         token = context.attach(ctx)
98         span_kind = trace.SpanKind.SERVER
99     else:
100         ctx = context.get_current()
101         span_kind = trace.SpanKind.INTERNAL
102     span = tracer.start_span(
103         name=span_name,
104         context=ctx,
105         kind=span_kind,
106         start_time=start_time,
107     )
108     return span, token
109
```
--- 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-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py
--- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py
+++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py
@@ -49,6 +49,9 @@
         status (int): HTTP status code
     """
     # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status
+    if not isinstance(status, int):
+        return StatusCode.UNSET
+
     if status < 100:
         return StatusCode.ERROR
     if status <= 299:

{"golden_diff": "diff --git a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py\n--- a/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py\n+++ b/opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py\n@@ -49,6 +49,9 @@\n         status (int): HTTP status code\n     \"\"\"\n     # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status\n+    if not isinstance(status, int):\n+        return StatusCode.UNSET\n+\n     if status < 100:\n         return StatusCode.ERROR\n     if status <= 299:\n", "issue": "urllib instrumentation fails for local file access\nWhen reading local files the status code is not specified and is None. This isn't handled by the instrumentation and causes an exception.\r\n\r\nhttps://github.com/open-telemetry/opentelemetry-python-contrib/blob/444e0a13127304d3a04ccd44445b2e6caed3f770/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py#L212-L217\nurllib instrumentation fails for local file access\nWhen reading local files the status code is not specified and is None. This isn't handled by the instrumentation and causes an exception.\r\n\r\nhttps://github.com/open-telemetry/opentelemetry-python-contrib/blob/444e0a13127304d3a04ccd44445b2e6caed3f770/instrumentation/opentelemetry-instrumentation-urllib/src/opentelemetry/instrumentation/urllib/__init__.py#L212-L217\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 typing import Dict, Sequence\n\nfrom wrapt import ObjectProxy\n\nfrom opentelemetry import context, trace\n\n# pylint: disable=unused-import\n# pylint: disable=E0611\nfrom opentelemetry.context import _SUPPRESS_INSTRUMENTATION_KEY  # noqa: F401\nfrom opentelemetry.propagate import extract\nfrom opentelemetry.trace import StatusCode\n\n\ndef extract_attributes_from_object(\n    obj: any, attributes: Sequence[str], existing: Dict[str, str] = None\n) -> Dict[str, str]:\n    extracted = {}\n    if existing:\n        extracted.update(existing)\n    for attr in attributes:\n        value = getattr(obj, attr, None)\n        if value is not None:\n            extracted[attr] = str(value)\n    return extracted\n\n\ndef http_status_to_status_code(\n    status: int,\n    allow_redirect: bool = True,\n    server_span: bool = False,\n) -> StatusCode:\n    \"\"\"Converts an HTTP status code to an OpenTelemetry canonical status code\n\n    Args:\n        status (int): HTTP status code\n    \"\"\"\n    # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status\n    if status < 100:\n        return StatusCode.ERROR\n    if status <= 299:\n        return StatusCode.UNSET\n    if status <= 399 and allow_redirect:\n        return StatusCode.UNSET\n    if status <= 499 and server_span:\n        return StatusCode.UNSET\n    return StatusCode.ERROR\n\n\ndef unwrap(obj, attr: str):\n    \"\"\"Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it\n\n    Args:\n        obj: Object that holds a reference to the wrapped function\n        attr (str): Name of the wrapped function\n    \"\"\"\n    func = getattr(obj, attr, None)\n    if func and isinstance(func, ObjectProxy) and hasattr(func, \"__wrapped__\"):\n        setattr(obj, attr, func.__wrapped__)\n\n\ndef _start_internal_or_server_span(\n    tracer, span_name, start_time, context_carrier, context_getter\n):\n    \"\"\"Returns internal or server span along with the token which can be used by caller to reset context\n\n\n    Args:\n        tracer : tracer in use by given instrumentation library\n        name (string): name of the span\n        start_time : start time of the span\n        context_carrier : object which contains values that are\n            used to construct a Context. This object\n            must be paired with an appropriate getter\n            which understands how to extract a value from it.\n        context_getter : an object which contains a get function that can retrieve zero\n            or more values from the carrier and a keys function that can get all the keys\n            from carrier.\n    \"\"\"\n\n    token = ctx = span_kind = None\n    if trace.get_current_span() is trace.INVALID_SPAN:\n        ctx = extract(context_carrier, getter=context_getter)\n        token = context.attach(ctx)\n        span_kind = trace.SpanKind.SERVER\n    else:\n        ctx = context.get_current()\n        span_kind = trace.SpanKind.INTERNAL\n    span = tracer.start_span(\n        name=span_name,\n        context=ctx,\n        kind=span_kind,\n        start_time=start_time,\n    )\n    return span, token\n", "path": "opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.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 typing import Dict, Sequence\n\nfrom wrapt import ObjectProxy\n\nfrom opentelemetry import context, trace\n\n# pylint: disable=unused-import\n# pylint: disable=E0611\nfrom opentelemetry.context import _SUPPRESS_INSTRUMENTATION_KEY  # noqa: F401\nfrom opentelemetry.propagate import extract\nfrom opentelemetry.trace import StatusCode\n\n\ndef extract_attributes_from_object(\n    obj: any, attributes: Sequence[str], existing: Dict[str, str] = None\n) -> Dict[str, str]:\n    extracted = {}\n    if existing:\n        extracted.update(existing)\n    for attr in attributes:\n        value = getattr(obj, attr, None)\n        if value is not None:\n            extracted[attr] = str(value)\n    return extracted\n\n\ndef http_status_to_status_code(\n    status: int,\n    allow_redirect: bool = True,\n    server_span: bool = False,\n) -> StatusCode:\n    \"\"\"Converts an HTTP status code to an OpenTelemetry canonical status code\n\n    Args:\n        status (int): HTTP status code\n    \"\"\"\n    # See: https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#status\n    if not isinstance(status, int):\n        return StatusCode.UNSET\n\n    if status < 100:\n        return StatusCode.ERROR\n    if status <= 299:\n        return StatusCode.UNSET\n    if status <= 399 and allow_redirect:\n        return StatusCode.UNSET\n    if status <= 499 and server_span:\n        return StatusCode.UNSET\n    return StatusCode.ERROR\n\n\ndef unwrap(obj, attr: str):\n    \"\"\"Given a function that was wrapped by wrapt.wrap_function_wrapper, unwrap it\n\n    Args:\n        obj: Object that holds a reference to the wrapped function\n        attr (str): Name of the wrapped function\n    \"\"\"\n    func = getattr(obj, attr, None)\n    if func and isinstance(func, ObjectProxy) and hasattr(func, \"__wrapped__\"):\n        setattr(obj, attr, func.__wrapped__)\n\n\ndef _start_internal_or_server_span(\n    tracer, span_name, start_time, context_carrier, context_getter\n):\n    \"\"\"Returns internal or server span along with the token which can be used by caller to reset context\n\n\n    Args:\n        tracer : tracer in use by given instrumentation library\n        name (string): name of the span\n        start_time : start time of the span\n        context_carrier : object which contains values that are\n            used to construct a Context. This object\n            must be paired with an appropriate getter\n            which understands how to extract a value from it.\n        context_getter : an object which contains a get function that can retrieve zero\n            or more values from the carrier and a keys function that can get all the keys\n            from carrier.\n    \"\"\"\n\n    token = ctx = span_kind = None\n    if trace.get_current_span() is trace.INVALID_SPAN:\n        ctx = extract(context_carrier, getter=context_getter)\n        token = context.attach(ctx)\n        span_kind = trace.SpanKind.SERVER\n    else:\n        ctx = context.get_current()\n        span_kind = trace.SpanKind.INTERNAL\n    span = tracer.start_span(\n        name=span_name,\n        context=ctx,\n        kind=span_kind,\n        start_time=start_time,\n    )\n    return span, token\n", "path": "opentelemetry-instrumentation/src/opentelemetry/instrumentation/utils.py"}]}