Skip to content

Commit fee1fd7

Browse files
feat(hub): Emit deprecation warnings from Hub API
`sentry_sdk.Hub` has been deprecated since Sentry SDK version 2.0.0 per our docs; however, we waited with adding deprecation warnings because the SDK itself was still using `Hub` APIs until recently. Since we no longer use `Hub` APIs in the SDK (except in `Hub` APIs which are themselves deprecated), we can now start emitting deprecation warnings. Closes #3265
1 parent 06d5da1 commit fee1fd7

File tree

6 files changed

+76
-8
lines changed

6 files changed

+76
-8
lines changed

sentry_sdk/hub.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import warnings
12
from contextlib import contextmanager
23

34
from sentry_sdk._compat import with_metaclass
@@ -56,6 +57,23 @@ def overload(x):
5657
return x
5758

5859

60+
_HUB_DEPRECATION_MESSAGE = (
61+
"`sentry_sdk.Hub` is deprecated and will be removed in a future major release. "
62+
"Please consult our 1.x to 2.x migration guide for details on how to migrate "
63+
"`Hub` usage to the new API: "
64+
"https://docs.sentry.io/platforms/python/migration/1.x-to-2.x"
65+
)
66+
67+
68+
@contextmanager
69+
def _suppress_hub_deprecation_warning():
70+
# type: () -> Generator[None, None, None]
71+
"""Utility function to suppress deprecation warnings for the Hub."""
72+
with warnings.catch_warnings():
73+
warnings.filterwarnings("ignore", _HUB_DEPRECATION_MESSAGE, DeprecationWarning)
74+
yield
75+
76+
5977
_local = ContextVar("sentry_current_hub")
6078

6179

@@ -121,16 +139,20 @@ class HubMeta(type):
121139
def current(cls):
122140
# type: () -> Hub
123141
"""Returns the current instance of the hub."""
142+
warnings.warn(_HUB_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
124143
rv = _local.get(None)
125144
if rv is None:
126-
rv = Hub(GLOBAL_HUB)
145+
with _suppress_hub_deprecation_warning():
146+
# This will raise a deprecation warning; supress it since we already warned above.
147+
rv = Hub(GLOBAL_HUB)
127148
_local.set(rv)
128149
return rv
129150

130151
@property
131152
def main(cls):
132153
# type: () -> Hub
133154
"""Returns the main instance of the hub."""
155+
warnings.warn(_HUB_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
134156
return GLOBAL_HUB
135157

136158

@@ -161,6 +183,7 @@ def __init__(
161183
scope=None, # type: Optional[Any]
162184
):
163185
# type: (...) -> None
186+
warnings.warn(_HUB_DEPRECATION_MESSAGE, DeprecationWarning, stacklevel=2)
164187

165188
current_scope = None
166189

@@ -747,7 +770,10 @@ def trace_propagation_meta(self, span=None):
747770
)
748771

749772

750-
GLOBAL_HUB = Hub()
773+
with _suppress_hub_deprecation_warning():
774+
# Suppress deprecation warning for the Hub here, since we still always
775+
# import this module.
776+
GLOBAL_HUB = Hub()
751777
_local.set(GLOBAL_HUB)
752778

753779

tests/conftest.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import json
22
import os
33
import socket
4+
import warnings
45
from threading import Thread
56
from contextlib import contextmanager
67
from http.server import BaseHTTPRequestHandler, HTTPServer
@@ -561,6 +562,17 @@ def teardown_profiling():
561562
teardown_continuous_profiler()
562563

563564

565+
@pytest.fixture()
566+
def suppress_deprecation_warnings():
567+
"""
568+
Use this fixture to suppress deprecation warnings in a test.
569+
Useful for testing deprecated SDK features.
570+
"""
571+
with warnings.catch_warnings():
572+
warnings.simplefilter("ignore", DeprecationWarning)
573+
yield
574+
575+
564576
class MockServerRequestHandler(BaseHTTPRequestHandler):
565577
def do_GET(self): # noqa: N802
566578
# Process an HTTP GET request and return a response with an HTTP 200 status.

tests/new_scopes_compat/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33

44

55
@pytest.fixture(autouse=True)
6-
def isolate_hub():
6+
def isolate_hub(suppress_deprecation_warnings):
77
with sentry_sdk.Hub(None):
88
yield

tests/profiler/test_transaction_profiler.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -817,7 +817,7 @@ def test_profile_processing(
817817
assert processed["samples"] == expected["samples"]
818818

819819

820-
def test_hub_backwards_compatibility():
820+
def test_hub_backwards_compatibility(suppress_deprecation_warnings):
821821
hub = sentry_sdk.Hub()
822822

823823
with pytest.warns(DeprecationWarning):

tests/test_basics.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,3 +839,21 @@ def test_last_event_id_scope(sentry_init):
839839
# Should not crash
840840
with isolation_scope() as scope:
841841
assert scope.last_event_id() is None
842+
843+
844+
def test_hub_constructor_deprecation_warning():
845+
with pytest.warns(DeprecationWarning):
846+
Hub()
847+
848+
849+
def test_hub_current_deprecation_warning():
850+
with pytest.warns(DeprecationWarning) as warning_records:
851+
Hub.current
852+
853+
# Make sure we only issue one deprecation warning
854+
assert len(warning_records) == 1
855+
856+
857+
def test_hub_main_deprecation_warnings():
858+
with pytest.warns(DeprecationWarning):
859+
Hub.main

tests/tracing/test_deprecated.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,29 @@ def test_start_span_to_start_transaction(sentry_init, capture_events):
2727
assert events[1]["transaction"] == "/2/"
2828

2929

30-
@pytest.mark.parametrize("parameter_value", (sentry_sdk.Hub(), sentry_sdk.Scope()))
31-
def test_passing_hub_parameter_to_transaction_finish(parameter_value):
30+
@pytest.mark.parametrize(
31+
"parameter_value_getter",
32+
# Use lambda to avoid Hub deprecation warning here (will suppress it in the test)
33+
(lambda: sentry_sdk.Hub(), lambda: sentry_sdk.Scope()),
34+
)
35+
def test_passing_hub_parameter_to_transaction_finish(
36+
suppress_deprecation_warnings, parameter_value_getter
37+
):
38+
parameter_value = parameter_value_getter()
3239
transaction = sentry_sdk.tracing.Transaction()
3340
with pytest.warns(DeprecationWarning):
3441
transaction.finish(hub=parameter_value)
3542

3643

37-
def test_passing_hub_object_to_scope_transaction_finish():
44+
def test_passing_hub_object_to_scope_transaction_finish(suppress_deprecation_warnings):
3845
transaction = sentry_sdk.tracing.Transaction()
46+
47+
# Do not move the following line under the `with` statement. Otherwise, the Hub.__init__ deprecation
48+
# warning will be confused with the transaction.finish deprecation warning that we are testing.
49+
hub = sentry_sdk.Hub()
50+
3951
with pytest.warns(DeprecationWarning):
40-
transaction.finish(sentry_sdk.Hub())
52+
transaction.finish(hub)
4153

4254

4355
def test_no_warnings_scope_to_transaction_finish():

0 commit comments

Comments
 (0)