From fae6713f5acb43804197f55569bb256522d166e2 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Tue, 5 Nov 2024 09:43:58 +0100 Subject: [PATCH 1/2] ref(init): Deprecate `sentry_sdk.init` context manager It is possible to use the return value of `sentry_sdk.init` as a context manager; however, this functionality has not been maintained for a long time, and it does not seem to be documented anywhere. So, we are deprecating this functionality, and we will remove it in the next major release. Closes #3282 --- sentry_sdk/_init_implementation.py | 21 +++++++++++++++++++++ tests/test_api.py | 17 +++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/sentry_sdk/_init_implementation.py b/sentry_sdk/_init_implementation.py index 256a69ee83..eb02b3d11e 100644 --- a/sentry_sdk/_init_implementation.py +++ b/sentry_sdk/_init_implementation.py @@ -1,3 +1,5 @@ +import warnings + from typing import TYPE_CHECKING import sentry_sdk @@ -9,16 +11,35 @@ class _InitGuard: + _CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE = ( + "Using the return value of sentry_sdk.init as a context manager " + "and manually calling the __enter__ and __exit__ methods on the " + "return value are deprecated. We are no longer maintaining this " + "functionality, and we will remove it in the next major release." + ) + def __init__(self, client): # type: (sentry_sdk.Client) -> None self._client = client def __enter__(self): # type: () -> _InitGuard + warnings.warn( + self._CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE, + stacklevel=2, + category=DeprecationWarning, + ) + return self def __exit__(self, exc_type, exc_value, tb): # type: (Any, Any, Any) -> None + warnings.warn( + self._CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE, + stacklevel=2, + category=DeprecationWarning, + ) + c = self._client if c is not None: c.close() diff --git a/tests/test_api.py b/tests/test_api.py index 46fc24fd24..0fdafa9f5d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,6 +1,7 @@ import pytest from unittest import mock +import sentry_sdk from sentry_sdk import ( capture_exception, continue_trace, @@ -181,3 +182,19 @@ def test_set_tags(sentry_init, capture_events): "tag2": "updated", "tag3": "new", }, "Updating tags with empty dict changed tags" + + +def test_init_context_manager_deprecation(): + with pytest.warns(DeprecationWarning): + with sentry_sdk.init(): + ... + + +def test_init_enter_deprecation(): + with pytest.warns(DeprecationWarning): + sentry_sdk.init().__enter__() + + +def test_init_exit_deprecation(): + with pytest.warns(DeprecationWarning): + sentry_sdk.init().__exit__(None, None, None) From e7218dacb34630f00c8d1c80692303752b7b7a67 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Tue, 5 Nov 2024 10:17:05 +0100 Subject: [PATCH 2/2] feat(init): Remove `sentry_sdk.init` context manager BREAKING CHANGE: `sentry_sdk.init` now returns `None` instead of a context manager. --- MIGRATION_GUIDE.md | 3 +- sentry_sdk/_init_implementation.py | 45 ++---------------------------- tests/test_api.py | 17 ----------- 3 files changed, 4 insertions(+), 61 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 5658ee04fd..495bfff75e 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -1,6 +1,5 @@ # Sentry SDK Migration Guide - ## Upgrading to 3.0 Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of what's changed. Looking for a more digestible summary? See the [guide in the docs](https://docs.sentry.io/platforms/python/migration/2.x-to-3.x) with the most common migration patterns. @@ -19,6 +18,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - `sentry_sdk.continue_trace` no longer returns a `Transaction` and is now a context manager. - Redis integration: In Redis pipeline spans there is no `span["data"]["redis.commands"]` that contains a dict `{"count": 3, "first_ten": ["cmd1", "cmd2", ...]}` but instead `span["data"]["redis.commands.count"]` (containing `3`) and `span["data"]["redis.commands.first_ten"]` (containing `["cmd1", "cmd2", ...]`). - clickhouse-driver integration: The query is now available under the `db.query.text` span attribute (only if `send_default_pii` is `True`). +- `sentry_sdk.init` now returns `None` instead of a context manager. ### Removed @@ -40,7 +40,6 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh - `continue_from_headers`, `continue_from_environ` and `from_traceparent` have been removed, please use top-level API `sentry_sdk.continue_trace` instead. - `PropagationContext` constructor no longer takes a `dynamic_sampling_context` but takes a `baggage` object instead. - ### Deprecated - `sentry_sdk.start_transaction` is deprecated. Use `sentry_sdk.start_span` instead. diff --git a/sentry_sdk/_init_implementation.py b/sentry_sdk/_init_implementation.py index eb02b3d11e..dc235af243 100644 --- a/sentry_sdk/_init_implementation.py +++ b/sentry_sdk/_init_implementation.py @@ -1,50 +1,13 @@ -import warnings - from typing import TYPE_CHECKING import sentry_sdk if TYPE_CHECKING: - from typing import Any, ContextManager, Optional + from typing import Any, Optional import sentry_sdk.consts -class _InitGuard: - _CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE = ( - "Using the return value of sentry_sdk.init as a context manager " - "and manually calling the __enter__ and __exit__ methods on the " - "return value are deprecated. We are no longer maintaining this " - "functionality, and we will remove it in the next major release." - ) - - def __init__(self, client): - # type: (sentry_sdk.Client) -> None - self._client = client - - def __enter__(self): - # type: () -> _InitGuard - warnings.warn( - self._CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE, - stacklevel=2, - category=DeprecationWarning, - ) - - return self - - def __exit__(self, exc_type, exc_value, tb): - # type: (Any, Any, Any) -> None - warnings.warn( - self._CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE, - stacklevel=2, - category=DeprecationWarning, - ) - - c = self._client - if c is not None: - c.close() - - def _check_python_deprecations(): # type: () -> None # Since we're likely to deprecate Python versions in the future, I'm keeping @@ -54,7 +17,7 @@ def _check_python_deprecations(): def _init(*args, **kwargs): - # type: (*Optional[str], **Any) -> ContextManager[Any] + # type: (*Optional[str], **Any) -> None """Initializes the SDK and optionally integrations. This takes the same arguments as the client constructor. @@ -62,8 +25,6 @@ def _init(*args, **kwargs): client = sentry_sdk.Client(*args, **kwargs) sentry_sdk.get_global_scope().set_client(client) _check_python_deprecations() - rv = _InitGuard(client) - return rv if TYPE_CHECKING: @@ -73,7 +34,7 @@ def _init(*args, **kwargs): # Use `ClientConstructor` to define the argument types of `init` and # `ContextManager[Any]` to tell static analyzers about the return type. - class init(sentry_sdk.consts.ClientConstructor, _InitGuard): # noqa: N801 + class init(sentry_sdk.consts.ClientConstructor): # noqa: N801 pass else: diff --git a/tests/test_api.py b/tests/test_api.py index 0fdafa9f5d..46fc24fd24 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,7 +1,6 @@ import pytest from unittest import mock -import sentry_sdk from sentry_sdk import ( capture_exception, continue_trace, @@ -182,19 +181,3 @@ def test_set_tags(sentry_init, capture_events): "tag2": "updated", "tag3": "new", }, "Updating tags with empty dict changed tags" - - -def test_init_context_manager_deprecation(): - with pytest.warns(DeprecationWarning): - with sentry_sdk.init(): - ... - - -def test_init_enter_deprecation(): - with pytest.warns(DeprecationWarning): - sentry_sdk.init().__enter__() - - -def test_init_exit_deprecation(): - with pytest.warns(DeprecationWarning): - sentry_sdk.init().__exit__(None, None, None)