We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`sentry_sdk.init` breaks `import exceptiongroup` in virtualenv activated with `activate_this.py`
### How do you use Sentry?

Sentry Saas (sentry.io)

### Version

2.2.1

### Steps to Reproduce

```console
$ docker run --rm -it ubuntu:22.04
root@e264f830878b:/# apt update
root@e264f830878b:/# apt install -y python3-apport virtualenv
root@e264f830878b:/# virtualenv venv
root@e264f830878b:/# venv/bin/pip install exceptiongroup sentry-sdk
…
Successfully installed certifi-2024.2.2 exceptiongroup-1.2.1 sentry-sdk-2.2.1 urllib3-2.2.1
root@e264f830878b:/# cat > test.py <<EOF
exec(open("venv/bin/activate_this.py").read(), {"__file__": "venv/bin/activate_this.py"})
import sentry_sdk
sentry_sdk.init(dsn="https://aaa@bbb.ingest.sentry.io/1234")
import exceptiongroup
EOF
root@e264f830878b:/# python3 test.py
```

### Expected Result

No error.

### Actual Result

```pytb
Traceback (most recent call last):
  File "//test.py", line 4, in <module>
    import exceptiongroup
  File "/venv/lib/python3.10/site-packages/exceptiongroup/__init__.py", line 20, in <module>
    from ._formatting import (
  File "/venv/lib/python3.10/site-packages/exceptiongroup/_formatting.py", line 394, in <module>
    assert sys.excepthook is apport_python_hook.apport_excepthook
AssertionError
Sentry is attempting to send 2 pending events
Waiting up to 2 seconds
Press Ctrl-C to quit
```

