Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions 2 MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh

## Removed

- Dropped support for gevent versions below 20.9.
- Dropped support for greenlet versions below 0.4.17.
- Removed the deprecated Hub class and all uses of hub throughout the SDK in arguments, options, etc. Use a scope instead.
- Removed the `auto_session_tracing` decorator. Use `track_session` instead.

Expand Down
35 changes: 29 additions & 6 deletions 35 sentry_sdk/_init_implementation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import re
import warnings
from typing import TYPE_CHECKING

import sentry_sdk
from sentry_sdk.utils import logger, parse_version

if TYPE_CHECKING:
from typing import Any, ContextManager, Optional
Expand Down Expand Up @@ -41,11 +43,32 @@ def __exit__(self, exc_type: "Any", exc_value: "Any", tb: "Any") -> None:
c.close()


def _check_python_deprecations() -> None:
# Since we're likely to deprecate Python versions in the future, I'm keeping
# this handy function around. Use this to detect the Python version used and
# to output logger.warning()s if it's deprecated.
pass
def _check_version_deprecations() -> None:
try:
import gevent

gevent_version = tuple(
int(part) for part in re.split(r"a|b|rc|\.", gevent.__version__)[:2]
)
if gevent_version < (20, 9):
logger.warning(
"sentry-sdk 3.x supports gevent 20.9.0 or newer. "
"Please upgrade gevent or downgrade to sentry-sdk 2.x."
Comment thread
sentrivana marked this conversation as resolved.
)
except Exception:
pass
Comment thread
sentrivana marked this conversation as resolved.

try:
import greenlet

greenlet_version = parse_version(greenlet.__version__)
if greenlet_version is not None and greenlet_version < (0, 4, 17):
logger.warning(
"sentry-sdk 3.x supports greenlet 0.4.17 or newer. "
"Please upgrade greenlet or downgrade to sentry-sdk 2.x."
)
Comment thread
sentrivana marked this conversation as resolved.
except Exception:
pass
Comment thread
sentrivana marked this conversation as resolved.


