We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
DjangoCache `IndexError` raised when using keywords approach
### How do you use Sentry?

Sentry Saas (sentry.io)

### Version

1.22.1

### Steps to Reproduce

1. Install the latest version
2. Run the code with django cache and get the key using keyword approach
3. Observe `IndexError` issue

Snippet:
```python
from djang.core.cache import cache

cache.get(key="my_key")  #  <-- `IndexError` as there will no `args[0]` which is used for spans
```

### Expected Result

No exception raised and value retrieved

### Actual Result
`IndexError` raised:
```python
IndexError
tuple index out of range
```

--- 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/django/caching.py`
Content:
```
1 import functools
2 from typing import TYPE_CHECKING
3 
4 from django import VERSION as DJANGO_VERSION
5 from django.core.cache import CacheHandler
6 
7 from sentry_sdk import Hub
8 from sentry_sdk.consts import OP, SPANDATA
9 from sentry_sdk._compat import text_type
10 
11 
12 if TYPE_CHECKING:
13     from typing import Any
14     from typing import Callable
15 
16 
17 METHODS_TO_INSTRUMENT = [
18     "get",
19     "get_many",
20 ]
21 
22 
23 def _patch_cache_method(cache, method_name):
24     # type: (CacheHandler, str) -> None
25     from sentry_sdk.integrations.django import DjangoIntegration
26 
27     def _instrument_call(cache, method_name, original_method, args, kwargs):
28         # type: (CacheHandler, str, Callable[..., Any], Any, Any) -> Any
29         hub = Hub.current
30         integration = hub.get_integration(DjangoIntegration)
31         if integration is None or not integration.cache_spans:
32             return original_method(*args, **kwargs)
33 
34         description = "{} {}".format(method_name, args[0])
35 
36         with hub.start_span(op=OP.CACHE, description=description) as span:
37             value = original_method(*args, **kwargs)
38 
39             if value:
40                 span.set_data(SPANDATA.CACHE_HIT, True)
41 
42                 size = len(text_type(value).encode("utf-8"))
43                 span.set_data(SPANDATA.CACHE_ITEM_SIZE, size)
44 
45             else:
46                 span.set_data(SPANDATA.CACHE_HIT, False)
47 
48             return value
49 
50     original_method = getattr(cache, method_name)
51 
52     @functools.wraps(original_method)
53     def sentry_method(*args, **kwargs):
54         # type: (*Any, **Any) -> Any
55         return _instrument_call(cache, method_name, original_method, args, kwargs)
56 
57     setattr(cache, method_name, sentry_method)
58 
59 
60 def _patch_cache(cache):
61     # type: (CacheHandler) -> None
62     if not hasattr(cache, "_sentry_patched"):
63         for method_name in METHODS_TO_INSTRUMENT:
64             _patch_cache_method(cache, method_name)
65         cache._sentry_patched = True
66 
67 
68 def patch_caching():
69     # type: () -> None
70     from sentry_sdk.integrations.django import DjangoIntegration
71 
72     if not hasattr(CacheHandler, "_sentry_patched"):
73         if DJANGO_VERSION < (3, 2):
74             original_get_item = CacheHandler.__getitem__
75 
76             @functools.wraps(original_get_item)
77             def sentry_get_item(self, alias):
78                 # type: (CacheHandler, str) -> Any
79                 cache = original_get_item(self, alias)
80 
81                 integration = Hub.current.get_integration(DjangoIntegration)
82                 if integration and integration.cache_spans:
83                     _patch_cache(cache)
84 
85                 return cache
86 
87             CacheHandler.__getitem__ = sentry_get_item
88             CacheHandler._sentry_patched = True
89 
90         else:
91             original_create_connection = CacheHandler.create_connection
92 
93             @functools.wraps(original_create_connection)
94             def sentry_create_connection(self, alias):
95                 # type: (CacheHandler, str) -> Any
96                 cache = original_create_connection(self, alias)
97 
98                 integration = Hub.current.get_integration(DjangoIntegration)
99                 if integration and integration.cache_spans:
100                     _patch_cache(cache)
101 
102                 return cache
103 
104             CacheHandler.create_connection = sentry_create_connection
105             CacheHandler._sentry_patched = True
106
```

Path: `sentry_sdk/consts.py`
Content:
```
1 from sentry_sdk._types import TYPE_CHECKING
2 
3 if TYPE_CHECKING:
4     import sentry_sdk
5 
6     from typing import Optional
7     from typing import Callable
8     from typing import Union
9     from typing import List
10     from typing import Type
11     from typing import Dict
12     from typing import Any
13     from typing import Sequence
14     from typing_extensions import TypedDict
15 
16     from sentry_sdk.integrations import Integration
17 
18     from sentry_sdk._types import (
19         BreadcrumbProcessor,
20         Event,
21         EventProcessor,
22         ProfilerMode,
23         TracesSampler,
24         TransactionProcessor,
25     )
26 
27     # Experiments are feature flags to enable and disable certain unstable SDK
28     # functionality. Changing them from the defaults (`None`) in production
29     # code is highly discouraged. They are not subject to any stability
30     # guarantees such as the ones from semantic versioning.
31     Experiments = TypedDict(
32         "Experiments",
33         {
34             "max_spans": Optional[int],
35             "record_sql_params": Optional[bool],
36             # TODO: Remove these 2 profiling related experiments
37             "profiles_sample_rate": Optional[float],
38             "profiler_mode": Optional[ProfilerMode],
39         },
40         total=False,
41     )
42 
43 DEFAULT_QUEUE_SIZE = 100
44 DEFAULT_MAX_BREADCRUMBS = 100
45 
46 MATCH_ALL = r".*"
47 
48 
49 class INSTRUMENTER:
50     SENTRY = "sentry"
51     OTEL = "otel"
52 
53 
54 class SPANDATA:
55     """
56     Additional information describing the type of the span.
57     See: https://develop.sentry.dev/sdk/performance/span-data-conventions/
58     """
59 
60     DB_SYSTEM = "db.system"
61     """
62     An identifier for the database management system (DBMS) product being used.
63     See: https://github.com/open-telemetry/opentelemetry-specification/blob/24de67b3827a4e3ab2515cd8ab62d5bcf837c586/specification/trace/semantic_conventions/database.md
64     Example: postgresql
65     """
66 
67     CACHE_HIT = "cache.hit"
68     """
69     A boolean indicating whether the requested data was found in the cache.
70     Example: true
71     """
72 
73     CACHE_ITEM_SIZE = "cache.item_size"
74     """
75     The size of the requested data in bytes.
76     Example: 58
77     """
78 
79     HTTP_QUERY = "http.query"
80     """
81     The Query string present in the URL.
82     Example: ?foo=bar&bar=baz
83     """
84 
85     HTTP_FRAGMENT = "http.fragment"
86     """
87     The Fragments present in the URL.
88     Example: #foo=bar
89     """
90 
91     HTTP_METHOD = "http.method"
92     """
93     The HTTP method used.
94     Example: GET
95     """
96 
97 
98 class OP:
99     CACHE = "cache"
100     DB = "db"
101     DB_REDIS = "db.redis"
102     EVENT_DJANGO = "event.django"
103     FUNCTION = "function"
104     FUNCTION_AWS = "function.aws"
105     FUNCTION_GCP = "function.gcp"
106     GRPC_CLIENT = "grpc.client"
107     GRPC_SERVER = "grpc.server"
108     HTTP_CLIENT = "http.client"
109     HTTP_CLIENT_STREAM = "http.client.stream"
110     HTTP_SERVER = "http.server"
111     MIDDLEWARE_DJANGO = "middleware.django"
112     MIDDLEWARE_STARLETTE = "middleware.starlette"
113     MIDDLEWARE_STARLETTE_RECEIVE = "middleware.starlette.receive"
114     MIDDLEWARE_STARLETTE_SEND = "middleware.starlette.send"
115     MIDDLEWARE_STARLITE = "middleware.starlite"
116     MIDDLEWARE_STARLITE_RECEIVE = "middleware.starlite.receive"
117     MIDDLEWARE_STARLITE_SEND = "middleware.starlite.send"
118     QUEUE_SUBMIT_ARQ = "queue.submit.arq"
119     QUEUE_TASK_ARQ = "queue.task.arq"
120     QUEUE_SUBMIT_CELERY = "queue.submit.celery"
121     QUEUE_TASK_CELERY = "queue.task.celery"
122     QUEUE_TASK_RQ = "queue.task.rq"
123     QUEUE_SUBMIT_HUEY = "queue.submit.huey"
124     QUEUE_TASK_HUEY = "queue.task.huey"
125     SUBPROCESS = "subprocess"
126     SUBPROCESS_WAIT = "subprocess.wait"
127     SUBPROCESS_COMMUNICATE = "subprocess.communicate"
128     TEMPLATE_RENDER = "template.render"
129     VIEW_RENDER = "view.render"
130     VIEW_RESPONSE_RENDER = "view.response.render"
131     WEBSOCKET_SERVER = "websocket.server"
132     SOCKET_CONNECTION = "socket.connection"
133     SOCKET_DNS = "socket.dns"
134 
135 
136 # This type exists to trick mypy and PyCharm into thinking `init` and `Client`
137 # take these arguments (even though they take opaque **kwargs)
138 class ClientConstructor(object):
139     def __init__(
140         self,
141         dsn=None,  # type: Optional[str]
142         max_breadcrumbs=DEFAULT_MAX_BREADCRUMBS,  # type: int
143         release=None,  # type: Optional[str]
144         environment=None,  # type: Optional[str]
145         server_name=None,  # type: Optional[str]
146         shutdown_timeout=2,  # type: float
147         integrations=[],  # type: Sequence[Integration]  # noqa: B006
148         in_app_include=[],  # type: List[str]  # noqa: B006
149         in_app_exclude=[],  # type: List[str]  # noqa: B006
150         default_integrations=True,  # type: bool
151         dist=None,  # type: Optional[str]
152         transport=None,  # type: Optional[Union[sentry_sdk.transport.Transport, Type[sentry_sdk.transport.Transport], Callable[[Event], None]]]
153         transport_queue_size=DEFAULT_QUEUE_SIZE,  # type: int
154         sample_rate=1.0,  # type: float
155         send_default_pii=False,  # type: bool
156         http_proxy=None,  # type: Optional[str]
157         https_proxy=None,  # type: Optional[str]
158         ignore_errors=[],  # type: Sequence[Union[type, str]]  # noqa: B006
159         request_bodies="medium",  # type: str
160         before_send=None,  # type: Optional[EventProcessor]
161         before_breadcrumb=None,  # type: Optional[BreadcrumbProcessor]
162         debug=False,  # type: bool
163         attach_stacktrace=False,  # type: bool
164         ca_certs=None,  # type: Optional[str]
165         propagate_traces=True,  # type: bool
166         traces_sample_rate=None,  # type: Optional[float]
167         traces_sampler=None,  # type: Optional[TracesSampler]
168         profiles_sample_rate=None,  # type: Optional[float]
169         profiles_sampler=None,  # type: Optional[TracesSampler]
170         profiler_mode=None,  # type: Optional[ProfilerMode]
171         auto_enabling_integrations=True,  # type: bool
172         auto_session_tracking=True,  # type: bool
173         send_client_reports=True,  # type: bool
174         _experiments={},  # type: Experiments  # noqa: B006
175         proxy_headers=None,  # type: Optional[Dict[str, str]]
176         instrumenter=INSTRUMENTER.SENTRY,  # type: Optional[str]
177         before_send_transaction=None,  # type: Optional[TransactionProcessor]
178         project_root=None,  # type: Optional[str]
179         enable_tracing=None,  # type: Optional[bool]
180         include_local_variables=True,  # type: Optional[bool]
181         trace_propagation_targets=[  # noqa: B006
182             MATCH_ALL
183         ],  # type: Optional[Sequence[str]]
184         functions_to_trace=[],  # type: Sequence[str]  # noqa: B006
185         event_scrubber=None,  # type: Optional[sentry_sdk.scrubber.EventScrubber]
186     ):
187         # type: (...) -> None
188         pass
189 
190 
191 def _get_default_options():
192     # type: () -> Dict[str, Any]
193     import inspect
194 
195     if hasattr(inspect, "getfullargspec"):
196         getargspec = inspect.getfullargspec
197     else:
198         getargspec = inspect.getargspec  # type: ignore
199 
200     a = getargspec(ClientConstructor.__init__)
201     defaults = a.defaults or ()
202     return dict(zip(a.args[-len(defaults) :], defaults))
203 
204 
205 DEFAULT_OPTIONS = _get_default_options()
206 del _get_default_options
207 
208 
209 VERSION = "1.22.1"
210
```
--- 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/consts.py b/sentry_sdk/consts.py
--- a/sentry_sdk/consts.py
+++ b/sentry_sdk/consts.py
@@ -96,7 +96,7 @@
 
 
 class OP:
-    CACHE = "cache"
+    CACHE_GET_ITEM = "cache.get_item"
     DB = "db"
     DB_REDIS = "db.redis"
     EVENT_DJANGO = "event.django"
diff --git a/sentry_sdk/integrations/django/caching.py b/sentry_sdk/integrations/django/caching.py
--- a/sentry_sdk/integrations/django/caching.py
+++ b/sentry_sdk/integrations/django/caching.py
@@ -20,6 +20,18 @@
 ]
 
 
+def _get_span_description(method_name, args, kwargs):
+    # type: (str, Any, Any) -> str
+    description = "{} ".format(method_name)
+
+    if args is not None and len(args) >= 1:
+        description += text_type(args[0])
+    elif kwargs is not None and "key" in kwargs:
+        description += text_type(kwargs["key"])
+
+    return description
+
+
 def _patch_cache_method(cache, method_name):
     # type: (CacheHandler, str) -> None
     from sentry_sdk.integrations.django import DjangoIntegration
@@ -31,9 +43,9 @@
         if integration is None or not integration.cache_spans:
             return original_method(*args, **kwargs)
 
-        description = "{} {}".format(method_name, args[0])
+        description = _get_span_description(method_name, args, kwargs)
 
-        with hub.start_span(op=OP.CACHE, description=description) as span:
+        with hub.start_span(op=OP.CACHE_GET_ITEM, description=description) as span:
             value = original_method(*args, **kwargs)
 
             if value:

{"golden_diff": "diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py\n--- a/sentry_sdk/consts.py\n+++ b/sentry_sdk/consts.py\n@@ -96,7 +96,7 @@\n \n \n class OP:\n-    CACHE = \"cache\"\n+    CACHE_GET_ITEM = \"cache.get_item\"\n     DB = \"db\"\n     DB_REDIS = \"db.redis\"\n     EVENT_DJANGO = \"event.django\"\ndiff --git a/sentry_sdk/integrations/django/caching.py b/sentry_sdk/integrations/django/caching.py\n--- a/sentry_sdk/integrations/django/caching.py\n+++ b/sentry_sdk/integrations/django/caching.py\n@@ -20,6 +20,18 @@\n ]\n \n \n+def _get_span_description(method_name, args, kwargs):\n+    # type: (str, Any, Any) -> str\n+    description = \"{} \".format(method_name)\n+\n+    if args is not None and len(args) >= 1:\n+        description += text_type(args[0])\n+    elif kwargs is not None and \"key\" in kwargs:\n+        description += text_type(kwargs[\"key\"])\n+\n+    return description\n+\n+\n def _patch_cache_method(cache, method_name):\n     # type: (CacheHandler, str) -> None\n     from sentry_sdk.integrations.django import DjangoIntegration\n@@ -31,9 +43,9 @@\n         if integration is None or not integration.cache_spans:\n             return original_method(*args, **kwargs)\n \n-        description = \"{} {}\".format(method_name, args[0])\n+        description = _get_span_description(method_name, args, kwargs)\n \n-        with hub.start_span(op=OP.CACHE, description=description) as span:\n+        with hub.start_span(op=OP.CACHE_GET_ITEM, description=description) as span:\n             value = original_method(*args, **kwargs)\n \n             if value:\n", "issue": "DjangoCache `IndexError` raised when using keywords approach\n### How do you use Sentry?\r\n\r\nSentry Saas (sentry.io)\r\n\r\n### Version\r\n\r\n1.22.1\r\n\r\n### Steps to Reproduce\r\n\r\n1. Install the latest version\r\n2. Run the code with django cache and get the key using keyword approach\r\n3. Observe `IndexError` issue\r\n\r\nSnippet:\r\n```python\r\nfrom djang.core.cache import cache\r\n\r\ncache.get(key=\"my_key\")  #  <-- `IndexError` as there will no `args[0]` which is used for spans\r\n```\r\n\r\n### Expected Result\r\n\r\nNo exception raised and value retrieved\r\n\r\n### Actual Result\r\n`IndexError` raised:\r\n```python\r\nIndexError\r\ntuple index out of range\r\n```\n", "before_files": [{"content": "import functools\nfrom typing import TYPE_CHECKING\n\nfrom django import VERSION as DJANGO_VERSION\nfrom django.core.cache import CacheHandler\n\nfrom sentry_sdk import Hub\nfrom sentry_sdk.consts import OP, SPANDATA\nfrom sentry_sdk._compat import text_type\n\n\nif TYPE_CHECKING:\n    from typing import Any\n    from typing import Callable\n\n\nMETHODS_TO_INSTRUMENT = [\n    \"get\",\n    \"get_many\",\n]\n\n\ndef _patch_cache_method(cache, method_name):\n    # type: (CacheHandler, str) -> None\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    def _instrument_call(cache, method_name, original_method, args, kwargs):\n        # type: (CacheHandler, str, Callable[..., Any], Any, Any) -> Any\n        hub = Hub.current\n        integration = hub.get_integration(DjangoIntegration)\n        if integration is None or not integration.cache_spans:\n            return original_method(*args, **kwargs)\n\n        description = \"{} {}\".format(method_name, args[0])\n\n        with hub.start_span(op=OP.CACHE, description=description) as span:\n            value = original_method(*args, **kwargs)\n\n            if value:\n                span.set_data(SPANDATA.CACHE_HIT, True)\n\n                size = len(text_type(value).encode(\"utf-8\"))\n                span.set_data(SPANDATA.CACHE_ITEM_SIZE, size)\n\n            else:\n                span.set_data(SPANDATA.CACHE_HIT, False)\n\n            return value\n\n    original_method = getattr(cache, method_name)\n\n    @functools.wraps(original_method)\n    def sentry_method(*args, **kwargs):\n        # type: (*Any, **Any) -> Any\n        return _instrument_call(cache, method_name, original_method, args, kwargs)\n\n    setattr(cache, method_name, sentry_method)\n\n\ndef _patch_cache(cache):\n    # type: (CacheHandler) -> None\n    if not hasattr(cache, \"_sentry_patched\"):\n        for method_name in METHODS_TO_INSTRUMENT:\n            _patch_cache_method(cache, method_name)\n        cache._sentry_patched = True\n\n\ndef patch_caching():\n    # type: () -> None\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    if not hasattr(CacheHandler, \"_sentry_patched\"):\n        if DJANGO_VERSION < (3, 2):\n            original_get_item = CacheHandler.__getitem__\n\n            @functools.wraps(original_get_item)\n            def sentry_get_item(self, alias):\n                # type: (CacheHandler, str) -> Any\n                cache = original_get_item(self, alias)\n\n                integration = Hub.current.get_integration(DjangoIntegration)\n                if integration and integration.cache_spans:\n                    _patch_cache(cache)\n\n                return cache\n\n            CacheHandler.__getitem__ = sentry_get_item\n            CacheHandler._sentry_patched = True\n\n        else:\n            original_create_connection = CacheHandler.create_connection\n\n            @functools.wraps(original_create_connection)\n            def sentry_create_connection(self, alias):\n                # type: (CacheHandler, str) -> Any\n                cache = original_create_connection(self, alias)\n\n                integration = Hub.current.get_integration(DjangoIntegration)\n                if integration and integration.cache_spans:\n                    _patch_cache(cache)\n\n                return cache\n\n            CacheHandler.create_connection = sentry_create_connection\n            CacheHandler._sentry_patched = True\n", "path": "sentry_sdk/integrations/django/caching.py"}, {"content": "from sentry_sdk._types import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    import sentry_sdk\n\n    from typing import Optional\n    from typing import Callable\n    from typing import Union\n    from typing import List\n    from typing import Type\n    from typing import Dict\n    from typing import Any\n    from typing import Sequence\n    from typing_extensions import TypedDict\n\n    from sentry_sdk.integrations import Integration\n\n    from sentry_sdk._types import (\n        BreadcrumbProcessor,\n        Event,\n        EventProcessor,\n        ProfilerMode,\n        TracesSampler,\n        TransactionProcessor,\n    )\n\n    # Experiments are feature flags to enable and disable certain unstable SDK\n    # functionality. Changing them from the defaults (`None`) in production\n    # code is highly discouraged. They are not subject to any stability\n    # guarantees such as the ones from semantic versioning.\n    Experiments = TypedDict(\n        \"Experiments\",\n        {\n            \"max_spans\": Optional[int],\n            \"record_sql_params\": Optional[bool],\n            # TODO: Remove these 2 profiling related experiments\n            \"profiles_sample_rate\": Optional[float],\n            \"profiler_mode\": Optional[ProfilerMode],\n        },\n        total=False,\n    )\n\nDEFAULT_QUEUE_SIZE = 100\nDEFAULT_MAX_BREADCRUMBS = 100\n\nMATCH_ALL = r\".*\"\n\n\nclass INSTRUMENTER:\n    SENTRY = \"sentry\"\n    OTEL = \"otel\"\n\n\nclass SPANDATA:\n    \"\"\"\n    Additional information describing the type of the span.\n    See: https://develop.sentry.dev/sdk/performance/span-data-conventions/\n    \"\"\"\n\n    DB_SYSTEM = \"db.system\"\n    \"\"\"\n    An identifier for the database management system (DBMS) product being used.\n    See: https://github.com/open-telemetry/opentelemetry-specification/blob/24de67b3827a4e3ab2515cd8ab62d5bcf837c586/specification/trace/semantic_conventions/database.md\n    Example: postgresql\n    \"\"\"\n\n    CACHE_HIT = \"cache.hit\"\n    \"\"\"\n    A boolean indicating whether the requested data was found in the cache.\n    Example: true\n    \"\"\"\n\n    CACHE_ITEM_SIZE = \"cache.item_size\"\n    \"\"\"\n    The size of the requested data in bytes.\n    Example: 58\n    \"\"\"\n\n    HTTP_QUERY = \"http.query\"\n    \"\"\"\n    The Query string present in the URL.\n    Example: ?foo=bar&bar=baz\n    \"\"\"\n\n    HTTP_FRAGMENT = \"http.fragment\"\n    \"\"\"\n    The Fragments present in the URL.\n    Example: #foo=bar\n    \"\"\"\n\n    HTTP_METHOD = \"http.method\"\n    \"\"\"\n    The HTTP method used.\n    Example: GET\n    \"\"\"\n\n\nclass OP:\n    CACHE = \"cache\"\n    DB = \"db\"\n    DB_REDIS = \"db.redis\"\n    EVENT_DJANGO = \"event.django\"\n    FUNCTION = \"function\"\n    FUNCTION_AWS = \"function.aws\"\n    FUNCTION_GCP = \"function.gcp\"\n    GRPC_CLIENT = \"grpc.client\"\n    GRPC_SERVER = \"grpc.server\"\n    HTTP_CLIENT = \"http.client\"\n    HTTP_CLIENT_STREAM = \"http.client.stream\"\n    HTTP_SERVER = \"http.server\"\n    MIDDLEWARE_DJANGO = \"middleware.django\"\n    MIDDLEWARE_STARLETTE = \"middleware.starlette\"\n    MIDDLEWARE_STARLETTE_RECEIVE = \"middleware.starlette.receive\"\n    MIDDLEWARE_STARLETTE_SEND = \"middleware.starlette.send\"\n    MIDDLEWARE_STARLITE = \"middleware.starlite\"\n    MIDDLEWARE_STARLITE_RECEIVE = \"middleware.starlite.receive\"\n    MIDDLEWARE_STARLITE_SEND = \"middleware.starlite.send\"\n    QUEUE_SUBMIT_ARQ = \"queue.submit.arq\"\n    QUEUE_TASK_ARQ = \"queue.task.arq\"\n    QUEUE_SUBMIT_CELERY = \"queue.submit.celery\"\n    QUEUE_TASK_CELERY = \"queue.task.celery\"\n    QUEUE_TASK_RQ = \"queue.task.rq\"\n    QUEUE_SUBMIT_HUEY = \"queue.submit.huey\"\n    QUEUE_TASK_HUEY = \"queue.task.huey\"\n    SUBPROCESS = \"subprocess\"\n    SUBPROCESS_WAIT = \"subprocess.wait\"\n    SUBPROCESS_COMMUNICATE = \"subprocess.communicate\"\n    TEMPLATE_RENDER = \"template.render\"\n    VIEW_RENDER = \"view.render\"\n    VIEW_RESPONSE_RENDER = \"view.response.render\"\n    WEBSOCKET_SERVER = \"websocket.server\"\n    SOCKET_CONNECTION = \"socket.connection\"\n    SOCKET_DNS = \"socket.dns\"\n\n\n# This type exists to trick mypy and PyCharm into thinking `init` and `Client`\n# take these arguments (even though they take opaque **kwargs)\nclass ClientConstructor(object):\n    def __init__(\n        self,\n        dsn=None,  # type: Optional[str]\n        max_breadcrumbs=DEFAULT_MAX_BREADCRUMBS,  # type: int\n        release=None,  # type: Optional[str]\n        environment=None,  # type: Optional[str]\n        server_name=None,  # type: Optional[str]\n        shutdown_timeout=2,  # type: float\n        integrations=[],  # type: Sequence[Integration]  # noqa: B006\n        in_app_include=[],  # type: List[str]  # noqa: B006\n        in_app_exclude=[],  # type: List[str]  # noqa: B006\n        default_integrations=True,  # type: bool\n        dist=None,  # type: Optional[str]\n        transport=None,  # type: Optional[Union[sentry_sdk.transport.Transport, Type[sentry_sdk.transport.Transport], Callable[[Event], None]]]\n        transport_queue_size=DEFAULT_QUEUE_SIZE,  # type: int\n        sample_rate=1.0,  # type: float\n        send_default_pii=False,  # type: bool\n        http_proxy=None,  # type: Optional[str]\n        https_proxy=None,  # type: Optional[str]\n        ignore_errors=[],  # type: Sequence[Union[type, str]]  # noqa: B006\n        request_bodies=\"medium\",  # type: str\n        before_send=None,  # type: Optional[EventProcessor]\n        before_breadcrumb=None,  # type: Optional[BreadcrumbProcessor]\n        debug=False,  # type: bool\n        attach_stacktrace=False,  # type: bool\n        ca_certs=None,  # type: Optional[str]\n        propagate_traces=True,  # type: bool\n        traces_sample_rate=None,  # type: Optional[float]\n        traces_sampler=None,  # type: Optional[TracesSampler]\n        profiles_sample_rate=None,  # type: Optional[float]\n        profiles_sampler=None,  # type: Optional[TracesSampler]\n        profiler_mode=None,  # type: Optional[ProfilerMode]\n        auto_enabling_integrations=True,  # type: bool\n        auto_session_tracking=True,  # type: bool\n        send_client_reports=True,  # type: bool\n        _experiments={},  # type: Experiments  # noqa: B006\n        proxy_headers=None,  # type: Optional[Dict[str, str]]\n        instrumenter=INSTRUMENTER.SENTRY,  # type: Optional[str]\n        before_send_transaction=None,  # type: Optional[TransactionProcessor]\n        project_root=None,  # type: Optional[str]\n        enable_tracing=None,  # type: Optional[bool]\n        include_local_variables=True,  # type: Optional[bool]\n        trace_propagation_targets=[  # noqa: B006\n            MATCH_ALL\n        ],  # type: Optional[Sequence[str]]\n        functions_to_trace=[],  # type: Sequence[str]  # noqa: B006\n        event_scrubber=None,  # type: Optional[sentry_sdk.scrubber.EventScrubber]\n    ):\n        # type: (...) -> None\n        pass\n\n\ndef _get_default_options():\n    # type: () -> Dict[str, Any]\n    import inspect\n\n    if hasattr(inspect, \"getfullargspec\"):\n        getargspec = inspect.getfullargspec\n    else:\n        getargspec = inspect.getargspec  # type: ignore\n\n    a = getargspec(ClientConstructor.__init__)\n    defaults = a.defaults or ()\n    return dict(zip(a.args[-len(defaults) :], defaults))\n\n\nDEFAULT_OPTIONS = _get_default_options()\ndel _get_default_options\n\n\nVERSION = \"1.22.1\"\n", "path": "sentry_sdk/consts.py"}], "after_files": [{"content": "import functools\nfrom typing import TYPE_CHECKING\n\nfrom django import VERSION as DJANGO_VERSION\nfrom django.core.cache import CacheHandler\n\nfrom sentry_sdk import Hub\nfrom sentry_sdk.consts import OP, SPANDATA\nfrom sentry_sdk._compat import text_type\n\n\nif TYPE_CHECKING:\n    from typing import Any\n    from typing import Callable\n\n\nMETHODS_TO_INSTRUMENT = [\n    \"get\",\n    \"get_many\",\n]\n\n\ndef _get_span_description(method_name, args, kwargs):\n    # type: (str, Any, Any) -> str\n    description = \"{} \".format(method_name)\n\n    if args is not None and len(args) >= 1:\n        description += text_type(args[0])\n    elif kwargs is not None and \"key\" in kwargs:\n        description += text_type(kwargs[\"key\"])\n\n    return description\n\n\ndef _patch_cache_method(cache, method_name):\n    # type: (CacheHandler, str) -> None\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    def _instrument_call(cache, method_name, original_method, args, kwargs):\n        # type: (CacheHandler, str, Callable[..., Any], Any, Any) -> Any\n        hub = Hub.current\n        integration = hub.get_integration(DjangoIntegration)\n        if integration is None or not integration.cache_spans:\n            return original_method(*args, **kwargs)\n\n        description = _get_span_description(method_name, args, kwargs)\n\n        with hub.start_span(op=OP.CACHE_GET_ITEM, description=description) as span:\n            value = original_method(*args, **kwargs)\n\n            if value:\n                span.set_data(SPANDATA.CACHE_HIT, True)\n\n                size = len(text_type(value).encode(\"utf-8\"))\n                span.set_data(SPANDATA.CACHE_ITEM_SIZE, size)\n\n            else:\n                span.set_data(SPANDATA.CACHE_HIT, False)\n\n            return value\n\n    original_method = getattr(cache, method_name)\n\n    @functools.wraps(original_method)\n    def sentry_method(*args, **kwargs):\n        # type: (*Any, **Any) -> Any\n        return _instrument_call(cache, method_name, original_method, args, kwargs)\n\n    setattr(cache, method_name, sentry_method)\n\n\ndef _patch_cache(cache):\n    # type: (CacheHandler) -> None\n    if not hasattr(cache, \"_sentry_patched\"):\n        for method_name in METHODS_TO_INSTRUMENT:\n            _patch_cache_method(cache, method_name)\n        cache._sentry_patched = True\n\n\ndef patch_caching():\n    # type: () -> None\n    from sentry_sdk.integrations.django import DjangoIntegration\n\n    if not hasattr(CacheHandler, \"_sentry_patched\"):\n        if DJANGO_VERSION < (3, 2):\n            original_get_item = CacheHandler.__getitem__\n\n            @functools.wraps(original_get_item)\n            def sentry_get_item(self, alias):\n                # type: (CacheHandler, str) -> Any\n                cache = original_get_item(self, alias)\n\n                integration = Hub.current.get_integration(DjangoIntegration)\n                if integration and integration.cache_spans:\n                    _patch_cache(cache)\n\n                return cache\n\n            CacheHandler.__getitem__ = sentry_get_item\n            CacheHandler._sentry_patched = True\n\n        else:\n            original_create_connection = CacheHandler.create_connection\n\n            @functools.wraps(original_create_connection)\n            def sentry_create_connection(self, alias):\n                # type: (CacheHandler, str) -> Any\n                cache = original_create_connection(self, alias)\n\n                integration = Hub.current.get_integration(DjangoIntegration)\n                if integration and integration.cache_spans:\n                    _patch_cache(cache)\n\n                return cache\n\n            CacheHandler.create_connection = sentry_create_connection\n            CacheHandler._sentry_patched = True\n", "path": "sentry_sdk/integrations/django/caching.py"}, {"content": "from sentry_sdk._types import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    import sentry_sdk\n\n    from typing import Optional\n    from typing import Callable\n    from typing import Union\n    from typing import List\n    from typing import Type\n    from typing import Dict\n    from typing import Any\n    from typing import Sequence\n    from typing_extensions import TypedDict\n\n    from sentry_sdk.integrations import Integration\n\n    from sentry_sdk._types import (\n        BreadcrumbProcessor,\n        Event,\n        EventProcessor,\n        ProfilerMode,\n        TracesSampler,\n        TransactionProcessor,\n    )\n\n    # Experiments are feature flags to enable and disable certain unstable SDK\n    # functionality. Changing them from the defaults (`None`) in production\n    # code is highly discouraged. They are not subject to any stability\n    # guarantees such as the ones from semantic versioning.\n    Experiments = TypedDict(\n        \"Experiments\",\n        {\n            \"max_spans\": Optional[int],\n            \"record_sql_params\": Optional[bool],\n            # TODO: Remove these 2 profiling related experiments\n            \"profiles_sample_rate\": Optional[float],\n            \"profiler_mode\": Optional[ProfilerMode],\n        },\n        total=False,\n    )\n\nDEFAULT_QUEUE_SIZE = 100\nDEFAULT_MAX_BREADCRUMBS = 100\n\nMATCH_ALL = r\".*\"\n\n\nclass INSTRUMENTER:\n    SENTRY = \"sentry\"\n    OTEL = \"otel\"\n\n\nclass SPANDATA:\n    \"\"\"\n    Additional information describing the type of the span.\n    See: https://develop.sentry.dev/sdk/performance/span-data-conventions/\n    \"\"\"\n\n    DB_SYSTEM = \"db.system\"\n    \"\"\"\n    An identifier for the database management system (DBMS) product being used.\n    See: https://github.com/open-telemetry/opentelemetry-specification/blob/24de67b3827a4e3ab2515cd8ab62d5bcf837c586/specification/trace/semantic_conventions/database.md\n    Example: postgresql\n    \"\"\"\n\n    CACHE_HIT = \"cache.hit\"\n    \"\"\"\n    A boolean indicating whether the requested data was found in the cache.\n    Example: true\n    \"\"\"\n\n    CACHE_ITEM_SIZE = \"cache.item_size\"\n    \"\"\"\n    The size of the requested data in bytes.\n    Example: 58\n    \"\"\"\n\n    HTTP_QUERY = \"http.query\"\n    \"\"\"\n    The Query string present in the URL.\n    Example: ?foo=bar&bar=baz\n    \"\"\"\n\n    HTTP_FRAGMENT = \"http.fragment\"\n    \"\"\"\n    The Fragments present in the URL.\n    Example: #foo=bar\n    \"\"\"\n\n    HTTP_METHOD = \"http.method\"\n    \"\"\"\n    The HTTP method used.\n    Example: GET\n    \"\"\"\n\n\nclass OP:\n    CACHE_GET_ITEM = \"cache.get_item\"\n    DB = \"db\"\n    DB_REDIS = \"db.redis\"\n    EVENT_DJANGO = \"event.django\"\n    FUNCTION = \"function\"\n    FUNCTION_AWS = \"function.aws\"\n    FUNCTION_GCP = \"function.gcp\"\n    GRPC_CLIENT = \"grpc.client\"\n    GRPC_SERVER = \"grpc.server\"\n    HTTP_CLIENT = \"http.client\"\n    HTTP_CLIENT_STREAM = \"http.client.stream\"\n    HTTP_SERVER = \"http.server\"\n    MIDDLEWARE_DJANGO = \"middleware.django\"\n    MIDDLEWARE_STARLETTE = \"middleware.starlette\"\n    MIDDLEWARE_STARLETTE_RECEIVE = \"middleware.starlette.receive\"\n    MIDDLEWARE_STARLETTE_SEND = \"middleware.starlette.send\"\n    MIDDLEWARE_STARLITE = \"middleware.starlite\"\n    MIDDLEWARE_STARLITE_RECEIVE = \"middleware.starlite.receive\"\n    MIDDLEWARE_STARLITE_SEND = \"middleware.starlite.send\"\n    QUEUE_SUBMIT_ARQ = \"queue.submit.arq\"\n    QUEUE_TASK_ARQ = \"queue.task.arq\"\n    QUEUE_SUBMIT_CELERY = \"queue.submit.celery\"\n    QUEUE_TASK_CELERY = \"queue.task.celery\"\n    QUEUE_TASK_RQ = \"queue.task.rq\"\n    QUEUE_SUBMIT_HUEY = \"queue.submit.huey\"\n    QUEUE_TASK_HUEY = \"queue.task.huey\"\n    SUBPROCESS = \"subprocess\"\n    SUBPROCESS_WAIT = \"subprocess.wait\"\n    SUBPROCESS_COMMUNICATE = \"subprocess.communicate\"\n    TEMPLATE_RENDER = \"template.render\"\n    VIEW_RENDER = \"view.render\"\n    VIEW_RESPONSE_RENDER = \"view.response.render\"\n    WEBSOCKET_SERVER = \"websocket.server\"\n    SOCKET_CONNECTION = \"socket.connection\"\n    SOCKET_DNS = \"socket.dns\"\n\n\n# This type exists to trick mypy and PyCharm into thinking `init` and `Client`\n# take these arguments (even though they take opaque **kwargs)\nclass ClientConstructor(object):\n    def __init__(\n        self,\n        dsn=None,  # type: Optional[str]\n        max_breadcrumbs=DEFAULT_MAX_BREADCRUMBS,  # type: int\n        release=None,  # type: Optional[str]\n        environment=None,  # type: Optional[str]\n        server_name=None,  # type: Optional[str]\n        shutdown_timeout=2,  # type: float\n        integrations=[],  # type: Sequence[Integration]  # noqa: B006\n        in_app_include=[],  # type: List[str]  # noqa: B006\n        in_app_exclude=[],  # type: List[str]  # noqa: B006\n        default_integrations=True,  # type: bool\n        dist=None,  # type: Optional[str]\n        transport=None,  # type: Optional[Union[sentry_sdk.transport.Transport, Type[sentry_sdk.transport.Transport], Callable[[Event], None]]]\n        transport_queue_size=DEFAULT_QUEUE_SIZE,  # type: int\n        sample_rate=1.0,  # type: float\n        send_default_pii=False,  # type: bool\n        http_proxy=None,  # type: Optional[str]\n        https_proxy=None,  # type: Optional[str]\n        ignore_errors=[],  # type: Sequence[Union[type, str]]  # noqa: B006\n        request_bodies=\"medium\",  # type: str\n        before_send=None,  # type: Optional[EventProcessor]\n        before_breadcrumb=None,  # type: Optional[BreadcrumbProcessor]\n        debug=False,  # type: bool\n        attach_stacktrace=False,  # type: bool\n        ca_certs=None,  # type: Optional[str]\n        propagate_traces=True,  # type: bool\n        traces_sample_rate=None,  # type: Optional[float]\n        traces_sampler=None,  # type: Optional[TracesSampler]\n        profiles_sample_rate=None,  # type: Optional[float]\n        profiles_sampler=None,  # type: Optional[TracesSampler]\n        profiler_mode=None,  # type: Optional[ProfilerMode]\n        auto_enabling_integrations=True,  # type: bool\n        auto_session_tracking=True,  # type: bool\n        send_client_reports=True,  # type: bool\n        _experiments={},  # type: Experiments  # noqa: B006\n        proxy_headers=None,  # type: Optional[Dict[str, str]]\n        instrumenter=INSTRUMENTER.SENTRY,  # type: Optional[str]\n        before_send_transaction=None,  # type: Optional[TransactionProcessor]\n        project_root=None,  # type: Optional[str]\n        enable_tracing=None,  # type: Optional[bool]\n        include_local_variables=True,  # type: Optional[bool]\n        trace_propagation_targets=[  # noqa: B006\n            MATCH_ALL\n        ],  # type: Optional[Sequence[str]]\n        functions_to_trace=[],  # type: Sequence[str]  # noqa: B006\n        event_scrubber=None,  # type: Optional[sentry_sdk.scrubber.EventScrubber]\n    ):\n        # type: (...) -> None\n        pass\n\n\ndef _get_default_options():\n    # type: () -> Dict[str, Any]\n    import inspect\n\n    if hasattr(inspect, \"getfullargspec\"):\n        getargspec = inspect.getfullargspec\n    else:\n        getargspec = inspect.getargspec  # type: ignore\n\n    a = getargspec(ClientConstructor.__init__)\n    defaults = a.defaults or ()\n    return dict(zip(a.args[-len(defaults) :], defaults))\n\n\nDEFAULT_OPTIONS = _get_default_options()\ndel _get_default_options\n\n\nVERSION = \"1.22.1\"\n", "path": "sentry_sdk/consts.py"}]}