The [relevant code within `exceptiongroup`](https://github.com/agronholm/exceptiongroup/blob/1.2.1/src/exceptiongroup/_formatting.py#L374-L400) is

```python
if getattr(sys.excepthook, "__name__", None) in (
    "apport_excepthook",
    # on ubuntu 22.10 the hook was renamed to partial_apport_excepthook
    "partial_apport_excepthook",
):
    …
    import apport_python_hook

    assert sys.excepthook is apport_python_hook.apport_excepthook
```

which fails because Sentry has patched `sys.excepthook` but retained the same `__name__`, due to `functools.wraps` within the `ensure_integration_enabled` decorator, used by `_make_excepthook` as of

- #2906

(cc @sentrivana)

This is arguably poor code within `exceptiongroup` (I opened agronholm/exceptiongroup#123), but Sentry should avoid breaking it since it’s a popular library; for example, it’s a dependency of IPython.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sentry_sdk/integrations/excepthook.py`
Content:
```
1 import sys
2 
3 import sentry_sdk
4 from sentry_sdk.utils import (
5     capture_internal_exceptions,
6     ensure_integration_enabled,
7     event_from_exception,
8 )
9 from sentry_sdk.integrations import Integration
10 
11 from sentry_sdk._types import TYPE_CHECKING
12 
13 if TYPE_CHECKING:
14     from typing import Callable
15     from typing import Any
16     from typing import Type
17     from typing import Optional
18 
19     from types import TracebackType
20 
21     Excepthook = Callable[
22         [Type[BaseException], BaseException, Optional[TracebackType]],
23         Any,
24     ]
25 
26 
27 class ExcepthookIntegration(Integration):
28     identifier = "excepthook"
29 
30     always_run = False
31 
32     def __init__(self, always_run=False):
33         # type: (bool) -> None
34 
35         if not isinstance(always_run, bool):
36             raise ValueError(
37                 "Invalid value for always_run: %s (must be type boolean)"
38                 % (always_run,)
39             )
40         self.always_run = always_run
41 
42     @staticmethod
43     def setup_once():
44         # type: () -> None
45         sys.excepthook = _make_excepthook(sys.excepthook)
46 
47 
48 def _make_excepthook(old_excepthook):
49     # type: (Excepthook) -> Excepthook
50     @ensure_integration_enabled(ExcepthookIntegration, old_excepthook)
51     def sentry_sdk_excepthook(type_, value, traceback):
52         # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None
53         integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)
54 
55         if _should_send(integration.always_run):
56             with capture_internal_exceptions():
57                 event, hint = event_from_exception(
58                     (type_, value, traceback),
59                     client_options=sentry_sdk.get_client().options,
60                     mechanism={"type": "excepthook", "handled": False},
61                 )
62                 sentry_sdk.capture_event(event, hint=hint)
63 
64         return old_excepthook(type_, value, traceback)
65 
66     return sentry_sdk_excepthook
67 
68 
69 def _should_send(always_run=False):
70     # type: (bool) -> bool
71     if always_run:
72         return True
73 
74     if hasattr(sys, "ps1"):
75         # Disable the excepthook for interactive Python shells, otherwise
76         # every typo gets sent to Sentry.
77         return False
78 
79     return True
80
```
--- 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/sentry_sdk/integrations/excepthook.py b/sentry_sdk/integrations/excepthook.py
--- a/sentry_sdk/integrations/excepthook.py
+++ b/sentry_sdk/integrations/excepthook.py
@@ -3,7 +3,6 @@
 import sentry_sdk
 from sentry_sdk.utils import (
     capture_internal_exceptions,
-    ensure_integration_enabled,
     event_from_exception,
 )
 from sentry_sdk.integrations import Integration
@@ -47,11 +46,16 @@
 
 def _make_excepthook(old_excepthook):
     # type: (Excepthook) -> Excepthook
-    @ensure_integration_enabled(ExcepthookIntegration, old_excepthook)
     def sentry_sdk_excepthook(type_, value, traceback):
         # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None
         integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)
 
+        # Note: If  we replace this with ensure_integration_enabled then
+        # we break the exceptiongroup backport;
+        # See: https://github.com/getsentry/sentry-python/issues/3097
+        if integration is None:
+            return old_excepthook(type_, value, traceback)
+
         if _should_send(integration.always_run):
             with capture_internal_exceptions():
                 event, hint = event_from_exception(

{"golden_diff": "diff --git a/sentry_sdk/integrations/excepthook.py b/sentry_sdk/integrations/excepthook.py\n--- a/sentry_sdk/integrations/excepthook.py\n+++ b/sentry_sdk/integrations/excepthook.py\n@@ -3,7 +3,6 @@\n import sentry_sdk\n from sentry_sdk.utils import (\n     capture_internal_exceptions,\n-    ensure_integration_enabled,\n     event_from_exception,\n )\n from sentry_sdk.integrations import Integration\n@@ -47,11 +46,16 @@\n \n def _make_excepthook(old_excepthook):\n     # type: (Excepthook) -> Excepthook\n-    @ensure_integration_enabled(ExcepthookIntegration, old_excepthook)\n     def sentry_sdk_excepthook(type_, value, traceback):\n         # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None\n         integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)\n \n+        # Note: If  we replace this with ensure_integration_enabled then\n+        # we break the exceptiongroup backport;\n+        # See: https://github.com/getsentry/sentry-python/issues/3097\n+        if integration is None:\n+            return old_excepthook(type_, value, traceback)\n+\n         if _should_send(integration.always_run):\n             with capture_internal_exceptions():\n                 event, hint = event_from_exception(\n", "issue": "`sentry_sdk.init` breaks `import exceptiongroup` in virtualenv activated with `activate_this.py`\n### How do you use Sentry?\r\n\r\nSentry Saas (sentry.io)\r\n\r\n### Version\r\n\r\n2.2.1\r\n\r\n### Steps to Reproduce\r\n\r\n```console\r\n$ docker run --rm -it ubuntu:22.04\r\nroot@e264f830878b:/# apt update\r\nroot@e264f830878b:/# apt install -y python3-apport virtualenv\r\nroot@e264f830878b:/# virtualenv venv\r\nroot@e264f830878b:/# venv/bin/pip install exceptiongroup sentry-sdk\r\n\u2026\r\nSuccessfully installed certifi-2024.2.2 exceptiongroup-1.2.1 sentry-sdk-2.2.1 urllib3-2.2.1\r\nroot@e264f830878b:/# cat > test.py <<EOF\r\nexec(open(\"venv/bin/activate_this.py\").read(), {\"__file__\": \"venv/bin/activate_this.py\"})\r\nimport sentry_sdk\r\nsentry_sdk.init(dsn=\"https://aaa@bbb.ingest.sentry.io/1234\")\r\nimport exceptiongroup\r\nEOF\r\nroot@e264f830878b:/# python3 test.py\r\n```\r\n\r\n### Expected Result\r\n\r\nNo error.\r\n\r\n### Actual Result\r\n\r\n```pytb\r\nTraceback (most recent call last):\r\n  File \"//test.py\", line 4, in <module>\r\n    import exceptiongroup\r\n  File \"/venv/lib/python3.10/site-packages/exceptiongroup/__init__.py\", line 20, in <module>\r\n    from ._formatting import (\r\n  File \"/venv/lib/python3.10/site-packages/exceptiongroup/_formatting.py\", line 394, in <module>\r\n    assert sys.excepthook is apport_python_hook.apport_excepthook\r\nAssertionError\r\nSentry is attempting to send 2 pending events\r\nWaiting up to 2 seconds\r\nPress Ctrl-C to quit\r\n```\r\n\r\nThe [relevant code within `exceptiongroup`](https://github.com/agronholm/exceptiongroup/blob/1.2.1/src/exceptiongroup/_formatting.py#L374-L400) is\r\n\r\n```python\r\nif getattr(sys.excepthook, \"__name__\", None) in (\r\n    \"apport_excepthook\",\r\n    # on ubuntu 22.10 the hook was renamed to partial_apport_excepthook\r\n    \"partial_apport_excepthook\",\r\n):\r\n    \u2026\r\n    import apport_python_hook\r\n\r\n    assert sys.excepthook is apport_python_hook.apport_excepthook\r\n```\r\n\r\nwhich fails because Sentry has patched `sys.excepthook` but retained the same `__name__`, due to `functools.wraps` within the `ensure_integration_enabled` decorator, used by `_make_excepthook` as of\r\n\r\n- #2906\r\n\r\n(cc @sentrivana)\r\n\r\nThis is arguably poor code within `exceptiongroup` (I opened agronholm/exceptiongroup#123), but Sentry should avoid breaking it since it\u2019s a popular library; for example, it\u2019s a dependency of IPython.\n", "before_files": [{"content": "import sys\n\nimport sentry_sdk\nfrom sentry_sdk.utils import (\n    capture_internal_exceptions,\n    ensure_integration_enabled,\n    event_from_exception,\n)\nfrom sentry_sdk.integrations import Integration\n\nfrom sentry_sdk._types import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from typing import Callable\n    from typing import Any\n    from typing import Type\n    from typing import Optional\n\n    from types import TracebackType\n\n    Excepthook = Callable[\n        [Type[BaseException], BaseException, Optional[TracebackType]],\n        Any,\n    ]\n\n\nclass ExcepthookIntegration(Integration):\n    identifier = \"excepthook\"\n\n    always_run = False\n\n    def __init__(self, always_run=False):\n        # type: (bool) -> None\n\n        if not isinstance(always_run, bool):\n            raise ValueError(\n                \"Invalid value for always_run: %s (must be type boolean)\"\n                % (always_run,)\n            )\n        self.always_run = always_run\n\n    @staticmethod\n    def setup_once():\n        # type: () -> None\n        sys.excepthook = _make_excepthook(sys.excepthook)\n\n\ndef _make_excepthook(old_excepthook):\n    # type: (Excepthook) -> Excepthook\n    @ensure_integration_enabled(ExcepthookIntegration, old_excepthook)\n    def sentry_sdk_excepthook(type_, value, traceback):\n        # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None\n        integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)\n\n        if _should_send(integration.always_run):\n            with capture_internal_exceptions():\n                event, hint = event_from_exception(\n                    (type_, value, traceback),\n                    client_options=sentry_sdk.get_client().options,\n                    mechanism={\"type\": \"excepthook\", \"handled\": False},\n                )\n                sentry_sdk.capture_event(event, hint=hint)\n\n        return old_excepthook(type_, value, traceback)\n\n    return sentry_sdk_excepthook\n\n\ndef _should_send(always_run=False):\n    # type: (bool) -> bool\n    if always_run:\n        return True\n\n    if hasattr(sys, \"ps1\"):\n        # Disable the excepthook for interactive Python shells, otherwise\n        # every typo gets sent to Sentry.\n        return False\n\n    return True\n", "path": "sentry_sdk/integrations/excepthook.py"}], "after_files": [{"content": "import sys\n\nimport sentry_sdk\nfrom sentry_sdk.utils import (\n    capture_internal_exceptions,\n    event_from_exception,\n)\nfrom sentry_sdk.integrations import Integration\n\nfrom sentry_sdk._types import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from typing import Callable\n    from typing import Any\n    from typing import Type\n    from typing import Optional\n\n    from types import TracebackType\n\n    Excepthook = Callable[\n        [Type[BaseException], BaseException, Optional[TracebackType]],\n        Any,\n    ]\n\n\nclass ExcepthookIntegration(Integration):\n    identifier = \"excepthook\"\n\n    always_run = False\n\n    def __init__(self, always_run=False):\n        # type: (bool) -> None\n\n        if not isinstance(always_run, bool):\n            raise ValueError(\n                \"Invalid value for always_run: %s (must be type boolean)\"\n                % (always_run,)\n            )\n        self.always_run = always_run\n\n    @staticmethod\n    def setup_once():\n        # type: () -> None\n        sys.excepthook = _make_excepthook(sys.excepthook)\n\n\ndef _make_excepthook(old_excepthook):\n    # type: (Excepthook) -> Excepthook\n    def sentry_sdk_excepthook(type_, value, traceback):\n        # type: (Type[BaseException], BaseException, Optional[TracebackType]) -> None\n        integration = sentry_sdk.get_client().get_integration(ExcepthookIntegration)\n\n        # Note: If  we replace this with ensure_integration_enabled then\n        # we break the exceptiongroup backport;\n        # See: https://github.com/getsentry/sentry-python/issues/3097\n        if integration is None:\n            return old_excepthook(type_, value, traceback)\n\n        if _should_send(integration.always_run):\n            with capture_internal_exceptions():\n                event, hint = event_from_exception(\n                    (type_, value, traceback),\n                    client_options=sentry_sdk.get_client().options,\n                    mechanism={\"type\": \"excepthook\", \"handled\": False},\n                )\n                sentry_sdk.capture_event(event, hint=hint)\n\n        return old_excepthook(type_, value, traceback)\n\n    return sentry_sdk_excepthook\n\n\ndef _should_send(always_run=False):\n    # type: (bool) -> bool\n    if always_run:\n        return True\n\n    if hasattr(sys, \"ps1\"):\n        # Disable the excepthook for interactive Python shells, otherwise\n        # every typo gets sent to Sentry.\n        return False\n\n    return True\n", "path": "sentry_sdk/integrations/excepthook.py"}]}