def _init(*args: "Optional[str]", **kwargs: "Any") -> "ContextManager[Any]":
Expand All @@ -55,7 +78,7 @@ def _init(*args: "Optional[str]", **kwargs: "Any") -> "ContextManager[Any]":
"""
client = sentry_sdk.Client(*args, **kwargs)
sentry_sdk.get_global_scope().set_client(client)
_check_python_deprecations()
_check_version_deprecations()
rv = _InitGuard(client)
return rv

Expand Down
7 changes: 5 additions & 2 deletions 7 sentry_sdk/ai/monitoring.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import inspect
import sys
from contextvars import ContextVar
from functools import wraps
from typing import TYPE_CHECKING

Expand All @@ -10,14 +11,16 @@
from sentry_sdk.traces import StreamedSpan
from sentry_sdk.tracing import Span
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.utils import ContextVar, capture_internal_exceptions, reraise
from sentry_sdk.utils import capture_internal_exceptions, reraise

if TYPE_CHECKING:
from typing import Any, Awaitable, Callable, Optional, TypeVar, Union

F = TypeVar("F", bound=Union[Callable[..., Any], Callable[..., Awaitable[Any]]])

_ai_pipeline_name = ContextVar("ai_pipeline_name", default=None)
_ai_pipeline_name: "ContextVar[Optional[str]]" = ContextVar(
"ai_pipeline_name", default=None
)


def set_ai_pipeline_name(name: "Optional[str]") -> None:
Expand Down
4 changes: 2 additions & 2 deletions 4 sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import uuid
import warnings
from collections.abc import Iterable, Mapping
from contextvars import ContextVar
from datetime import datetime, timezone
from importlib import import_module
from typing import TYPE_CHECKING, Dict, List, cast, overload
Expand Down Expand Up @@ -50,7 +51,6 @@
)
from sentry_sdk.utils import (
AnnotatedValue,
ContextVar,
capture_internal_exceptions,
current_stacktrace,
datetime_from_isoformat,
Expand Down Expand Up @@ -93,7 +93,7 @@

I = TypeVar("I", bound=Integration) # noqa: E741

_client_init_debug = ContextVar("client_init_debug")
_client_init_debug: "ContextVar[bool]" = ContextVar("client_init_debug")


SDK_INFO: "SDKInfo" = {
Expand Down
10 changes: 0 additions & 10 deletions 10 sentry_sdk/integrations/aiohttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@
should_propagate_trace,
)
from sentry_sdk.utils import (
CONTEXTVARS_ERROR_MESSAGE,
HAS_REAL_CONTEXTVARS,
SENSITIVE_DATA_SUBSTITUTE,
AnnotatedValue,
_register_control_flow_exception,
Expand Down Expand Up @@ -108,14 +106,6 @@ def setup_once() -> None:
version = parse_version(AIOHTTP_VERSION)
_check_minimum_version(AioHttpIntegration, version)

if not HAS_REAL_CONTEXTVARS:
# We better have contextvars or we're going to leak state between
# requests.
raise DidNotEnable(
"The aiohttp integration for Sentry requires Python 3.7+ "
" or aiocontextvars package." + CONTEXTVARS_ERROR_MESSAGE
)

# In the aiohttp integration, all of their HTTP responses are Exceptions.
# Because they have to be raised and handled by the framework, we need to
# register the exceptions as control flow exceptions so that we don't
Expand Down
17 changes: 4 additions & 13 deletions 17 sentry_sdk/integrations/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import inspect
import sys
from contextvars import ContextVar
from copy import deepcopy
from functools import partial
from typing import TYPE_CHECKING
Expand Down Expand Up @@ -41,9 +42,6 @@
)
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.utils import (
CONTEXTVARS_ERROR_MESSAGE,
HAS_REAL_CONTEXTVARS,
ContextVar,
_get_installed_modules,
capture_internal_exceptions,
event_from_exception,
Expand All @@ -61,7 +59,9 @@
from sentry_sdk.tracing import Span


_asgi_middleware_applied = ContextVar("sentry_asgi_middleware_applied")
_asgi_middleware_applied: "ContextVar[bool]" = ContextVar(
"sentry_asgi_middleware_applied"
)

_DEFAULT_TRANSACTION_NAME = "generic ASGI request"

Expand Down Expand Up @@ -113,7 +113,6 @@ class SentryAsgiMiddleware:
def __init__(
self,
app: "Any",
unsafe_context_data: bool = False,
transaction_style: str = "endpoint",
mechanism_type: str = "asgi",
span_origin: str = "manual",
Expand All @@ -126,15 +125,7 @@ def __init__(
data to sent events and basic handling for exceptions bubbling up
through the middleware.

:param unsafe_context_data: Disable errors when a proper contextvars installation could not be found. We do not recommend changing this from the default.
"""
if not unsafe_context_data and not HAS_REAL_CONTEXTVARS:
# We better have contextvars or we're going to leak state between
# requests.
raise RuntimeError(
"The ASGI middleware for Sentry requires Python 3.7+ "
"or the aiocontextvars package." + CONTEXTVARS_ERROR_MESSAGE
)
if transaction_style not in TRANSACTION_STYLE_VALUES:
raise ValueError(
"Invalid value for transaction_style: %s (must be in %s)"
Expand Down
7 changes: 4 additions & 3 deletions 7 sentry_sdk/integrations/dedupe.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import weakref
from contextvars import ContextVar
from typing import TYPE_CHECKING

import sentry_sdk
from sentry_sdk.integrations import Integration
from sentry_sdk.scope import add_global_event_processor
from sentry_sdk.utils import ContextVar, logger
from sentry_sdk.utils import logger

if TYPE_CHECKING:
from typing import Optional
from typing import Any, Optional

from sentry_sdk._types import Event, Hint

Expand All @@ -16,7 +17,7 @@ class DedupeIntegration(Integration):
identifier = "dedupe"

def __init__(self) -> None:
self._last_seen = ContextVar("last-seen")
self._last_seen: "ContextVar[Any]" = ContextVar("last-seen")

@staticmethod
def setup_once() -> None:
Expand Down
26 changes: 0 additions & 26 deletions 26 sentry_sdk/integrations/django/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,12 @@
record_sql_queries,
)
from sentry_sdk.utils import (
CONTEXTVARS_ERROR_MESSAGE,
HAS_REAL_CONTEXTVARS,
SENSITIVE_DATA_SUBSTITUTE,
AnnotatedValue,
capture_internal_exceptions,
ensure_integration_enabled,
event_from_exception,
has_data_collection_enabled,
logger,
transaction_from_function,
walk_exception_chain,
)
Expand Down Expand Up @@ -346,19 +343,6 @@ def _patch_channels() -> None:
except ImportError:
return

if not HAS_REAL_CONTEXTVARS:
# We better have contextvars or we're going to leak state between
# requests.
#
# We cannot hard-raise here because channels may not be used at all in
# the current process. That is the case when running traditional WSGI
# workers in gunicorn+gevent and the websocket stuff in a separate
# process.
logger.warning(
"We detected that you are using Django channels 2.0."
+ CONTEXTVARS_ERROR_MESSAGE
)

from sentry_sdk.integrations.django.asgi import patch_channels_asgi_handler_impl

patch_channels_asgi_handler_impl(AsgiHandler)
Expand All @@ -370,16 +354,6 @@ def _patch_django_asgi_handler() -> None:
except ImportError:
return

