diff --git a/sentry_sdk/_types.py b/sentry_sdk/_types.py index 7da76e63dc..8336617a8d 100644 --- a/sentry_sdk/_types.py +++ b/sentry_sdk/_types.py @@ -170,7 +170,7 @@ class SDKInfo(TypedDict): "contexts": dict[str, dict[str, object]], "dist": str, "duration": Optional[float], - "environment": str, + "environment": Optional[str], "errors": list[dict[str, Any]], # TODO: We can expand on this type "event_id": str, "exception": dict[ @@ -188,7 +188,7 @@ class SDKInfo(TypedDict): "monitor_slug": Optional[str], "platform": Literal["python"], "profile": object, # Should be sentry_sdk.profiler.Profile, but we can't import that here due to circular imports - "release": str, + "release": Optional[str], "request": dict[str, object], "sdk": Mapping[str, object], "server_name": str, diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py index 73a25acc9f..63a3f0b8f2 100644 --- a/sentry_sdk/integrations/django/asgi.py +++ b/sentry_sdk/integrations/django/asgi.py @@ -237,9 +237,9 @@ async def __acall__(self, *args, **kwargs): middleware_span = _check_middleware_span(old_method=f) if middleware_span is None: - return await f(*args, **kwargs) + return await f(*args, **kwargs) # type: ignore with middleware_span: - return await f(*args, **kwargs) + return await f(*args, **kwargs) # type: ignore return SentryASGIMixin diff --git a/sentry_sdk/integrations/redis/_async_common.py b/sentry_sdk/integrations/redis/_async_common.py index 196e85e74b..b96986fba3 100644 --- a/sentry_sdk/integrations/redis/_async_common.py +++ b/sentry_sdk/integrations/redis/_async_common.py @@ -41,13 +41,21 @@ async def _sentry_execute(self, *args, **kwargs): origin=SPAN_ORIGIN, ) as span: with capture_internal_exceptions(): + try: + command_seq = self._execution_strategy._command_queue + except AttributeError: + if is_cluster: + command_seq = self._command_stack + else: + command_seq = self.command_stack + set_db_data_fn(span, self) _set_pipeline_data( span, is_cluster, get_command_args_fn, False if is_cluster else self.is_transaction, - self._command_stack if is_cluster else self.command_stack, + command_seq, ) return await old_execute(self, *args, **kwargs) diff --git a/sentry_sdk/integrations/redis/redis_cluster.py b/sentry_sdk/integrations/redis/redis_cluster.py index 80cdc7235a..52936d1512 100644 --- a/sentry_sdk/integrations/redis/redis_cluster.py +++ b/sentry_sdk/integrations/redis/redis_cluster.py @@ -36,11 +36,19 @@ def _set_async_cluster_db_data(span, async_redis_cluster_instance): def _set_async_cluster_pipeline_db_data(span, async_redis_cluster_pipeline_instance): # type: (Span, AsyncClusterPipeline[Any]) -> None with capture_internal_exceptions(): + client = getattr(async_redis_cluster_pipeline_instance, "cluster_client", None) + if client is None: + # In older redis-py versions, the AsyncClusterPipeline had a `_client` + # attr but it is private so potentially problematic and mypy does not + # recognize it - see + # https://github.com/redis/redis-py/blame/v5.0.0/redis/asyncio/cluster.py#L1386 + client = ( + async_redis_cluster_pipeline_instance._client # type: ignore[attr-defined] + ) + _set_async_cluster_db_data( span, - # the AsyncClusterPipeline has always had a `_client` attr but it is private so potentially problematic and mypy - # does not recognize it - see https://github.com/redis/redis-py/blame/v5.0.0/redis/asyncio/cluster.py#L1386 - async_redis_cluster_pipeline_instance._client, # type: ignore[attr-defined] + client, ) diff --git a/sentry_sdk/integrations/tornado.py b/sentry_sdk/integrations/tornado.py index 3cd087524a..83fe5e94e8 100644 --- a/sentry_sdk/integrations/tornado.py +++ b/sentry_sdk/integrations/tornado.py @@ -76,7 +76,7 @@ async def sentry_execute_request_handler(self, *args, **kwargs): else: @coroutine # type: ignore - def sentry_execute_request_handler(self, *args, **kwargs): # type: ignore + def sentry_execute_request_handler(self, *args, **kwargs): # type: (RequestHandler, *Any, **Any) -> Any with _handle_request_impl(self): result = yield from old_execute(self, *args, **kwargs) diff --git a/tests/integrations/aiohttp/test_aiohttp.py b/tests/integrations/aiohttp/test_aiohttp.py index 06859b127f..47152f254c 100644 --- a/tests/integrations/aiohttp/test_aiohttp.py +++ b/tests/integrations/aiohttp/test_aiohttp.py @@ -6,11 +6,6 @@ import pytest -try: - import pytest_asyncio -except ImportError: - pytest_asyncio = None - from aiohttp import web, ClientSession from aiohttp.client import ServerDisconnectedError from aiohttp.web_request import Request @@ -27,14 +22,6 @@ from tests.conftest import ApproxDict -if pytest_asyncio is None: - # `loop` was deprecated in `pytest-aiohttp` - # in favor of `event_loop` from `pytest-asyncio` - @pytest.fixture - def event_loop(loop): - yield loop - - @pytest.mark.asyncio async def test_basic(sentry_init, aiohttp_client, capture_events): sentry_init(integrations=[AioHttpIntegration()]) @@ -490,7 +477,7 @@ async def hello(request): @pytest.mark.asyncio async def test_crumb_capture( - sentry_init, aiohttp_raw_server, aiohttp_client, event_loop, capture_events + sentry_init, aiohttp_raw_server, aiohttp_client, capture_events ): def before_breadcrumb(crumb, hint): crumb["data"]["extra"] = "foo" @@ -546,7 +533,6 @@ async def test_crumb_capture_client_error( sentry_init, aiohttp_raw_server, aiohttp_client, - event_loop, capture_events, status_code, level,