if not HAS_REAL_CONTEXTVARS:
# We better have contextvars or we're going to leak state between
# requests.
#
# We cannot hard-raise here because Django's ASGI stuff may not be used
# at all.
logger.warning(
"We detected that you are using Django 3." + CONTEXTVARS_ERROR_MESSAGE
)

from sentry_sdk.integrations.django.asgi import patch_django_asgi_handler_impl

patch_django_asgi_handler_impl(ASGIHandler)
Expand Down
2 changes: 0 additions & 2 deletions 2 sentry_sdk/integrations/django/asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,6 @@ async def sentry_patched_asgi_handler(

middleware = SentryAsgiMiddleware(
old_app.__get__(self, cls),
unsafe_context_data=True,
span_origin=DjangoIntegration.origin,
http_methods_to_capture=integration.http_methods_to_capture,
)._run_asgi3
Expand Down Expand Up @@ -154,7 +153,6 @@ async def sentry_patched_asgi_handler(

middleware = SentryAsgiMiddleware(
lambda _scope: old_app.__get__(self, cls),
unsafe_context_data=True,
span_origin=DjangoIntegration.origin,
http_methods_to_capture=integration.http_methods_to_capture,
)
Expand Down
4 changes: 2 additions & 2 deletions 4 sentry_sdk/integrations/django/middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Create spans from Django middleware invocations
"""

from contextvars import ContextVar
from functools import wraps
from typing import TYPE_CHECKING

Expand All @@ -11,7 +12,6 @@
from sentry_sdk.consts import OP, SPANDATA
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.utils import (
ContextVar,
capture_internal_exceptions,
transaction_from_function,
)
Expand All @@ -24,7 +24,7 @@

F = TypeVar("F", bound=Callable[..., Any])

_import_string_should_wrap_middleware = ContextVar(
_import_string_should_wrap_middleware: "ContextVar[bool]" = ContextVar(
"import_string_should_wrap_middleware"
)

Expand Down
1 change: 0 additions & 1 deletion 1 sentry_sdk/integrations/litestar.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def __init__(
) -> None:
super().__init__(
app=app,
unsafe_context_data=False,
transaction_style="endpoint",
mechanism_type="asgi",
span_origin=span_origin,
Expand Down
10 changes: 0 additions & 10 deletions 10 sentry_sdk/integrations/sanic.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
from sentry_sdk.tracing import TransactionSource
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.utils import (
CONTEXTVARS_ERROR_MESSAGE,
HAS_REAL_CONTEXTVARS,
capture_internal_exceptions,
ensure_integration_enabled,
event_from_exception,
Expand Down Expand Up @@ -80,14 +78,6 @@ def setup_once() -> None:
SanicIntegration.version = parse_version(SANIC_VERSION)
_check_minimum_version(SanicIntegration, SanicIntegration.version)

if not HAS_REAL_CONTEXTVARS:
# We better have contextvars or we're going to leak state between
# requests.
raise DidNotEnable(
"The sanic integration for Sentry requires Python 3.7+ "
" or the aiocontextvars package." + CONTEXTVARS_ERROR_MESSAGE
)

if SANIC_VERSION.startswith("0.8."):
# Sanic 0.8 and older creates a logger named "root" and puts a
# stringified version of every exception in there (without exc_info),
Expand Down
1 change: 0 additions & 1 deletion 1 sentry_sdk/integrations/starlite.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,6 @@ def __init__(
) -> None:
super().__init__(
app=app,
unsafe_context_data=False,
transaction_style="endpoint",
mechanism_type="asgi",
span_origin=span_origin,
Expand Down
10 changes: 0 additions & 10 deletions 10 sentry_sdk/integrations/tornado.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
from sentry_sdk.tracing import TransactionSource
from sentry_sdk.tracing_utils import has_span_streaming_enabled
from sentry_sdk.utils import (
CONTEXTVARS_ERROR_MESSAGE,
HAS_REAL_CONTEXTVARS,
AnnotatedValue,
capture_internal_exceptions,
ensure_integration_enabled,
Expand Down Expand Up @@ -54,14 +52,6 @@ class TornadoIntegration(Integration):
def setup_once() -> None:
_check_minimum_version(TornadoIntegration, TORNADO_VERSION)

if not HAS_REAL_CONTEXTVARS:
# Tornado is async. We better have contextvars or we're going to leak
# state between requests.
raise DidNotEnable(
"The tornado integration for Sentry requires Python 3.7+ or the aiocontextvars package"
+ CONTEXTVARS_ERROR_MESSAGE
)

ignore_logger("tornado.access")

old_execute = RequestHandler._execute
Expand Down
Loading
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.