From 8fdb6161fd41687f2065ff7079319f1578140b2c Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Fri, 26 Jul 2024 14:48:43 +0200 Subject: [PATCH 1/6] Expose the scope getters to top level API and use them everywhere * Going forward, we might have 2 different scope implementations so we can't have the `Scope` class being called everywhere directly since this will be abstracted away. --- CHANGELOG.md | 30 +++--- MIGRATION_GUIDE.md | 10 +- sentry_sdk/__init__.py | 16 +-- sentry_sdk/_init_implementation.py | 2 +- sentry_sdk/api.py | 100 +++++++++++------- sentry_sdk/debug.py | 4 +- sentry_sdk/hub.py | 73 +++++++------ sentry_sdk/integrations/aiohttp.py | 8 +- sentry_sdk/integrations/ariadne.py | 9 +- sentry_sdk/integrations/arq.py | 10 +- sentry_sdk/integrations/atexit.py | 3 +- sentry_sdk/integrations/aws_lambda.py | 4 +- sentry_sdk/integrations/bottle.py | 3 +- sentry_sdk/integrations/celery/__init__.py | 9 +- sentry_sdk/integrations/celery/beat.py | 3 +- sentry_sdk/integrations/django/__init__.py | 12 +-- sentry_sdk/integrations/django/asgi.py | 5 +- sentry_sdk/integrations/django/templates.py | 3 +- sentry_sdk/integrations/django/views.py | 3 +- sentry_sdk/integrations/falcon.py | 3 +- sentry_sdk/integrations/fastapi.py | 10 +- sentry_sdk/integrations/flask.py | 10 +- sentry_sdk/integrations/gql.py | 4 +- sentry_sdk/integrations/graphene.py | 8 +- sentry_sdk/integrations/grpc/aio/client.py | 6 +- sentry_sdk/integrations/grpc/client.py | 6 +- sentry_sdk/integrations/httpx.py | 5 +- sentry_sdk/integrations/huey.py | 6 +- sentry_sdk/integrations/pyramid.py | 8 +- sentry_sdk/integrations/quart.py | 10 +- sentry_sdk/integrations/rq.py | 3 +- sentry_sdk/integrations/sanic.py | 5 +- sentry_sdk/integrations/spark/spark_driver.py | 3 +- sentry_sdk/integrations/spark/spark_worker.py | 3 +- sentry_sdk/integrations/starlette.py | 20 ++-- sentry_sdk/integrations/starlite.py | 6 +- sentry_sdk/integrations/stdlib.py | 9 +- sentry_sdk/integrations/strawberry.py | 8 +- sentry_sdk/integrations/threading.py | 8 +- sentry_sdk/metrics.py | 2 +- sentry_sdk/profiler/transaction_profiler.py | 6 +- sentry_sdk/scope.py | 42 ++++---- sentry_sdk/tracing.py | 14 ++- sentry_sdk/tracing_utils.py | 4 +- sentry_sdk/utils.py | 9 +- tests/conftest.py | 8 +- tests/integrations/celery/test_celery.py | 9 +- .../celery/test_update_celery_task_headers.py | 6 +- tests/integrations/django/myapp/views.py | 10 +- tests/integrations/django/test_basic.py | 10 +- tests/integrations/falcon/test_falcon.py | 9 +- tests/integrations/flask/test_flask.py | 11 +- tests/integrations/loguru/test_loguru.py | 4 +- .../opentelemetry/test_span_processor.py | 18 ++-- tests/integrations/quart/test_quart.py | 10 +- tests/integrations/rq/test_rq.py | 4 +- tests/integrations/sanic/test_sanic.py | 8 +- .../sqlalchemy/test_sqlalchemy.py | 4 +- .../integrations/threading/test_threading.py | 3 +- tests/integrations/tornado/test_tornado.py | 12 +-- tests/test_api.py | 14 +-- tests/test_basics.py | 9 +- tests/test_client.py | 8 +- tests/test_metrics.py | 7 +- tests/test_sessions.py | 19 ++-- tests/test_transport.py | 37 ++++--- tests/tracing/test_integration_tests.py | 8 +- tests/tracing/test_misc.py | 12 +-- tests/tracing/test_noop_span.py | 8 +- tests/tracing/test_sampling.py | 5 +- 70 files changed, 412 insertions(+), 366 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 158ccde21b..4752726262 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ ```python import sentry_sdk from sentry_sdk.integrations.flask import FlaskIntegration - + sentry_sdk.init( # Do not use the Flask integration even if Flask is installed. disabled_integrations=[ @@ -68,7 +68,7 @@ LangchainIntegration(tiktoken_encoding_name="cl100k_base"), ], ) - ``` + ``` - PyMongo: Send query description as valid JSON (#3291) by @0Calories - Remove Python 2 compatibility code (#3284) by @szokeasaurusrex @@ -183,7 +183,7 @@ This change fixes a regression in our cron monitoring feature, which caused cron ```python from sentry_sdk.integrations.starlette import StarletteIntegration from sentry_sdk.integrations.fastapi import FastApiIntegration - + sentry_sdk.init( # ... integrations=[ @@ -312,9 +312,9 @@ This change fixes a regression in our cron monitoring feature, which caused cron integrations=[AnthropicIntegration()], ) - client = Anthropic() + client = Anthropic() ``` - Check out [the Anthropic docs](https://docs.sentry.io/platforms/python/integrations/anthropic/) for details. + Check out [the Anthropic docs](https://docs.sentry.io/platforms/python/integrations/anthropic/) for details. - **New integration:** [Huggingface Hub](https://docs.sentry.io/platforms/python/integrations/huggingface/) (#3033) by @colin-sentry @@ -369,13 +369,13 @@ This change fixes a regression in our cron monitoring feature, which caused cron ## 2.0.0 -This is the first major update in a *long* time! +This is the first major update in a *long* time! We dropped support for some ancient languages and frameworks (Yes, Python 2.7 is no longer supported). Additionally we refactored a big part of the foundation of the SDK (how data inside the SDK is handled). We hope you like it! -For a shorter version of what you need to do, to upgrade to Sentry SDK 2.0 see: https://docs.sentry.io/platforms/python/migration/1.x-to-2.x +For a shorter version of what you need to do, to upgrade to Sentry SDK 2.0 see: https://docs.sentry.io/platforms/python/migration/1.x-to-2.x ### New Features @@ -415,7 +415,7 @@ For a shorter version of what you need to do, to upgrade to Sentry SDK 2.0 see: # later in the code execution: - scope = sentry_sdk.Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() scope.set_transaction_name("new-transaction-name") ``` - The classes listed in the table below are now abstract base classes. Therefore, they can no longer be instantiated. Subclasses can only be instantiated if they implement all of the abstract methods. @@ -492,7 +492,7 @@ For a shorter version of what you need to do, to upgrade to Sentry SDK 2.0 see: # do something with the forked scope ``` -- `configure_scope` is deprecated. Use the new isolation scope directly via `Scope.get_isolation_scope()` instead. +- `configure_scope` is deprecated. Use the new isolation scope directly via `get_isolation_scope()` instead. Before: @@ -504,9 +504,9 @@ For a shorter version of what you need to do, to upgrade to Sentry SDK 2.0 see: After: ```python - from sentry_sdk.scope import Scope + from sentry_sdkd import get_isolation_scope - scope = Scope.get_isolation_scope() + scope = get_isolation_scope() # do something with `scope` ``` @@ -563,7 +563,7 @@ This is the final 1.x release for the forseeable future. Development will contin "failure_issue_threshold": 5, "recovery_threshold": 5, } - + @monitor(monitor_slug='', monitor_config=monitor_config) def tell_the_world(): print('My scheduled task...') @@ -578,14 +578,14 @@ This is the final 1.x release for the forseeable future. Development will contin ```python import django.db.models.signals import sentry_sdk - + sentry_sdk.init( ... integrations=[ DjangoIntegration( ... signals_denylist=[ - django.db.models.signals.pre_init, + django.db.models.signals.pre_init, django.db.models.signals.post_init, ], ), @@ -608,7 +608,7 @@ This is the final 1.x release for the forseeable future. Development will contin tags["extra"] = "foo" del tags["release"] return True - + sentry_sdk.init( ... _experiments={ diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 17a9186ff6..53396a37ba 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -42,7 +42,7 @@ Looking to upgrade from Sentry SDK 1.x to 2.x? Here's a comprehensive list of wh # later in the code execution: - scope = sentry_sdk.Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() scope.set_transaction_name("new-transaction-name") ``` @@ -132,18 +132,18 @@ Looking to upgrade from Sentry SDK 1.x to 2.x? Here's a comprehensive list of wh After: ```python - from sentry_sdk.scope import Scope + from sentry_sdk import get_current_scope - scope = Scope.get_current_scope() + scope = get_current_scope() # do something with `scope` ``` Or: ```python - from sentry_sdk.scope import Scope + from sentry_sdk import get_isolation_scope - scope = Scope.get_isolation_scope() + scope = get_isolation_scope() # do something with `scope` ``` diff --git a/sentry_sdk/__init__.py b/sentry_sdk/__init__.py index f74c20a194..1c9cedec5f 100644 --- a/sentry_sdk/__init__.py +++ b/sentry_sdk/__init__.py @@ -1,26 +1,20 @@ -from sentry_sdk.hub import Hub from sentry_sdk.scope import Scope from sentry_sdk.transport import Transport, HttpTransport from sentry_sdk.client import Client -from sentry_sdk._init_implementation import init from sentry_sdk.api import * # noqa from sentry_sdk.consts import VERSION # noqa -from sentry_sdk.crons import monitor # noqa -from sentry_sdk.tracing import trace # noqa - __all__ = [ # noqa "Hub", "Scope", "Client", "Transport", "HttpTransport", - "init", "integrations", - "trace", # From sentry_sdk.api + "init", "add_breadcrumb", "capture_event", "capture_exception", @@ -30,6 +24,9 @@ "flush", "get_baggage", "get_client", + "get_global_scope", + "get_isolation_scope", + "get_current_scope", "get_current_span", "get_traceparent", "is_initialized", @@ -46,6 +43,8 @@ "set_user", "start_span", "start_transaction", + "trace", + "monitor", ] # Initialize the debug support after everything is loaded @@ -53,3 +52,6 @@ init_debug_support() del init_debug_support + +# circular imports +from sentry_sdk.hub import Hub diff --git a/sentry_sdk/_init_implementation.py b/sentry_sdk/_init_implementation.py index 382b82acac..256a69ee83 100644 --- a/sentry_sdk/_init_implementation.py +++ b/sentry_sdk/_init_implementation.py @@ -39,7 +39,7 @@ def _init(*args, **kwargs): This takes the same arguments as the client constructor. """ client = sentry_sdk.Client(*args, **kwargs) - sentry_sdk.Scope.get_global_scope().set_client(client) + sentry_sdk.get_global_scope().set_client(client) _check_python_deprecations() rv = _InitGuard(client) return rv diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index 8476ac1e50..3c0876382c 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -3,10 +3,14 @@ from contextlib import contextmanager from sentry_sdk import tracing_utils, Client -from sentry_sdk._types import TYPE_CHECKING +from sentry_sdk._init_implementation import init from sentry_sdk.consts import INSTRUMENTER from sentry_sdk.scope import Scope, _ScopeManager, new_scope, isolation_scope -from sentry_sdk.tracing import NoOpSpan, Transaction +from sentry_sdk.tracing import NoOpSpan, Transaction, trace +from sentry_sdk.crons import monitor + + +from sentry_sdk._types import TYPE_CHECKING if TYPE_CHECKING: from collections.abc import Mapping @@ -47,6 +51,7 @@ def overload(x): # When changing this, update __all__ in __init__.py too __all__ = [ + "init", "add_breadcrumb", "capture_event", "capture_exception", @@ -56,6 +61,9 @@ def overload(x): "flush", "get_baggage", "get_client", + "get_global_scope", + "get_isolation_scope", + "get_current_scope", "get_current_span", "get_traceparent", "is_initialized", @@ -72,6 +80,8 @@ def overload(x): "set_user", "start_span", "start_transaction", + "trace", + "monitor", ] @@ -93,6 +103,12 @@ def clientmethod(f): return f +@scopemethod +def get_client(): + # type: () -> BaseClient + return Scope.get_client() + + def is_initialized(): # type: () -> bool """ @@ -104,13 +120,35 @@ def is_initialized(): (meaning it is configured to send data) then Sentry is initialized. """ - return Scope.get_client().is_active() + return get_client().is_active() @scopemethod -def get_client(): - # type: () -> BaseClient - return Scope.get_client() +def get_global_scope(): + # type: () -> Scope + return Scope.get_global_scope() + + +@scopemethod +def get_isolation_scope(): + # type: () -> Scope + return Scope.get_isolation_scope() + + +@scopemethod +def get_current_scope(): + # type: () -> Scope + return Scope.get_current_scope() + + +@scopemethod +def last_event_id(): + # type: () -> Optional[str] + """ + See :py:meth:`sentry_sdk.Scope.last_event_id` documentation regarding + this method's limitations. + """ + return Scope.last_event_id() @scopemethod @@ -121,9 +159,7 @@ def capture_event( **scope_kwargs, # type: Any ): # type: (...) -> Optional[str] - return Scope.get_current_scope().capture_event( - event, hint, scope=scope, **scope_kwargs - ) + return get_current_scope().capture_event(event, hint, scope=scope, **scope_kwargs) @scopemethod @@ -134,7 +170,7 @@ def capture_message( **scope_kwargs, # type: Any ): # type: (...) -> Optional[str] - return Scope.get_current_scope().capture_message( + return get_current_scope().capture_message( message, level, scope=scope, **scope_kwargs ) @@ -146,9 +182,7 @@ def capture_exception( **scope_kwargs, # type: Any ): # type: (...) -> Optional[str] - return Scope.get_current_scope().capture_exception( - error, scope=scope, **scope_kwargs - ) + return get_current_scope().capture_exception(error, scope=scope, **scope_kwargs) @scopemethod @@ -158,7 +192,7 @@ def add_breadcrumb( **kwargs, # type: Any ): # type: (...) -> None - return Scope.get_isolation_scope().add_breadcrumb(crumb, hint, **kwargs) + return get_isolation_scope().add_breadcrumb(crumb, hint, **kwargs) @overload @@ -194,7 +228,7 @@ def configure_scope( # noqa: F811 stacklevel=2, ) - scope = Scope.get_isolation_scope() + scope = get_isolation_scope() scope.generate_propagation_context() if callback is not None: @@ -259,37 +293,37 @@ def push_scope( # noqa: F811 @scopemethod def set_tag(key, value): # type: (str, Any) -> None - return Scope.get_isolation_scope().set_tag(key, value) + return get_isolation_scope().set_tag(key, value) @scopemethod def set_tags(tags): # type: (Mapping[str, object]) -> None - Scope.get_isolation_scope().set_tags(tags) + return get_isolation_scope().set_tags(tags) @scopemethod def set_context(key, value): # type: (str, Dict[str, Any]) -> None - return Scope.get_isolation_scope().set_context(key, value) + return get_isolation_scope().set_context(key, value) @scopemethod def set_extra(key, value): # type: (str, Any) -> None - return Scope.get_isolation_scope().set_extra(key, value) + return get_isolation_scope().set_extra(key, value) @scopemethod def set_user(value): # type: (Optional[Dict[str, Any]]) -> None - return Scope.get_isolation_scope().set_user(value) + return get_isolation_scope().set_user(value) @scopemethod def set_level(value): # type: (LogLevelStr) -> None - return Scope.get_isolation_scope().set_level(value) + return get_isolation_scope().set_level(value) @clientmethod @@ -298,7 +332,7 @@ def flush( callback=None, # type: Optional[Callable[[int, float], None]] ): # type: (...) -> None - return Scope.get_client().flush(timeout=timeout, callback=callback) + return get_client().flush(timeout=timeout, callback=callback) @scopemethod @@ -306,7 +340,7 @@ def start_span( **kwargs, # type: Any ): # type: (...) -> Span - return Scope.get_current_scope().start_span(**kwargs) + return get_current_scope().start_span(**kwargs) @scopemethod @@ -348,24 +382,14 @@ def start_transaction( constructor. See :py:class:`sentry_sdk.tracing.Transaction` for available arguments. """ - return Scope.get_current_scope().start_transaction( + return get_current_scope().start_transaction( transaction, instrumenter, custom_sampling_context, **kwargs ) -@scopemethod -def last_event_id(): - # type: () -> Optional[str] - """ - See :py:meth:`sentry_sdk.Scope.last_event_id` documentation regarding - this method's limitations. - """ - return Scope.last_event_id() - - def set_measurement(name, value, unit=""): # type: (str, float, MeasurementUnit) -> None - transaction = Scope.get_current_scope().transaction + transaction = get_current_scope().transaction if transaction is not None: transaction.set_measurement(name, value, unit) @@ -383,7 +407,7 @@ def get_traceparent(): """ Returns the traceparent either from the active span or from the scope. """ - return Scope.get_current_scope().get_traceparent() + return get_current_scope().get_traceparent() def get_baggage(): @@ -391,7 +415,7 @@ def get_baggage(): """ Returns Baggage either from the active span or from the scope. """ - baggage = Scope.get_current_scope().get_baggage() + baggage = get_current_scope().get_baggage() if baggage is not None: return baggage.serialize() @@ -405,6 +429,6 @@ def continue_trace( """ Sets the propagation context from environment or headers and returns a transaction. """ - return Scope.get_isolation_scope().continue_trace( + return get_isolation_scope().continue_trace( environ_or_headers, op, name, source, origin ) diff --git a/sentry_sdk/debug.py b/sentry_sdk/debug.py index e30b471698..e4c686a3e8 100644 --- a/sentry_sdk/debug.py +++ b/sentry_sdk/debug.py @@ -2,8 +2,8 @@ import logging import warnings +from sentry_sdk import get_client from sentry_sdk.client import _client_init_debug -from sentry_sdk.scope import Scope from sentry_sdk.utils import logger from logging import LogRecord @@ -14,7 +14,7 @@ def filter(self, record): if _client_init_debug.get(False): return True - return Scope.get_client().options["debug"] + return get_client().options["debug"] def init_debug_support(): diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index d514c168fa..7d81d69541 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -1,9 +1,15 @@ import warnings from contextlib import contextmanager +from sentry_sdk import ( + get_client, + get_global_scope, + get_isolation_scope, + get_current_scope, +) from sentry_sdk._compat import with_metaclass from sentry_sdk.consts import INSTRUMENTER -from sentry_sdk.scope import Scope, _ScopeManager +from sentry_sdk.scope import _ScopeManager from sentry_sdk.client import Client from sentry_sdk.tracing import ( NoOpSpan, @@ -34,6 +40,7 @@ from typing_extensions import Unpack + from sentry_sdk.scope import Scope from sentry_sdk.client import BaseClient from sentry_sdk.integrations import Integration from sentry_sdk._types import ( @@ -139,23 +146,23 @@ def __init__( current_scope = None if isinstance(client_or_hub, Hub): - client = Scope.get_client() + client = get_client() if scope is None: # hub cloning is going on, we use a fork of the current/isolation scope for context manager - scope = Scope.get_isolation_scope().fork() - current_scope = Scope.get_current_scope().fork() + scope = get_isolation_scope().fork() + current_scope = get_current_scope().fork() else: client = client_or_hub # type: ignore - Scope.get_global_scope().set_client(client) + get_global_scope().set_client(client) if scope is None: # so there is no Hub cloning going on # just the current isolation scope is used for context manager - scope = Scope.get_isolation_scope() - current_scope = Scope.get_current_scope() + scope = get_isolation_scope() + current_scope = get_current_scope() if current_scope is None: # just the current current scope is used for context manager - current_scope = Scope.get_current_scope() + current_scope = get_current_scope() self._stack = [(client, scope)] # type: ignore self._last_event_id = None # type: Optional[str] @@ -171,11 +178,11 @@ def __enter__(self): self._old_hubs.append(Hub.current) _local.set(self) - current_scope = Scope.get_current_scope() + current_scope = get_current_scope() self._old_current_scopes.append(current_scope) scope._current_scope.set(self._current_scope) - isolation_scope = Scope.get_isolation_scope() + isolation_scope = get_isolation_scope() self._old_isolation_scopes.append(isolation_scope) scope._isolation_scope.set(self._scope) @@ -227,7 +234,7 @@ def get_integration( If the return value is not `None` the hub is guaranteed to have a client attached. """ - return Scope.get_client().get_integration(name_or_class) + return get_client().get_integration(name_or_class) @property def client(self): @@ -239,7 +246,7 @@ def client(self): Returns the current client on the hub. """ - client = Scope.get_client() + client = get_client() if not client.is_active(): return None @@ -254,7 +261,7 @@ def scope(self): This property is deprecated and will be removed in a future release. Returns the current scope on the hub. """ - return Scope.get_isolation_scope() + return get_isolation_scope() def last_event_id(self): # type: () -> Optional[str] @@ -280,7 +287,7 @@ def bind_client( Binds a new client to the hub. """ - Scope.get_global_scope().set_client(new) + get_global_scope().set_client(new) def capture_event(self, event, hint=None, scope=None, **scope_kwargs): # type: (Event, Optional[Hint], Optional[Scope], Any) -> Optional[str] @@ -304,7 +311,7 @@ def capture_event(self, event, hint=None, scope=None, **scope_kwargs): For supported `**scope_kwargs` see :py:meth:`sentry_sdk.Scope.update_from_kwargs`. The `scope` and `scope_kwargs` parameters are mutually exclusive. """ - last_event_id = Scope.get_current_scope().capture_event( + last_event_id = get_current_scope().capture_event( event, hint, scope=scope, **scope_kwargs ) @@ -338,7 +345,7 @@ def capture_message(self, message, level=None, scope=None, **scope_kwargs): :returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.client._Client.capture_event`). """ - last_event_id = Scope.get_current_scope().capture_message( + last_event_id = get_current_scope().capture_message( message, level=level, scope=scope, **scope_kwargs ) @@ -369,7 +376,7 @@ def capture_exception(self, error=None, scope=None, **scope_kwargs): :returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.client._Client.capture_event`). """ - last_event_id = Scope.get_current_scope().capture_exception( + last_event_id = get_current_scope().capture_exception( error, scope=scope, **scope_kwargs ) @@ -392,7 +399,7 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): :param hint: An optional value that can be used by `before_breadcrumb` to customize the breadcrumbs that are emitted. """ - Scope.get_isolation_scope().add_breadcrumb(crumb, hint, **kwargs) + get_isolation_scope().add_breadcrumb(crumb, hint, **kwargs) def start_span(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): # type: (str, Any) -> Span @@ -415,7 +422,7 @@ def start_span(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Span`. """ - scope = Scope.get_current_scope() + scope = get_current_scope() return scope.start_span(instrumenter=instrumenter, **kwargs) def start_transaction( @@ -454,7 +461,7 @@ def start_transaction( For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Transaction`. """ - scope = Scope.get_current_scope() + scope = get_current_scope() # For backwards compatibility, we allow passing the scope as the hub. # We need a major release to make this nice. (if someone searches the code: deprecated) @@ -474,7 +481,7 @@ def continue_trace(self, environ_or_headers, op=None, name=None, source=None): Sets the propagation context from environment or headers and returns a transaction. """ - return Scope.get_isolation_scope().continue_trace( + return get_isolation_scope().continue_trace( environ_or_headers=environ_or_headers, op=op, name=name, source=source ) @@ -561,7 +568,7 @@ def configure_scope( # noqa :returns: If no callback is provided, returns a context manager that returns the scope. """ - scope = Scope.get_isolation_scope() + scope = get_isolation_scope() if continue_trace: scope.generate_propagation_context() @@ -590,7 +597,7 @@ def start_session( Starts a new session. """ - Scope.get_isolation_scope().start_session( + get_isolation_scope().start_session( session_mode=session_mode, ) @@ -603,7 +610,7 @@ def end_session(self): Ends the current session if there is one. """ - Scope.get_isolation_scope().end_session() + get_isolation_scope().end_session() def stop_auto_session_tracking(self): # type: (...) -> None @@ -617,7 +624,7 @@ def stop_auto_session_tracking(self): This temporarily session tracking for the current scope when called. To resume session tracking call `resume_auto_session_tracking`. """ - Scope.get_isolation_scope().stop_auto_session_tracking() + get_isolation_scope().stop_auto_session_tracking() def resume_auto_session_tracking(self): # type: (...) -> None @@ -630,7 +637,7 @@ def resume_auto_session_tracking(self): disabled earlier. This requires that generally automatic session tracking is enabled. """ - Scope.get_isolation_scope().resume_auto_session_tracking() + get_isolation_scope().resume_auto_session_tracking() def flush( self, @@ -645,7 +652,7 @@ def flush( Alias for :py:meth:`sentry_sdk.client._Client.flush` """ - return Scope.get_client().flush(timeout=timeout, callback=callback) + return get_client().flush(timeout=timeout, callback=callback) def get_traceparent(self): # type: () -> Optional[str] @@ -656,11 +663,11 @@ def get_traceparent(self): Returns the traceparent either from the active span or from the scope. """ - current_scope = Scope.get_current_scope() + current_scope = get_current_scope() traceparent = current_scope.get_traceparent() if traceparent is None: - isolation_scope = Scope.get_isolation_scope() + isolation_scope = get_isolation_scope() traceparent = isolation_scope.get_traceparent() return traceparent @@ -674,11 +681,11 @@ def get_baggage(self): Returns Baggage either from the active span or from the scope. """ - current_scope = Scope.get_current_scope() + current_scope = get_current_scope() baggage = current_scope.get_baggage() if baggage is None: - isolation_scope = Scope.get_isolation_scope() + isolation_scope = get_isolation_scope() baggage = isolation_scope.get_baggage() if baggage is not None: @@ -697,7 +704,7 @@ def iter_trace_propagation_headers(self, span=None): from the span representing the request, if available, or the current span on the scope if not. """ - return Scope.get_current_scope().iter_trace_propagation_headers( + return get_current_scope().iter_trace_propagation_headers( span=span, ) @@ -716,7 +723,7 @@ def trace_propagation_meta(self, span=None): "The parameter `span` in trace_propagation_meta() is deprecated and will be removed in the future." ) - return Scope.get_current_scope().trace_propagation_meta( + return get_current_scope().trace_propagation_meta( span=span, ) diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index 41cf837187..6da340f31c 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -6,7 +6,6 @@ from sentry_sdk.consts import OP, SPANSTATUS, SPANDATA from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations.logging import ignore_logger -from sentry_sdk.scope import Scope from sentry_sdk.sessions import auto_session_tracking_scope from sentry_sdk.integrations._wsgi_common import ( _filter_headers, @@ -166,7 +165,7 @@ async def sentry_urldispatcher_resolve(self, request): pass if name is not None: - Scope.get_current_scope().set_transaction_name( + sentry_sdk.get_current_scope().set_transaction_name( name, source=SOURCE_FOR_STYLE[integration.transaction_style], ) @@ -219,7 +218,10 @@ async def on_request_start(session, trace_config_ctx, params): client = sentry_sdk.get_client() if should_propagate_trace(client, str(params.url)): - for key, value in Scope.get_current_scope().iter_trace_propagation_headers( + for ( + key, + value, + ) in sentry_sdk.get_current_scope().iter_trace_propagation_headers( span=span ): logger.debug( diff --git a/sentry_sdk/integrations/ariadne.py b/sentry_sdk/integrations/ariadne.py index 86407408a6..c58caec8f0 100644 --- a/sentry_sdk/integrations/ariadne.py +++ b/sentry_sdk/integrations/ariadne.py @@ -1,10 +1,11 @@ from importlib import import_module +import sentry_sdk from sentry_sdk import get_client, capture_event from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.integrations._wsgi_common import request_body_within_bounds -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -57,7 +58,7 @@ def _patch_graphql(): def _sentry_patched_parse_query(context_value, query_parser, data): # type: (Optional[Any], Optional[QueryParser], Any) -> DocumentNode event_processor = _make_request_event_processor(data) - Scope.get_isolation_scope().add_event_processor(event_processor) + sentry_sdk.get_isolation_scope().add_event_processor(event_processor) result = old_parse_query(context_value, query_parser, data) return result @@ -68,7 +69,7 @@ def _sentry_patched_handle_graphql_errors(errors, *args, **kwargs): result = old_handle_errors(errors, *args, **kwargs) event_processor = _make_response_event_processor(result[1]) - Scope.get_isolation_scope().add_event_processor(event_processor) + sentry_sdk.get_isolation_scope().add_event_processor(event_processor) client = get_client() if client.is_active(): @@ -92,7 +93,7 @@ def _sentry_patched_handle_query_result(result, *args, **kwargs): query_result = old_handle_query_result(result, *args, **kwargs) event_processor = _make_response_event_processor(query_result[1]) - Scope.get_isolation_scope().add_event_processor(event_processor) + sentry_sdk.get_isolation_scope().add_event_processor(event_processor) client = get_client() if client.is_active(): diff --git a/sentry_sdk/integrations/arq.py b/sentry_sdk/integrations/arq.py index 881722b457..c347ec5138 100644 --- a/sentry_sdk/integrations/arq.py +++ b/sentry_sdk/integrations/arq.py @@ -5,7 +5,7 @@ from sentry_sdk.consts import OP, SPANSTATUS from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations.logging import ignore_logger -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import Transaction, TRANSACTION_SOURCE_TASK from sentry_sdk.utils import ( capture_internal_exceptions, @@ -115,7 +115,7 @@ async def _sentry_run_job(self, job_id, score): def _capture_exception(exc_info): # type: (ExcInfo) -> None - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() if scope.transaction is not None: if exc_info[0] in ARQ_CONTROL_FLOW_EXCEPTIONS: @@ -126,7 +126,7 @@ def _capture_exception(exc_info): event, hint = event_from_exception( exc_info, - client_options=Scope.get_client().options, + client_options=sentry_sdk.get_client().options, mechanism={"type": ArqIntegration.identifier, "handled": False}, ) sentry_sdk.capture_event(event, hint=hint) @@ -138,7 +138,7 @@ def event_processor(event, hint): # type: (Event, Hint) -> Optional[Event] with capture_internal_exceptions(): - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() if scope.transaction is not None: scope.transaction.name = ctx["job_name"] event["transaction"] = ctx["job_name"] @@ -172,7 +172,7 @@ async def _sentry_coroutine(ctx, *args, **kwargs): if integration is None: return await coroutine(ctx, *args, **kwargs) - Scope.get_isolation_scope().add_event_processor( + sentry_sdk.get_isolation_scope().add_event_processor( _make_event_processor({**ctx, "job_name": name}, *args, **kwargs) ) diff --git a/sentry_sdk/integrations/atexit.py b/sentry_sdk/integrations/atexit.py index d11e35fafa..9babbf235d 100644 --- a/sentry_sdk/integrations/atexit.py +++ b/sentry_sdk/integrations/atexit.py @@ -3,7 +3,6 @@ import atexit import sentry_sdk -from sentry_sdk import Scope from sentry_sdk.utils import logger from sentry_sdk.integrations import Integration from sentry_sdk.utils import ensure_integration_enabled @@ -52,5 +51,5 @@ def _shutdown(): integration = client.get_integration(AtexitIntegration) logger.debug("atexit: shutting down client") - Scope.get_isolation_scope().end_session() + sentry_sdk.get_isolation_scope().end_session() client.close(callback=integration.callback) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 3c909ad9af..560511b48b 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -6,7 +6,7 @@ import sentry_sdk from sentry_sdk.api import continue_trace from sentry_sdk.consts import OP -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT from sentry_sdk.utils import ( AnnotatedValue, @@ -44,7 +44,7 @@ def sentry_init_error(*args, **kwargs): client = sentry_sdk.get_client() with capture_internal_exceptions(): - Scope.get_isolation_scope().clear_breadcrumbs() + sentry_sdk.get_isolation_scope().clear_breadcrumbs() exc_info = sys.exc_info() if exc_info and all(exc_info): diff --git a/sentry_sdk/integrations/bottle.py b/sentry_sdk/integrations/bottle.py index f6dc454478..c5dca2f822 100644 --- a/sentry_sdk/integrations/bottle.py +++ b/sentry_sdk/integrations/bottle.py @@ -10,7 +10,6 @@ from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware from sentry_sdk.integrations._wsgi_common import RequestExtractor -from sentry_sdk.scope import Scope from sentry_sdk._types import TYPE_CHECKING if TYPE_CHECKING: @@ -86,7 +85,7 @@ def _patched_handle(self, environ): # type: (Bottle, Dict[str, Any]) -> Any integration = sentry_sdk.get_client().get_integration(BottleIntegration) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope._name = "bottle" scope.add_event_processor( _make_request_event_processor(self, bottle_request, integration) diff --git a/sentry_sdk/integrations/celery/__init__.py b/sentry_sdk/integrations/celery/__init__.py index fa40565a62..e1b54d0a37 100644 --- a/sentry_sdk/integrations/celery/__init__.py +++ b/sentry_sdk/integrations/celery/__init__.py @@ -16,7 +16,6 @@ from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.tracing import BAGGAGE_HEADER_NAME, TRANSACTION_SOURCE_TASK from sentry_sdk._types import TYPE_CHECKING -from sentry_sdk.scope import Scope from sentry_sdk.tracing_utils import Baggage from sentry_sdk.utils import ( capture_internal_exceptions, @@ -100,7 +99,7 @@ def setup_once(): def _set_status(status): # type: (str) -> None with capture_internal_exceptions(): - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() if scope.span is not None: scope.span.set_status(status) @@ -170,7 +169,7 @@ def _update_celery_task_headers(original_headers, span, monitor_beat_tasks): # if span is None (when the task was started by Celery Beat) # this will return the trace headers from the scope. headers = dict( - Scope.get_isolation_scope().iter_trace_propagation_headers(span=span) + sentry_sdk.get_isolation_scope().iter_trace_propagation_headers(span=span) ) if monitor_beat_tasks: @@ -262,9 +261,7 @@ def apply_async(*args, **kwargs): task = args[0] - task_started_from_beat = ( - sentry_sdk.Scope.get_isolation_scope()._name == "celery-beat" - ) + task_started_from_beat = sentry_sdk.get_isolation_scope()._name == "celery-beat" span_mgr = ( sentry_sdk.start_span( diff --git a/sentry_sdk/integrations/celery/beat.py b/sentry_sdk/integrations/celery/beat.py index 6264d58804..b40c39fa80 100644 --- a/sentry_sdk/integrations/celery/beat.py +++ b/sentry_sdk/integrations/celery/beat.py @@ -6,7 +6,6 @@ _now_seconds_since_epoch, ) from sentry_sdk._types import TYPE_CHECKING -from sentry_sdk.scope import Scope from sentry_sdk.utils import ( logger, match_regex_list, @@ -185,7 +184,7 @@ def sentry_patched_scheduler(*args, **kwargs): return original_function(*args, **kwargs) # Tasks started by Celery Beat start a new Trace - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.set_new_propagation_context() scope._name = "celery-beat" diff --git a/sentry_sdk/integrations/django/__init__.py b/sentry_sdk/integrations/django/__init__.py index 253fce1745..508df2e431 100644 --- a/sentry_sdk/integrations/django/__init__.py +++ b/sentry_sdk/integrations/django/__init__.py @@ -8,7 +8,7 @@ from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.consts import OP, SPANDATA from sentry_sdk.db.explain_plan.django import attach_explain_plan_to_span -from sentry_sdk.scope import Scope, add_global_event_processor, should_send_default_pii +from sentry_sdk.scope import add_global_event_processor, should_send_default_pii from sentry_sdk.serializer import add_global_repr_processor from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_URL from sentry_sdk.tracing_utils import add_query_source, record_sql_queries @@ -371,7 +371,7 @@ def _patch_django_asgi_handler(): def _set_transaction_name_and_source(scope, transaction_style, request): - # type: (Scope, str, WSGIRequest) -> None + # type: (sentry_sdk.Scope, str, WSGIRequest) -> None try: transaction_name = None if transaction_style == "function_name": @@ -419,7 +419,7 @@ def _before_get_response(request): _patch_drf() - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() # Rely on WSGI middleware to start a trace _set_transaction_name_and_source(scope, integration.transaction_style, request) @@ -429,7 +429,7 @@ def _before_get_response(request): def _attempt_resolve_again(request, scope, transaction_style): - # type: (WSGIRequest, Scope, str) -> None + # type: (WSGIRequest, sentry_sdk.Scope, str) -> None """ Some django middlewares overwrite request.urlconf so we need to respect that contract, @@ -448,7 +448,7 @@ def _after_get_response(request): if integration.transaction_style != "url": return - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() _attempt_resolve_again(request, scope, integration.transaction_style) @@ -518,7 +518,7 @@ def _got_request_exception(request=None, **kwargs): integration = client.get_integration(DjangoIntegration) if request is not None and integration.transaction_style == "url": - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() _attempt_resolve_again(request, scope, integration.transaction_style) event, hint = event_from_exception( diff --git a/sentry_sdk/integrations/django/asgi.py b/sentry_sdk/integrations/django/asgi.py index bbc742abe9..11691de5a4 100644 --- a/sentry_sdk/integrations/django/asgi.py +++ b/sentry_sdk/integrations/django/asgi.py @@ -13,7 +13,6 @@ from django.core.handlers.wsgi import WSGIRequest import sentry_sdk -from sentry_sdk import Scope from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.consts import OP @@ -112,7 +111,7 @@ async def sentry_patched_asgi_handler(self, scope, receive, send): def sentry_patched_create_request(self, *args, **kwargs): # type: (Any, *Any, **Any) -> Any request, error_response = old_create_request(self, *args, **kwargs) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.add_event_processor(_make_asgi_request_event_processor(request)) return request, error_response @@ -169,7 +168,7 @@ def wrap_async_view(callback): @functools.wraps(callback) async def sentry_wrapped_callback(request, *args, **kwargs): # type: (Any, *Any, **Any) -> Any - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() if sentry_scope.profile is not None: sentry_scope.profile.update_active_thread_id() diff --git a/sentry_sdk/integrations/django/templates.py b/sentry_sdk/integrations/django/templates.py index fb79fdf75b..e91e1a908c 100644 --- a/sentry_sdk/integrations/django/templates.py +++ b/sentry_sdk/integrations/django/templates.py @@ -5,7 +5,6 @@ from django import VERSION as DJANGO_VERSION import sentry_sdk -from sentry_sdk import Scope from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.consts import OP from sentry_sdk.utils import ensure_integration_enabled @@ -93,7 +92,7 @@ def render(request, template_name, context=None, *args, **kwargs): context = context or {} if "sentry_trace_meta" not in context: context["sentry_trace_meta"] = mark_safe( - Scope.get_current_scope().trace_propagation_meta() + sentry_sdk.get_current_scope().trace_propagation_meta() ) with sentry_sdk.start_span( diff --git a/sentry_sdk/integrations/django/views.py b/sentry_sdk/integrations/django/views.py index 01f871a2f6..1bcee492bf 100644 --- a/sentry_sdk/integrations/django/views.py +++ b/sentry_sdk/integrations/django/views.py @@ -1,7 +1,6 @@ import functools import sentry_sdk -from sentry_sdk import Scope from sentry_sdk.consts import OP from sentry_sdk._types import TYPE_CHECKING @@ -76,7 +75,7 @@ def _wrap_sync_view(callback): @functools.wraps(callback) def sentry_wrapped_callback(request, *args, **kwargs): # type: (Any, *Any, **Any) -> Any - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() # set the active thread id to the handler thread for sync views # this isn't necessary for async views since that runs on main if sentry_scope.profile is not None: diff --git a/sentry_sdk/integrations/falcon.py b/sentry_sdk/integrations/falcon.py index be3fe27519..0e0bfec9c8 100644 --- a/sentry_sdk/integrations/falcon.py +++ b/sentry_sdk/integrations/falcon.py @@ -2,7 +2,6 @@ from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations._wsgi_common import RequestExtractor from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware -from sentry_sdk.scope import Scope from sentry_sdk.tracing import SOURCE_FOR_STYLE from sentry_sdk.utils import ( capture_internal_exceptions, @@ -106,7 +105,7 @@ def process_request(self, req, resp, *args, **kwargs): if integration is None: return - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope._name = "falcon" scope.add_event_processor(_make_request_event_processor(req, integration)) diff --git a/sentry_sdk/integrations/fastapi.py b/sentry_sdk/integrations/fastapi.py index 8fd18fef96..09784560b4 100644 --- a/sentry_sdk/integrations/fastapi.py +++ b/sentry_sdk/integrations/fastapi.py @@ -5,7 +5,7 @@ import sentry_sdk from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.integrations import DidNotEnable -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE from sentry_sdk.utils import ( transaction_from_function, @@ -43,7 +43,7 @@ def setup_once(): def _set_transaction_name_and_source(scope, transaction_style, request): - # type: (Scope, str, Any) -> None + # type: (sentry_sdk.Scope, str, Any) -> None name = "" if transaction_style == "endpoint": @@ -87,7 +87,7 @@ def _sentry_get_request_handler(*args, **kwargs): @wraps(old_call) def _sentry_call(*args, **kwargs): # type: (*Any, **Any) -> Any - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() if sentry_scope.profile is not None: sentry_scope.profile.update_active_thread_id() return old_call(*args, **kwargs) @@ -105,9 +105,9 @@ async def _sentry_app(*args, **kwargs): request = args[0] _set_transaction_name_and_source( - Scope.get_current_scope(), integration.transaction_style, request + sentry_sdk.get_current_scope(), integration.transaction_style, request ) - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() extractor = StarletteRequestExtractor(request) info = await extractor.extract_request_info() diff --git a/sentry_sdk/integrations/flask.py b/sentry_sdk/integrations/flask.py index 783576839a..8d82c57695 100644 --- a/sentry_sdk/integrations/flask.py +++ b/sentry_sdk/integrations/flask.py @@ -3,7 +3,7 @@ from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations._wsgi_common import RequestExtractor from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE from sentry_sdk.utils import ( capture_internal_exceptions, @@ -96,14 +96,14 @@ def _add_sentry_trace(sender, template, context, **extra): if "sentry_trace" in context: return - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() trace_meta = Markup(scope.trace_propagation_meta()) context["sentry_trace"] = trace_meta # for backwards compatibility context["sentry_trace_meta"] = trace_meta def _set_transaction_name_and_source(scope, transaction_style, request): - # type: (Scope, str, Request) -> None + # type: (sentry_sdk.Scope, str, Request) -> None try: name_for_style = { "url": request.url_rule.rule, @@ -126,10 +126,10 @@ def _request_started(app, **kwargs): # Set the transaction name and source here, # but rely on WSGI middleware to actually start the transaction _set_transaction_name_and_source( - Scope.get_current_scope(), integration.transaction_style, request + sentry_sdk.get_current_scope(), integration.transaction_style, request ) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() evt_processor = _make_request_event_processor(app, request, integration) scope.add_event_processor(evt_processor) diff --git a/sentry_sdk/integrations/gql.py b/sentry_sdk/integrations/gql.py index 0552edde60..220095f2ac 100644 --- a/sentry_sdk/integrations/gql.py +++ b/sentry_sdk/integrations/gql.py @@ -6,7 +6,7 @@ ) from sentry_sdk.integrations import DidNotEnable, Integration -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii try: import gql # type: ignore[import-not-found] @@ -94,7 +94,7 @@ def _patch_execute(): @ensure_integration_enabled(GQLIntegration, real_execute) def sentry_patched_execute(self, document, *args, **kwargs): # type: (gql.Client, DocumentNode, Any, Any) -> Any - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.add_event_processor(_make_gql_event_processor(self, document)) try: diff --git a/sentry_sdk/integrations/graphene.py b/sentry_sdk/integrations/graphene.py index 6054ea62f0..aa16dce92b 100644 --- a/sentry_sdk/integrations/graphene.py +++ b/sentry_sdk/integrations/graphene.py @@ -3,7 +3,7 @@ import sentry_sdk from sentry_sdk.consts import OP from sentry_sdk.integrations import DidNotEnable, Integration -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -53,7 +53,7 @@ def _patch_graphql(): @ensure_integration_enabled(GrapheneIntegration, old_graphql_sync) def _sentry_patched_graphql_sync(schema, source, *args, **kwargs): # type: (GraphQLSchema, Union[str, Source], Any, Any) -> ExecutionResult - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.add_event_processor(_event_processor) with graphql_span(schema, source, kwargs): @@ -80,7 +80,7 @@ async def _sentry_patched_graphql_async(schema, source, *args, **kwargs): if integration is None: return await old_graphql_async(schema, source, *args, **kwargs) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.add_event_processor(_event_processor) with graphql_span(schema, source, kwargs): @@ -141,7 +141,7 @@ def graphql_span(schema, source, kwargs): }, ) - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() if scope.span: _graphql_span = scope.span.start_child(op=op, description=operation_name) else: diff --git a/sentry_sdk/integrations/grpc/aio/client.py b/sentry_sdk/integrations/grpc/aio/client.py index b67481b5b5..143f0e43a9 100644 --- a/sentry_sdk/integrations/grpc/aio/client.py +++ b/sentry_sdk/integrations/grpc/aio/client.py @@ -12,7 +12,6 @@ import sentry_sdk from sentry_sdk.consts import OP from sentry_sdk.integrations.grpc.consts import SPAN_ORIGIN -from sentry_sdk.scope import Scope class ClientInterceptor: @@ -23,7 +22,10 @@ def _update_client_call_details_metadata_from_scope( metadata = ( list(client_call_details.metadata) if client_call_details.metadata else [] ) - for key, value in Scope.get_current_scope().iter_trace_propagation_headers(): + for ( + key, + value, + ) in sentry_sdk.get_current_scope().iter_trace_propagation_headers(): metadata.append((key, value)) client_call_details = ClientCallDetails( diff --git a/sentry_sdk/integrations/grpc/client.py b/sentry_sdk/integrations/grpc/client.py index c4e89f3737..c12f0ab2c4 100644 --- a/sentry_sdk/integrations/grpc/client.py +++ b/sentry_sdk/integrations/grpc/client.py @@ -3,7 +3,6 @@ from sentry_sdk.consts import OP from sentry_sdk.integrations import DidNotEnable from sentry_sdk.integrations.grpc.consts import SPAN_ORIGIN -from sentry_sdk.scope import Scope if TYPE_CHECKING: from typing import Any, Callable, Iterator, Iterable, Union @@ -74,7 +73,10 @@ def _update_client_call_details_metadata_from_scope(client_call_details): metadata = ( list(client_call_details.metadata) if client_call_details.metadata else [] ) - for key, value in Scope.get_current_scope().iter_trace_propagation_headers(): + for ( + key, + value, + ) in sentry_sdk.get_current_scope().iter_trace_propagation_headers(): metadata.append((key, value)) client_call_details = grpc._interceptor._ClientCallDetails( diff --git a/sentry_sdk/integrations/httpx.py b/sentry_sdk/integrations/httpx.py index e19455118d..d35990cb30 100644 --- a/sentry_sdk/integrations/httpx.py +++ b/sentry_sdk/integrations/httpx.py @@ -1,7 +1,6 @@ import sentry_sdk from sentry_sdk.consts import OP, SPANDATA from sentry_sdk.integrations import Integration, DidNotEnable -from sentry_sdk.scope import Scope from sentry_sdk.tracing import BAGGAGE_HEADER_NAME from sentry_sdk.tracing_utils import should_propagate_trace from sentry_sdk.utils import ( @@ -71,7 +70,7 @@ def send(self, request, **kwargs): for ( key, value, - ) in Scope.get_current_scope().iter_trace_propagation_headers(): + ) in sentry_sdk.get_current_scope().iter_trace_propagation_headers(): logger.debug( "[Tracing] Adding `{key}` header {value} to outgoing request to {url}.".format( key=key, value=value, url=request.url @@ -127,7 +126,7 @@ async def send(self, request, **kwargs): for ( key, value, - ) in Scope.get_current_scope().iter_trace_propagation_headers(): + ) in sentry_sdk.get_current_scope().iter_trace_propagation_headers(): logger.debug( "[Tracing] Adding `{key}` header {value} to outgoing request to {url}.".format( key=key, value=value, url=request.url diff --git a/sentry_sdk/integrations/huey.py b/sentry_sdk/integrations/huey.py index 254775386f..21ccf95813 100644 --- a/sentry_sdk/integrations/huey.py +++ b/sentry_sdk/integrations/huey.py @@ -6,7 +6,7 @@ from sentry_sdk.api import continue_trace, get_baggage, get_traceparent from sentry_sdk.consts import OP, SPANSTATUS from sentry_sdk.integrations import DidNotEnable, Integration -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import ( BAGGAGE_HEADER_NAME, SENTRY_TRACE_HEADER_NAME, @@ -106,7 +106,7 @@ def event_processor(event, hint): def _capture_exception(exc_info): # type: (ExcInfo) -> None - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() if exc_info[0] in HUEY_CONTROL_FLOW_EXCEPTIONS: scope.transaction.set_status(SPANSTATUS.ABORTED) @@ -115,7 +115,7 @@ def _capture_exception(exc_info): scope.transaction.set_status(SPANSTATUS.INTERNAL_ERROR) event, hint = event_from_exception( exc_info, - client_options=Scope.get_client().options, + client_options=sentry_sdk.get_client().options, mechanism={"type": HueyIntegration.identifier, "handled": False}, ) scope.capture_event(event, hint=hint) diff --git a/sentry_sdk/integrations/pyramid.py b/sentry_sdk/integrations/pyramid.py index b7404c8bec..887837c0d6 100644 --- a/sentry_sdk/integrations/pyramid.py +++ b/sentry_sdk/integrations/pyramid.py @@ -6,7 +6,7 @@ from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations._wsgi_common import RequestExtractor from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE from sentry_sdk.utils import ( capture_internal_exceptions, @@ -79,9 +79,9 @@ def sentry_patched_call_view(registry, request, *args, **kwargs): integration = sentry_sdk.get_client().get_integration(PyramidIntegration) _set_transaction_name_and_source( - Scope.get_current_scope(), integration.transaction_style, request + sentry_sdk.get_current_scope(), integration.transaction_style, request ) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.add_event_processor( _make_event_processor(weakref.ref(request), integration) ) @@ -149,7 +149,7 @@ def _capture_exception(exc_info): def _set_transaction_name_and_source(scope, transaction_style, request): - # type: (Scope, str, Request) -> None + # type: (sentry_sdk.Scope, str, Request) -> None try: name_for_style = { "route_name": request.matched_route.name, diff --git a/sentry_sdk/integrations/quart.py b/sentry_sdk/integrations/quart.py index 662074cf9b..0689406672 100644 --- a/sentry_sdk/integrations/quart.py +++ b/sentry_sdk/integrations/quart.py @@ -7,7 +7,7 @@ from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations._wsgi_common import _filter_headers from sentry_sdk.integrations.asgi import SentryAsgiMiddleware -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE from sentry_sdk.utils import ( capture_internal_exceptions, @@ -122,7 +122,7 @@ def decorator(old_func): @ensure_integration_enabled(QuartIntegration, old_func) def _sentry_func(*args, **kwargs): # type: (*Any, **Any) -> Any - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() if scope.profile is not None: scope.profile.active_thread_id = ( threading.current_thread().ident @@ -140,7 +140,7 @@ def _sentry_func(*args, **kwargs): def _set_transaction_name_and_source(scope, transaction_style, request): - # type: (Scope, str, Request) -> None + # type: (sentry_sdk.Scope, str, Request) -> None try: name_for_style = { @@ -169,10 +169,10 @@ async def _request_websocket_started(app, **kwargs): # Set the transaction name here, but rely on ASGI middleware # to actually start the transaction _set_transaction_name_and_source( - Scope.get_current_scope(), integration.transaction_style, request_websocket + sentry_sdk.get_current_scope(), integration.transaction_style, request_websocket ) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() evt_processor = _make_request_event_processor(app, request_websocket, integration) scope.add_event_processor(evt_processor) diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py index fc5c3faf76..6afb07c92d 100644 --- a/sentry_sdk/integrations/rq.py +++ b/sentry_sdk/integrations/rq.py @@ -6,7 +6,6 @@ from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK -from sentry_sdk.scope import Scope from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -105,7 +104,7 @@ def sentry_patched_handle_exception(self, job, *exc_info, **kwargs): @ensure_integration_enabled(RqIntegration, old_enqueue_job) def sentry_patched_enqueue_job(self, job, **kwargs): # type: (Queue, Any, **Any) -> Any - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() if scope.span is not None: job.meta["_sentry_trace_headers"] = dict( scope.iter_trace_propagation_headers() diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index 46250926ef..36e3b4c892 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -10,7 +10,6 @@ from sentry_sdk.integrations._wsgi_common import RequestExtractor, _filter_headers from sentry_sdk.integrations.logging import ignore_logger from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, TRANSACTION_SOURCE_URL -from sentry_sdk.scope import Scope from sentry_sdk.utils import ( capture_internal_exceptions, ensure_integration_enabled, @@ -235,7 +234,7 @@ async def _set_transaction(request, route, **_): # type: (Request, Route, **Any) -> None if request.ctx._sentry_do_integration: with capture_internal_exceptions(): - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() route_name = route.name.replace(request.app.name, "").strip(".") scope.set_transaction_name(route_name, source=TRANSACTION_SOURCE_COMPONENT) @@ -297,7 +296,7 @@ def _legacy_router_get(self, *args): rv = old_router_get(self, *args) if sentry_sdk.get_client().get_integration(SanicIntegration) is not None: with capture_internal_exceptions(): - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() if SanicIntegration.version and SanicIntegration.version >= (21, 3): # Sanic versions above and including 21.3 append the app name to the # route name, and so we need to remove it from Route name so the diff --git a/sentry_sdk/integrations/spark/spark_driver.py b/sentry_sdk/integrations/spark/spark_driver.py index 4c7f694ec0..b55550cbef 100644 --- a/sentry_sdk/integrations/spark/spark_driver.py +++ b/sentry_sdk/integrations/spark/spark_driver.py @@ -1,6 +1,5 @@ import sentry_sdk from sentry_sdk.integrations import Integration -from sentry_sdk.scope import Scope from sentry_sdk.utils import capture_internal_exceptions, ensure_integration_enabled from sentry_sdk._types import TYPE_CHECKING @@ -63,7 +62,7 @@ def _sentry_patched_spark_context_init(self, *args, **kwargs): _start_sentry_listener(self) _set_app_properties() - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() @scope.add_event_processor def process_event(event, hint): diff --git a/sentry_sdk/integrations/spark/spark_worker.py b/sentry_sdk/integrations/spark/spark_worker.py index fa18896516..d9e598603e 100644 --- a/sentry_sdk/integrations/spark/spark_worker.py +++ b/sentry_sdk/integrations/spark/spark_worker.py @@ -2,7 +2,6 @@ import sentry_sdk from sentry_sdk.integrations import Integration -from sentry_sdk.scope import Scope from sentry_sdk.utils import ( capture_internal_exceptions, exc_info_from_error, @@ -65,7 +64,7 @@ def _tag_task_context(): # type: () -> None from pyspark.taskcontext import TaskContext - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() @scope.add_event_processor def process_event(event, hint): diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index c417b834be..3b7aa11a93 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -12,7 +12,7 @@ request_body_within_bounds, ) from sentry_sdk.integrations.asgi import SentryAsgiMiddleware -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import ( SOURCE_FOR_STYLE, TRANSACTION_SOURCE_COMPONENT, @@ -124,7 +124,7 @@ async def _create_span_call(app, scope, receive, send, **kwargs): # Update transaction name with middleware name name, source = _get_transaction_from_middleware(app, scope, integration) if name is not None: - Scope.get_current_scope().set_transaction_name( + sentry_sdk.get_current_scope().set_transaction_name( name, source=source, ) @@ -298,7 +298,7 @@ def _add_user_to_sentry_scope(scope): if email: user_info.setdefault("email", starlette_user.email) - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() sentry_scope.user = user_info @@ -410,10 +410,12 @@ async def _sentry_async_func(*args, **kwargs): request = args[0] _set_transaction_name_and_source( - Scope.get_current_scope(), integration.transaction_style, request + sentry_sdk.get_current_scope(), + integration.transaction_style, + request, ) - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() extractor = StarletteRequestExtractor(request) info = await extractor.extract_request_info() @@ -452,7 +454,7 @@ def _sentry_sync_func(*args, **kwargs): integration = sentry_sdk.get_client().get_integration( StarletteIntegration ) - sentry_scope = Scope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() if sentry_scope.profile is not None: sentry_scope.profile.update_active_thread_id() @@ -521,7 +523,9 @@ def _sentry_jinja2templates_init(self, *args, **kwargs): # type: (Jinja2Templates, *Any, **Any) -> None def add_sentry_trace_meta(request): # type: (Request) -> Dict[str, Any] - trace_meta = Markup(Scope.get_current_scope().trace_propagation_meta()) + trace_meta = Markup( + sentry_sdk.get_current_scope().trace_propagation_meta() + ) return { "sentry_trace_meta": trace_meta, } @@ -655,7 +659,7 @@ def _transaction_name_from_router(scope): def _set_transaction_name_and_source(scope, transaction_style, request): - # type: (Scope, str, Any) -> None + # type: (sentry_sdk.Scope, str, Any) -> None name = None source = SOURCE_FOR_STYLE[transaction_style] diff --git a/sentry_sdk/integrations/starlite.py b/sentry_sdk/integrations/starlite.py index 9ff5045d6c..07259563e0 100644 --- a/sentry_sdk/integrations/starlite.py +++ b/sentry_sdk/integrations/starlite.py @@ -4,7 +4,7 @@ from sentry_sdk.consts import OP from sentry_sdk.integrations import DidNotEnable, Integration from sentry_sdk.integrations.asgi import SentryAsgiMiddleware -from sentry_sdk.scope import Scope as SentryScope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import SOURCE_FOR_STYLE, TRANSACTION_SOURCE_ROUTE from sentry_sdk.utils import ( ensure_integration_enabled, @@ -190,7 +190,7 @@ async def handle_wrapper( if sentry_sdk.get_client().get_integration(StarliteIntegration) is None: return await old_handle(self, scope, receive, send) - sentry_scope = SentryScope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() request: "Request[Any, Any]" = scope["app"].request_class( scope=scope, receive=receive, send=send ) @@ -268,7 +268,7 @@ def exception_handler(exc: Exception, scope: "StarliteScope", _: "State") -> Non if should_send_default_pii(): user_info = retrieve_user_from_scope(scope) if user_info and isinstance(user_info, dict): - sentry_scope = SentryScope.get_isolation_scope() + sentry_scope = sentry_sdk.get_isolation_scope() sentry_scope.set_user(user_info) event, hint = event_from_exception( diff --git a/sentry_sdk/integrations/stdlib.py b/sentry_sdk/integrations/stdlib.py index e0b4d06794..ad8e965a4a 100644 --- a/sentry_sdk/integrations/stdlib.py +++ b/sentry_sdk/integrations/stdlib.py @@ -7,7 +7,7 @@ import sentry_sdk from sentry_sdk.consts import OP, SPANDATA from sentry_sdk.integrations import Integration -from sentry_sdk.scope import Scope, add_global_event_processor +from sentry_sdk.scope import add_global_event_processor from sentry_sdk.tracing_utils import EnvironHeaders, should_propagate_trace from sentry_sdk.utils import ( SENSITIVE_DATA_SUBSTITUTE, @@ -102,7 +102,10 @@ def putrequest(self, method, url, *args, **kwargs): rv = real_putrequest(self, method, url, *args, **kwargs) if should_propagate_trace(client, real_url): - for key, value in Scope.get_current_scope().iter_trace_propagation_headers( + for ( + key, + value, + ) in sentry_sdk.get_current_scope().iter_trace_propagation_headers( span=span ): logger.debug( @@ -202,7 +205,7 @@ def sentry_patched_popen_init(self, *a, **kw): description=description, origin="auto.subprocess.stdlib.subprocess", ) as span: - for k, v in Scope.get_current_scope().iter_trace_propagation_headers( + for k, v in sentry_sdk.get_current_scope().iter_trace_propagation_headers( span=span ): if env is None: diff --git a/sentry_sdk/integrations/strawberry.py b/sentry_sdk/integrations/strawberry.py index 326dd37fd6..148edac334 100644 --- a/sentry_sdk/integrations/strawberry.py +++ b/sentry_sdk/integrations/strawberry.py @@ -5,7 +5,7 @@ from sentry_sdk.consts import OP from sentry_sdk.integrations import Integration, DidNotEnable from sentry_sdk.integrations.logging import ignore_logger -from sentry_sdk.scope import Scope, should_send_default_pii +from sentry_sdk.scope import should_send_default_pii from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT from sentry_sdk.utils import ( capture_internal_exceptions, @@ -297,7 +297,7 @@ async def _sentry_patched_execute_async(*args, **kwargs): return result if "execution_context" in kwargs and result.errors: - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() event_processor = _make_request_event_processor(kwargs["execution_context"]) scope.add_event_processor(event_processor) @@ -309,7 +309,7 @@ def _sentry_patched_execute_sync(*args, **kwargs): result = old_execute_sync(*args, **kwargs) if "execution_context" in kwargs and result.errors: - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() event_processor = _make_request_event_processor(kwargs["execution_context"]) scope.add_event_processor(event_processor) @@ -340,7 +340,7 @@ def _sentry_patched_handle_errors(self, errors, response_data): if not errors: return - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() event_processor = _make_response_event_processor(response_data) scope.add_event_processor(event_processor) diff --git a/sentry_sdk/integrations/threading.py b/sentry_sdk/integrations/threading.py index 63b6e13846..6dd6acbae1 100644 --- a/sentry_sdk/integrations/threading.py +++ b/sentry_sdk/integrations/threading.py @@ -5,7 +5,7 @@ import sentry_sdk from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.integrations import Integration -from sentry_sdk.scope import Scope, use_isolation_scope, use_scope +from sentry_sdk.scope import use_isolation_scope, use_scope from sentry_sdk.utils import ( ensure_integration_enabled, event_from_exception, @@ -55,8 +55,8 @@ def sentry_start(self, *a, **kw): # type: (Thread, *Any, **Any) -> Any integration = sentry_sdk.get_client().get_integration(ThreadingIntegration) if integration.propagate_scope: - isolation_scope = sentry_sdk.Scope.get_isolation_scope() - current_scope = sentry_sdk.Scope.get_current_scope() + isolation_scope = sentry_sdk.get_isolation_scope() + current_scope = sentry_sdk.get_current_scope() else: isolation_scope = None current_scope = None @@ -81,7 +81,7 @@ def sentry_start(self, *a, **kw): def _wrap_run(isolation_scope_to_use, current_scope_to_use, old_run_func): - # type: (Optional[Scope], Optional[Scope], F) -> F + # type: (Optional[sentry_sdk.Scope], Optional[sentry_sdk.Scope], F) -> F @wraps(old_run_func) def run(*a, **kw): # type: (*Any, **Any) -> Any diff --git a/sentry_sdk/metrics.py b/sentry_sdk/metrics.py index dfc1d89734..452bb61658 100644 --- a/sentry_sdk/metrics.py +++ b/sentry_sdk/metrics.py @@ -738,7 +738,7 @@ def _get_aggregator_and_update_tags(key, value, unit, tags): updated_tags.setdefault("release", client.options["release"]) updated_tags.setdefault("environment", client.options["environment"]) - scope = sentry_sdk.Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() local_aggregator = None # We go with the low-level API here to access transaction information as diff --git a/sentry_sdk/profiler/transaction_profiler.py b/sentry_sdk/profiler/transaction_profiler.py index e8ebfa6450..6ed983fb59 100644 --- a/sentry_sdk/profiler/transaction_profiler.py +++ b/sentry_sdk/profiler/transaction_profiler.py @@ -288,7 +288,7 @@ def _set_initial_sampling_decision(self, sampling_context): self.sampled = False return - client = sentry_sdk.Scope.get_client() + client = sentry_sdk.get_client() if not client.is_active(): self.sampled = False return @@ -356,7 +356,7 @@ def stop(self): def __enter__(self): # type: () -> Profile - scope = sentry_sdk.scope.Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() old_profile = scope.profile scope.profile = self @@ -492,7 +492,7 @@ def to_json(self, event_opt, options): def valid(self): # type: () -> bool - client = sentry_sdk.Scope.get_client() + client = sentry_sdk.get_client() if not client.is_active(): return False diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 7ce1ab04cd..0eaf3dc440 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -497,7 +497,7 @@ def get_traceparent(self, *args, **kwargs): Returns the Sentry "sentry-trace" header (aka the traceparent) from the currently active span or the scopes Propagation Context. """ - client = Scope.get_client() + client = self.get_client() # If we have an active span, return traceparent from there if has_tracing_enabled(client.options) and self.span is not None: @@ -512,7 +512,7 @@ def get_traceparent(self, *args, **kwargs): return traceparent # Fall back to isolation scope's traceparent. It always has one - return Scope.get_isolation_scope().get_traceparent() + return self.get_isolation_scope().get_traceparent() def get_baggage(self, *args, **kwargs): # type: (Any, Any) -> Optional[Baggage] @@ -520,7 +520,7 @@ def get_baggage(self, *args, **kwargs): Returns the Sentry "baggage" header containing trace information from the currently active span or the scopes Propagation Context. """ - client = Scope.get_client() + client = self.get_client() # If we have an active span, return baggage from there if has_tracing_enabled(client.options) and self.span is not None: @@ -537,7 +537,7 @@ def get_baggage(self, *args, **kwargs): return Baggage(dynamic_sampling_context) # Fall back to isolation scope's baggage. It always has one - return Scope.get_isolation_scope().get_baggage() + return self.get_isolation_scope().get_baggage() def get_trace_context(self): # type: () -> Any @@ -609,7 +609,7 @@ def iter_trace_propagation_headers(self, *args, **kwargs): If a span is given, the trace data will taken from the span. If no span is given, the trace data is taken from the scope. """ - client = Scope.get_client() + client = self.get_client() if not client.options.get("propagate_traces"): return @@ -627,13 +627,13 @@ def iter_trace_propagation_headers(self, *args, **kwargs): yield header else: # otherwise try headers from current scope - current_scope = Scope.get_current_scope() + current_scope = self.get_current_scope() if current_scope._propagation_context is not None: for header in current_scope.iter_headers(): yield header else: # otherwise fall back to headers from isolation scope - isolation_scope = Scope.get_isolation_scope() + isolation_scope = self.get_isolation_scope() if isolation_scope._propagation_context is not None: for header in isolation_scope.iter_headers(): yield header @@ -643,11 +643,11 @@ def get_active_propagation_context(self): if self._propagation_context is not None: return self._propagation_context - current_scope = Scope.get_current_scope() + current_scope = self.get_current_scope() if current_scope._propagation_context is not None: return current_scope._propagation_context - isolation_scope = Scope.get_isolation_scope() + isolation_scope = self.get_isolation_scope() if isolation_scope._propagation_context is not None: return isolation_scope._propagation_context @@ -779,7 +779,7 @@ def set_user(self, value): # type: (Optional[Dict[str, Any]]) -> None """Sets a user for the scope.""" self._user = value - session = Scope.get_isolation_scope()._session + session = self.get_isolation_scope()._session if session is not None: session.update(user=value) @@ -924,7 +924,7 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): :param hint: An optional value that can be used by `before_breadcrumb` to customize the breadcrumbs that are emitted. """ - client = Scope.get_client() + client = self.get_client() if not client.is_active(): logger.info("Dropped breadcrumb because no client bound") @@ -999,7 +999,7 @@ def start_transaction( """ kwargs.setdefault("scope", self) - client = Scope.get_client() + client = self.get_client() configuration_instrumenter = client.options["instrumenter"] @@ -1066,7 +1066,7 @@ def start_span(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): with new_scope(): kwargs.setdefault("scope", self) - client = Scope.get_client() + client = self.get_client() configuration_instrumenter = client.options["instrumenter"] @@ -1074,7 +1074,7 @@ def start_span(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): return NoOpSpan() # get current span or transaction - span = self.span or Scope.get_isolation_scope().span + span = self.span or self.get_isolation_scope().span if span is None: # New spans get the `trace_id` from the scope @@ -1131,7 +1131,7 @@ def capture_event(self, event, hint=None, scope=None, **scope_kwargs): """ scope = self._merge_scopes(scope, scope_kwargs) - event_id = Scope.get_client().capture_event(event=event, hint=hint, scope=scope) + event_id = self.get_client().capture_event(event=event, hint=hint, scope=scope) if event_id is not None and event.get("type") != "transaction": self.get_isolation_scope()._last_event_id = event_id @@ -1187,7 +1187,7 @@ def capture_exception(self, error=None, scope=None, **scope_kwargs): exc_info = sys.exc_info() event, hint = event_from_exception( - exc_info, client_options=Scope.get_client().options + exc_info, client_options=self.get_client().options ) try: @@ -1215,7 +1215,7 @@ def start_session(self, *args, **kwargs): self.end_session() - client = Scope.get_client() + client = self.get_client() self._session = Session( release=client.options.get("release"), environment=client.options.get("environment"), @@ -1231,7 +1231,7 @@ def end_session(self, *args, **kwargs): if session is not None: session.close() - Scope.get_client().capture_session(session) + self.get_client().capture_session(session) def stop_auto_session_tracking(self, *args, **kwargs): # type: (*Any, **Any) -> None @@ -1365,9 +1365,9 @@ def run_error_processors(self, event, hint): exc_info = hint.get("exc_info") if exc_info is not None: error_processors = chain( - Scope.get_global_scope()._error_processors, - Scope.get_isolation_scope()._error_processors, - Scope.get_current_scope()._error_processors, + self.get_global_scope()._error_processors, + self.get_isolation_scope()._error_processors, + self.get_current_scope()._error_processors, ) for error_processor in error_processors: diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 8e74707608..dbfa4d896b 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -358,7 +358,7 @@ def __repr__(self): def __enter__(self): # type: () -> Span - scope = self.scope or sentry_sdk.Scope.get_current_scope() + scope = self.scope or sentry_sdk.get_current_scope() old_span = scope.span scope.span = self self._context_manager_state = (scope, old_span) @@ -399,9 +399,7 @@ def start_child(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): be removed in the next major version. Going forward, it should only be used by the SDK itself. """ - configuration_instrumenter = sentry_sdk.Scope.get_client().options[ - "instrumenter" - ] + configuration_instrumenter = sentry_sdk.get_client().options["instrumenter"] if instrumenter != configuration_instrumenter: return NoOpSpan() @@ -635,7 +633,7 @@ def finish(self, scope=None, end_timestamp=None): except AttributeError: self.timestamp = datetime.now(timezone.utc) - scope = scope or sentry_sdk.Scope.get_current_scope() + scope = scope or sentry_sdk.get_current_scope() maybe_create_breadcrumbs_from_span(scope, self) return None @@ -903,8 +901,8 @@ def finish( scope, hub ) # type: Optional[sentry_sdk.Scope] - scope = scope or self.scope or sentry_sdk.Scope.get_current_scope() - client = sentry_sdk.Scope.get_client() + scope = scope or self.scope or sentry_sdk.get_current_scope() + client = sentry_sdk.get_client() if not client.is_active(): # We have no active client and therefore nowhere to send this transaction. @@ -1063,7 +1061,7 @@ def _set_initial_sampling_decision(self, sampling_context): 4. If `traces_sampler` is not defined and there's no parent sampling decision, `traces_sample_rate` will be used. """ - client = sentry_sdk.Scope.get_client() + client = sentry_sdk.get_client() transaction_description = "{op}transaction <{name}>".format( op=("<" + self.op + "> " if self.op else ""), name=self.name diff --git a/sentry_sdk/tracing_utils.py b/sentry_sdk/tracing_utils.py index 4a50f50810..0dabfbc486 100644 --- a/sentry_sdk/tracing_utils.py +++ b/sentry_sdk/tracing_utils.py @@ -524,7 +524,7 @@ def populate_from_transaction(cls, transaction): Populate fresh baggage entry with sentry_items and make it immutable if this is the head SDK which originates traces. """ - client = sentry_sdk.Scope.get_client() + client = sentry_sdk.get_client() sentry_items = {} # type: Dict[str, str] if not client.is_active(): @@ -691,7 +691,7 @@ def get_current_span(scope=None): """ Returns the currently active span if there is one running, otherwise `None` """ - scope = scope or sentry_sdk.Scope.get_current_scope() + scope = scope or sentry_sdk.get_current_scope() current_span = scope.span return current_span diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 8a805d3d64..783cfbe361 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -25,7 +25,6 @@ BaseExceptionGroup = None # type: ignore import sentry_sdk -import sentry_sdk.hub from sentry_sdk._compat import PY37 from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH, EndpointType @@ -191,8 +190,14 @@ def capture_internal_exceptions(): def capture_internal_exception(exc_info): # type: (ExcInfo) -> None + """ + Capture an exception that is likely caused by a bug in the SDK + itself. + + These exceptions do not end up in Sentry and are just logged instead. + """ if sentry_sdk.get_client().is_active(): - sentry_sdk.Scope._capture_internal_exception(exc_info) + logger.error("Internal error in sentry_sdk", exc_info=exc_info) def to_timestamp(value): diff --git a/tests/conftest.py b/tests/conftest.py index 3c5e444f6a..70ca60614a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -191,7 +191,7 @@ def sentry_init(request): def inner(*a, **kw): kw.setdefault("transport", TestTransport()) client = sentry_sdk.Client(*a, **kw) - sentry_sdk.Scope.get_global_scope().set_client(client) + sentry_sdk.get_global_scope().set_client(client) if request.node.get_closest_marker("forked"): # Do not run isolation if the test is already running in @@ -199,12 +199,12 @@ def inner(*a, **kw): # fork) yield inner else: - old_client = sentry_sdk.Scope.get_global_scope().client + old_client = sentry_sdk.get_global_scope().client try: - sentry_sdk.Scope.get_current_scope().set_client(None) + sentry_sdk.get_current_scope().set_client(None) yield inner finally: - sentry_sdk.Scope.get_global_scope().set_client(old_client) + sentry_sdk.get_global_scope().set_client(old_client) class TestTransport(Transport): diff --git a/tests/integrations/celery/test_celery.py b/tests/integrations/celery/test_celery.py index 4058e43943..cc0bfd0390 100644 --- a/tests/integrations/celery/test_celery.py +++ b/tests/integrations/celery/test_celery.py @@ -6,7 +6,8 @@ from celery import Celery, VERSION from celery.bin import worker -from sentry_sdk import Scope, start_transaction, get_current_span +import sentry_sdk +from sentry_sdk import start_transaction, get_current_span from sentry_sdk.integrations.celery import ( CeleryIntegration, _wrap_apply_async, @@ -154,7 +155,7 @@ def dummy_task(x, y): foo = 42 # noqa return x / y - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() celery_invocation(dummy_task, 1, 2) _, expected_context = celery_invocation(dummy_task, 1, 0) @@ -256,14 +257,14 @@ def test_no_stackoverflows(celery): @celery.task(name="dummy_task") def dummy_task(): - Scope.get_isolation_scope().set_tag("foo", "bar") + sentry_sdk.get_isolation_scope().set_tag("foo", "bar") results.append(42) for _ in range(10000): dummy_task.delay() assert results == [42] * 10000 - assert not Scope.get_isolation_scope()._tags + assert not sentry_sdk.get_isolation_scope()._tags def test_simple_no_propagation(capture_events, init_celery): diff --git a/tests/integrations/celery/test_update_celery_task_headers.py b/tests/integrations/celery/test_update_celery_task_headers.py index 1680e54d80..705c00de58 100644 --- a/tests/integrations/celery/test_update_celery_task_headers.py +++ b/tests/integrations/celery/test_update_celery_task_headers.py @@ -139,7 +139,7 @@ def test_celery_trace_propagation_default(sentry_init, monitor_beat_tasks): headers = {} span = None - scope = sentry_sdk.Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() outgoing_headers = _update_celery_task_headers(headers, span, monitor_beat_tasks) @@ -175,7 +175,7 @@ def test_celery_trace_propagation_traces_sample_rate( headers = {} span = None - scope = sentry_sdk.Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() outgoing_headers = _update_celery_task_headers(headers, span, monitor_beat_tasks) @@ -211,7 +211,7 @@ def test_celery_trace_propagation_enable_tracing( headers = {} span = None - scope = sentry_sdk.Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() outgoing_headers = _update_celery_task_headers(headers, span, monitor_beat_tasks) diff --git a/tests/integrations/django/myapp/views.py b/tests/integrations/django/myapp/views.py index dcd630363b..c1950059fe 100644 --- a/tests/integrations/django/myapp/views.py +++ b/tests/integrations/django/myapp/views.py @@ -191,15 +191,13 @@ def template_test2(request, *args, **kwargs): @csrf_exempt def template_test3(request, *args, **kwargs): - from sentry_sdk import Scope - - traceparent = Scope.get_current_scope().get_traceparent() + traceparent = sentry_sdk.get_current_scope().get_traceparent() if traceparent is None: - traceparent = Scope.get_isolation_scope().get_traceparent() + traceparent = sentry_sdk.get_isolation_scope().get_traceparent() - baggage = Scope.get_current_scope().get_baggage() + baggage = sentry_sdk.get_current_scope().get_baggage() if baggage is None: - baggage = Scope.get_isolation_scope().get_baggage() + baggage = sentry_sdk.get_isolation_scope().get_baggage() capture_message(traceparent + "\n" + baggage.serialize()) return render(request, "trace_meta.html", {}) diff --git a/tests/integrations/django/test_basic.py b/tests/integrations/django/test_basic.py index 1505204f28..45c25595f3 100644 --- a/tests/integrations/django/test_basic.py +++ b/tests/integrations/django/test_basic.py @@ -16,13 +16,13 @@ except ImportError: from django.core.urlresolvers import reverse +import sentry_sdk from sentry_sdk._compat import PY310 from sentry_sdk import capture_message, capture_exception from sentry_sdk.consts import SPANDATA from sentry_sdk.integrations.django import DjangoIntegration, _set_db_data from sentry_sdk.integrations.django.signals_handlers import _get_receiver_name from sentry_sdk.integrations.executing import ExecutingIntegration -from sentry_sdk.scope import Scope from sentry_sdk.tracing import Span from tests.conftest import unpack_werkzeug_response from tests.integrations.django.myapp.wsgi import application @@ -342,7 +342,7 @@ def test_sql_queries(sentry_init, capture_events, with_integration): sql = connection.cursor() - Scope.get_isolation_scope().clear_breadcrumbs() + sentry_sdk.get_isolation_scope().clear_breadcrumbs() with pytest.raises(OperationalError): # table doesn't even exist @@ -376,7 +376,7 @@ def test_sql_dict_query_params(sentry_init, capture_events): sql = connections["postgres"].cursor() events = capture_events() - Scope.get_isolation_scope().clear_breadcrumbs() + sentry_sdk.get_isolation_scope().clear_breadcrumbs() with pytest.raises(ProgrammingError): sql.execute( @@ -441,7 +441,7 @@ def test_sql_psycopg2_string_composition(sentry_init, capture_events, query): sql = connections["postgres"].cursor() - Scope.get_isolation_scope().clear_breadcrumbs() + sentry_sdk.get_isolation_scope().clear_breadcrumbs() events = capture_events() @@ -474,7 +474,7 @@ def test_sql_psycopg2_placeholders(sentry_init, capture_events): sql = connections["postgres"].cursor() events = capture_events() - Scope.get_isolation_scope().clear_breadcrumbs() + sentry_sdk.get_isolation_scope().clear_breadcrumbs() with pytest.raises(DataError): names = ["foo", "bar"] diff --git a/tests/integrations/falcon/test_falcon.py b/tests/integrations/falcon/test_falcon.py index c88a95a531..0607d3fdeb 100644 --- a/tests/integrations/falcon/test_falcon.py +++ b/tests/integrations/falcon/test_falcon.py @@ -7,7 +7,6 @@ import sentry_sdk from sentry_sdk.integrations.falcon import FalconIntegration from sentry_sdk.integrations.logging import LoggingIntegration -from sentry_sdk.scope import Scope from sentry_sdk.utils import parse_version @@ -380,17 +379,17 @@ def test_does_not_leak_scope(sentry_init, capture_events): sentry_init(integrations=[FalconIntegration()]) events = capture_events() - Scope.get_isolation_scope().set_tag("request_data", False) + sentry_sdk.get_isolation_scope().set_tag("request_data", False) app = falcon.API() class Resource: def on_get(self, req, resp): - Scope.get_isolation_scope().set_tag("request_data", True) + sentry_sdk.get_isolation_scope().set_tag("request_data", True) def generator(): for row in range(1000): - assert Scope.get_isolation_scope()._tags["request_data"] + assert sentry_sdk.get_isolation_scope()._tags["request_data"] yield (str(row) + "\n").encode() @@ -404,7 +403,7 @@ def generator(): expected_response = "".join(str(row) + "\n" for row in range(1000)) assert response.text == expected_response assert not events - assert not Scope.get_isolation_scope()._tags["request_data"] + assert not sentry_sdk.get_isolation_scope()._tags["request_data"] @pytest.mark.skipif( diff --git a/tests/integrations/flask/test_flask.py b/tests/integrations/flask/test_flask.py index c35bf2acb5..03a3b0b9d0 100644 --- a/tests/integrations/flask/test_flask.py +++ b/tests/integrations/flask/test_flask.py @@ -28,7 +28,6 @@ capture_exception, ) from sentry_sdk.integrations.logging import LoggingIntegration -from sentry_sdk.scope import Scope from sentry_sdk.serializer import MAX_DATABAG_BREADTH @@ -278,7 +277,7 @@ def test_flask_session_tracking(sentry_init, capture_envelopes, app): @app.route("/") def index(): - Scope.get_isolation_scope().set_user({"ip_address": "1.2.3.4", "id": "42"}) + sentry_sdk.get_isolation_scope().set_user({"ip_address": "1.2.3.4", "id": "42"}) try: raise ValueError("stuff") except Exception: @@ -666,15 +665,15 @@ def test_does_not_leak_scope(sentry_init, capture_events, app): sentry_init(integrations=[flask_sentry.FlaskIntegration()]) events = capture_events() - Scope.get_isolation_scope().set_tag("request_data", False) + sentry_sdk.get_isolation_scope().set_tag("request_data", False) @app.route("/") def index(): - Scope.get_isolation_scope().set_tag("request_data", True) + sentry_sdk.get_isolation_scope().set_tag("request_data", True) def generate(): for row in range(1000): - assert Scope.get_isolation_scope()._tags["request_data"] + assert sentry_sdk.get_isolation_scope()._tags["request_data"] yield str(row) + "\n" @@ -685,7 +684,7 @@ def generate(): assert response.data.decode() == "".join(str(row) + "\n" for row in range(1000)) assert not events - assert not Scope.get_isolation_scope()._tags["request_data"] + assert not sentry_sdk.get_isolation_scope()._tags["request_data"] def test_scoped_test_client(sentry_init, app): diff --git a/tests/integrations/loguru/test_loguru.py b/tests/integrations/loguru/test_loguru.py index 98b8cb4dee..6030108de1 100644 --- a/tests/integrations/loguru/test_loguru.py +++ b/tests/integrations/loguru/test_loguru.py @@ -54,7 +54,7 @@ def test_just_log( if not created_event: assert not events - breadcrumbs = sentry_sdk.Scope.get_isolation_scope()._breadcrumbs + breadcrumbs = sentry_sdk.get_isolation_scope()._breadcrumbs if ( not disable_breadcrumbs and created_event is not None ): # not None == not TRACE or DEBUG level @@ -92,7 +92,7 @@ def test_breadcrumb_format(sentry_init, capture_events): logger.info("test") formatted_message = "test" - breadcrumbs = sentry_sdk.Scope.get_isolation_scope()._breadcrumbs + breadcrumbs = sentry_sdk.get_isolation_scope()._breadcrumbs (breadcrumb,) = breadcrumbs assert breadcrumb["message"] == formatted_message diff --git a/tests/integrations/opentelemetry/test_span_processor.py b/tests/integrations/opentelemetry/test_span_processor.py index 8064e127f6..7045b52f17 100644 --- a/tests/integrations/opentelemetry/test_span_processor.py +++ b/tests/integrations/opentelemetry/test_span_processor.py @@ -6,11 +6,11 @@ import pytest from opentelemetry.trace import SpanKind, SpanContext, Status, StatusCode +import sentry_sdk from sentry_sdk.integrations.opentelemetry.span_processor import ( SentrySpanProcessor, link_trace_context_to_error_event, ) -from sentry_sdk.scope import Scope from sentry_sdk.tracing import Span, Transaction from sentry_sdk.tracing_utils import extract_sentrytrace_data @@ -24,7 +24,7 @@ def test_is_sentry_span(): client = MagicMock() client.options = {"instrumenter": "otel"} client.dsn = "https://1234567890abcdef@o123456.ingest.sentry.io/123456" - Scope.get_global_scope().set_client(client) + sentry_sdk.get_global_scope().set_client(client) assert not span_processor._is_sentry_span(otel_span) @@ -307,7 +307,7 @@ def test_on_start_transaction(): fake_client = MagicMock() fake_client.options = {"instrumenter": "otel"} fake_client.dsn = "https://1234567890abcdef@o123456.ingest.sentry.io/123456" - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) with mock.patch( "sentry_sdk.integrations.opentelemetry.span_processor.start_transaction", @@ -351,7 +351,7 @@ def test_on_start_child(): fake_client = MagicMock() fake_client.options = {"instrumenter": "otel"} fake_client.dsn = "https://1234567890abcdef@o123456.ingest.sentry.io/123456" - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) fake_span = MagicMock() @@ -416,7 +416,7 @@ def test_on_end_sentry_transaction(): fake_client = MagicMock() fake_client.options = {"instrumenter": "otel"} - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) fake_sentry_span = MagicMock(spec=Transaction) fake_sentry_span.set_context = MagicMock() @@ -452,7 +452,7 @@ def test_on_end_sentry_span(): fake_client = MagicMock() fake_client.options = {"instrumenter": "otel"} - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) fake_sentry_span = MagicMock(spec=Span) fake_sentry_span.set_context = MagicMock() @@ -479,7 +479,7 @@ def test_link_trace_context_to_error_event(): """ fake_client = MagicMock() fake_client.options = {"instrumenter": "otel"} - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) span_id = "1234567890abcdef" trace_id = "1234567890abcdef1234567890abcdef" @@ -537,7 +537,7 @@ def test_pruning_old_spans_on_start(): fake_client = MagicMock() fake_client.options = {"instrumenter": "otel", "debug": False} fake_client.dsn = "https://1234567890abcdef@o123456.ingest.sentry.io/123456" - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) span_processor = SentrySpanProcessor() @@ -579,7 +579,7 @@ def test_pruning_old_spans_on_end(): fake_client = MagicMock() fake_client.options = {"instrumenter": "otel"} - Scope.get_global_scope().set_client(fake_client) + sentry_sdk.get_global_scope().set_client(fake_client) fake_sentry_span = MagicMock(spec=Span) fake_sentry_span.set_context = MagicMock() diff --git a/tests/integrations/quart/test_quart.py b/tests/integrations/quart/test_quart.py index d4b4c61d97..321f07e3c6 100644 --- a/tests/integrations/quart/test_quart.py +++ b/tests/integrations/quart/test_quart.py @@ -4,6 +4,7 @@ import pytest import pytest_asyncio +import sentry_sdk from sentry_sdk import ( set_tag, capture_message, @@ -11,7 +12,6 @@ ) from sentry_sdk.integrations.logging import LoggingIntegration import sentry_sdk.integrations.quart as quart_sentry -from sentry_sdk.scope import Scope from quart import Quart, Response, abort, stream_with_context from quart.views import View @@ -378,15 +378,15 @@ async def test_does_not_leak_scope(sentry_init, capture_events, app): sentry_init(integrations=[quart_sentry.QuartIntegration()]) events = capture_events() - Scope.get_isolation_scope().set_tag("request_data", False) + sentry_sdk.get_isolation_scope().set_tag("request_data", False) @app.route("/") async def index(): - Scope.get_isolation_scope().set_tag("request_data", True) + sentry_sdk.get_isolation_scope().set_tag("request_data", True) async def generate(): for row in range(1000): - assert Scope.get_isolation_scope()._tags["request_data"] + assert sentry_sdk.get_isolation_scope()._tags["request_data"] yield str(row) + "\n" @@ -398,7 +398,7 @@ async def generate(): str(row) + "\n" for row in range(1000) ) assert not events - assert not Scope.get_isolation_scope()._tags["request_data"] + assert not sentry_sdk.get_isolation_scope()._tags["request_data"] @pytest.mark.asyncio diff --git a/tests/integrations/rq/test_rq.py b/tests/integrations/rq/test_rq.py index 02db5eba8e..e445b588be 100644 --- a/tests/integrations/rq/test_rq.py +++ b/tests/integrations/rq/test_rq.py @@ -4,9 +4,9 @@ import rq from fakeredis import FakeStrictRedis +import sentry_sdk from sentry_sdk import start_transaction from sentry_sdk.integrations.rq import RqIntegration -from sentry_sdk.scope import Scope from sentry_sdk.utils import parse_version @@ -181,7 +181,7 @@ def test_tracing_disabled( queue = rq.Queue(connection=FakeStrictRedis()) worker = rq.SimpleWorker([queue], connection=queue.connection) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() queue.enqueue(crashing_job, foo=None) worker.work(burst=True) diff --git a/tests/integrations/sanic/test_sanic.py b/tests/integrations/sanic/test_sanic.py index 574fd673bb..598bae0134 100644 --- a/tests/integrations/sanic/test_sanic.py +++ b/tests/integrations/sanic/test_sanic.py @@ -7,9 +7,9 @@ import pytest +import sentry_sdk from sentry_sdk import capture_message from sentry_sdk.integrations.sanic import SanicIntegration -from sentry_sdk.scope import Scope from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT, TRANSACTION_SOURCE_URL from sanic import Sanic, request, response, __version__ as SANIC_VERSION_RAW @@ -234,12 +234,12 @@ def test_concurrency(sentry_init, app): @app.route("/context-check/") async def context_check(request, i): - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.set_tag("i", i) await asyncio.sleep(random.random()) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() assert scope._tags["i"] == i return response.text("ok") @@ -329,7 +329,7 @@ async def runner(): else: asyncio.run(runner()) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() assert not scope._tags diff --git a/tests/integrations/sqlalchemy/test_sqlalchemy.py b/tests/integrations/sqlalchemy/test_sqlalchemy.py index cedb542e93..2b95fe02d4 100644 --- a/tests/integrations/sqlalchemy/test_sqlalchemy.py +++ b/tests/integrations/sqlalchemy/test_sqlalchemy.py @@ -9,10 +9,10 @@ from sqlalchemy.orm import relationship, sessionmaker from sqlalchemy import text +import sentry_sdk from sentry_sdk import capture_message, start_transaction from sentry_sdk.consts import DEFAULT_MAX_VALUE_LENGTH, SPANDATA from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration -from sentry_sdk.scope import Scope from sentry_sdk.serializer import MAX_EVENT_BYTES from sentry_sdk.tracing_utils import record_sql_queries from sentry_sdk.utils import json_dumps @@ -235,7 +235,7 @@ def test_large_event_not_truncated(sentry_init, capture_events): long_str = "x" * (DEFAULT_MAX_VALUE_LENGTH + 10) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() @scope.add_event_processor def processor(event, hint): diff --git a/tests/integrations/threading/test_threading.py b/tests/integrations/threading/test_threading.py index 328d0708c4..2b6b280c1e 100644 --- a/tests/integrations/threading/test_threading.py +++ b/tests/integrations/threading/test_threading.py @@ -7,7 +7,6 @@ import sentry_sdk from sentry_sdk import capture_message from sentry_sdk.integrations.threading import ThreadingIntegration -from sentry_sdk.scope import Scope original_start = Thread.start original_run = Thread.run @@ -45,7 +44,7 @@ def test_propagates_hub(sentry_init, capture_events, propagate_hub): events = capture_events() def stage1(): - Scope.get_isolation_scope().set_tag("stage1", "true") + sentry_sdk.get_isolation_scope().set_tag("stage1", "true") t = Thread(target=stage2) t.start() diff --git a/tests/integrations/tornado/test_tornado.py b/tests/integrations/tornado/test_tornado.py index d379d3dae4..294f605f6a 100644 --- a/tests/integrations/tornado/test_tornado.py +++ b/tests/integrations/tornado/test_tornado.py @@ -2,9 +2,9 @@ import pytest +import sentry_sdk from sentry_sdk import start_transaction, capture_message from sentry_sdk.integrations.tornado import TornadoIntegration -from sentry_sdk.scope import Scope from tornado.web import RequestHandler, Application, HTTPError from tornado.testing import AsyncHTTPTestCase @@ -37,11 +37,11 @@ def bogustest(self): class CrashingHandler(RequestHandler): def get(self): - Scope.get_isolation_scope().set_tag("foo", "42") + sentry_sdk.get_isolation_scope().set_tag("foo", "42") 1 / 0 def post(self): - Scope.get_isolation_scope().set_tag("foo", "43") + sentry_sdk.get_isolation_scope().set_tag("foo", "43") 1 / 0 @@ -53,12 +53,12 @@ def get(self): class HelloHandler(RequestHandler): async def get(self): - Scope.get_isolation_scope().set_tag("foo", "42") + sentry_sdk.get_isolation_scope().set_tag("foo", "42") return b"hello" async def post(self): - Scope.get_isolation_scope().set_tag("foo", "43") + sentry_sdk.get_isolation_scope().set_tag("foo", "43") return b"hello" @@ -101,7 +101,7 @@ def test_basic(tornado_testcase, sentry_init, capture_events): ) assert event["transaction_info"] == {"source": "component"} - assert not Scope.get_isolation_scope()._tags + assert not sentry_sdk.get_isolation_scope()._tags @pytest.mark.parametrize( diff --git a/tests/test_api.py b/tests/test_api.py index d8db519e09..ae194af7fd 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -13,10 +13,12 @@ set_tags, configure_scope, push_scope, + get_global_scope, + get_current_scope, + get_isolation_scope, ) from sentry_sdk.client import Client, NonRecordingClient -from sentry_sdk.scope import Scope @pytest.mark.forked @@ -35,7 +37,7 @@ def test_get_current_span_default_hub(sentry_init): assert get_current_span() is None - scope = Scope.get_current_scope() + scope = get_current_scope() fake_span = mock.MagicMock() scope.span = fake_span @@ -68,7 +70,7 @@ def test_traceparent_with_tracing_enabled(sentry_init): def test_traceparent_with_tracing_disabled(sentry_init): sentry_init() - propagation_context = Scope.get_isolation_scope()._propagation_context + propagation_context = get_isolation_scope()._propagation_context expected_traceparent = "%s-%s" % ( propagation_context.trace_id, propagation_context.span_id, @@ -79,7 +81,7 @@ def test_traceparent_with_tracing_disabled(sentry_init): @pytest.mark.forked def test_baggage_with_tracing_disabled(sentry_init): sentry_init(release="1.0.0", environment="dev") - propagation_context = Scope.get_isolation_scope()._propagation_context + propagation_context = get_isolation_scope()._propagation_context expected_baggage = ( "sentry-trace_id={},sentry-environment=dev,sentry-release=1.0.0".format( propagation_context.trace_id @@ -115,7 +117,7 @@ def test_continue_trace(sentry_init): with start_transaction(transaction): assert transaction.name == "some name" - propagation_context = Scope.get_isolation_scope()._propagation_context + propagation_context = get_isolation_scope()._propagation_context assert propagation_context.trace_id == transaction.trace_id == trace_id assert propagation_context.parent_span_id == parent_span_id assert propagation_context.parent_sampled == parent_sampled @@ -128,7 +130,7 @@ def test_continue_trace(sentry_init): def test_is_initialized(): assert not is_initialized() - scope = Scope.get_global_scope() + scope = get_global_scope() scope.set_client(Client()) assert is_initialized() diff --git a/tests/test_basics.py b/tests/test_basics.py index 022f44edb8..cc4594d8ab 100644 --- a/tests/test_basics.py +++ b/tests/test_basics.py @@ -24,7 +24,6 @@ isolation_scope, new_scope, Hub, - Scope, ) from sentry_sdk.integrations import ( _AUTO_ENABLING_INTEGRATIONS, @@ -78,7 +77,7 @@ def error_processor(event, exc_info): event["exception"]["values"][0]["value"] += " whatever" return event - Scope.get_isolation_scope().add_error_processor(error_processor, ValueError) + sentry_sdk.get_isolation_scope().add_error_processor(error_processor, ValueError) try: raise ValueError("aha!") @@ -388,7 +387,7 @@ def test_breadcrumbs(sentry_init, capture_events): category="auth", message="Authenticated user %s" % i, level="info" ) - Scope.get_isolation_scope().clear() + sentry_sdk.get_isolation_scope().clear() capture_exception(ValueError()) (event,) = events @@ -432,7 +431,7 @@ def test_attachments(sentry_init, capture_envelopes): this_file = os.path.abspath(__file__.rstrip("c")) - scope = Scope.get_isolation_scope() + scope = sentry_sdk.get_isolation_scope() scope.add_attachment(bytes=b"Hello World!", filename="message.txt") scope.add_attachment(path=this_file) @@ -466,7 +465,7 @@ def test_attachments_graceful_failure( sentry_init() envelopes = capture_envelopes() - Scope.get_isolation_scope().add_attachment(path="non_existent") + sentry_sdk.get_isolation_scope().add_attachment(path="non_existent") capture_exception(ValueError()) (envelope,) = envelopes diff --git a/tests/test_client.py b/tests/test_client.py index 15a140d377..099e8ef288 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -599,7 +599,7 @@ def callback(scope): def test_client_debug_option_enabled(sentry_init, caplog): sentry_init(debug=True) - sentry_sdk.Scope.get_isolation_scope()._capture_internal_exception( + sentry_sdk.get_isolation_scope()._capture_internal_exception( (ValueError, ValueError("OK"), None) ) assert "OK" in caplog.text @@ -611,7 +611,7 @@ def test_client_debug_option_disabled(with_client, sentry_init, caplog): if with_client: sentry_init() - sentry_sdk.Scope.get_isolation_scope()._capture_internal_exception( + sentry_sdk.get_isolation_scope()._capture_internal_exception( (ValueError, ValueError("OK"), None) ) assert "OK" not in caplog.text @@ -694,7 +694,7 @@ def test_cyclic_data(sentry_init, capture_events): other_data = "" data["not_cyclic"] = other_data data["not_cyclic2"] = other_data - sentry_sdk.Scope.get_isolation_scope().set_extra("foo", data) + sentry_sdk.get_isolation_scope().set_extra("foo", data) capture_message("hi") (event,) = events @@ -1065,7 +1065,7 @@ def test_debug_option( else: sentry_init(debug=client_option) - sentry_sdk.Scope.get_isolation_scope()._capture_internal_exception( + sentry_sdk.get_isolation_scope()._capture_internal_exception( (ValueError, ValueError("something is wrong"), None) ) if debug_output_expected: diff --git a/tests/test_metrics.py b/tests/test_metrics.py index a29a18b0cf..537f8a9646 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -6,7 +6,7 @@ import pytest import sentry_sdk -from sentry_sdk import Scope, metrics +from sentry_sdk import metrics from sentry_sdk.tracing import TRANSACTION_SOURCE_ROUTE from sentry_sdk.envelope import parse_json @@ -538,8 +538,9 @@ def test_transaction_name( ts = time.time() envelopes = capture_envelopes() - scope = Scope.get_current_scope() - scope.set_transaction_name("/user/{user_id}", source="route") + sentry_sdk.get_current_scope().set_transaction_name( + "/user/{user_id}", source="route" + ) metrics.distribution("dist", 1.0, tags={"a": "b"}, timestamp=ts) metrics.distribution("dist", 2.0, tags={"a": "b"}, timestamp=ts) metrics.distribution("dist", 2.0, tags={"a": "b"}, timestamp=ts) diff --git a/tests/test_sessions.py b/tests/test_sessions.py index cc25f71cbb..c10b9262ce 100644 --- a/tests/test_sessions.py +++ b/tests/test_sessions.py @@ -14,16 +14,16 @@ def test_basic(sentry_init, capture_envelopes): sentry_init(release="fun-release", environment="not-fun-env") envelopes = capture_envelopes() - sentry_sdk.Scope.get_isolation_scope().start_session() + sentry_sdk.get_isolation_scope().start_session() try: - scope = sentry_sdk.Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() scope.set_user({"id": "42"}) raise Exception("all is wrong") except Exception: sentry_sdk.capture_exception() - sentry_sdk.Scope.get_isolation_scope().end_session() + sentry_sdk.get_isolation_scope().end_session() sentry_sdk.flush() assert len(envelopes) == 2 @@ -53,6 +53,7 @@ def test_aggregates(sentry_init, capture_envelopes): with auto_session_tracking(session_mode="request"): with sentry_sdk.new_scope() as scope: try: + scope = sentry_sdk.get_current_scope() scope.set_user({"id": "42"}) raise Exception("all is wrong") except Exception: @@ -61,8 +62,8 @@ def test_aggregates(sentry_init, capture_envelopes): with auto_session_tracking(session_mode="request"): pass - sentry_sdk.Scope.get_isolation_scope().start_session(session_mode="request") - sentry_sdk.Scope.get_isolation_scope().end_session() + sentry_sdk.get_isolation_scope().start_session(session_mode="request") + sentry_sdk.get_isolation_scope().end_session() sentry_sdk.flush() assert len(envelopes) == 2 @@ -100,8 +101,8 @@ def test_aggregates_explicitly_disabled_session_tracking_request_mode( with auto_session_tracking(session_mode="request"): pass - sentry_sdk.Scope.get_isolation_scope().start_session(session_mode="request") - sentry_sdk.Scope.get_isolation_scope().end_session() + sentry_sdk.get_isolation_scope().start_session(session_mode="request") + sentry_sdk.get_isolation_scope().end_session() sentry_sdk.flush() sess = envelopes[1] @@ -135,6 +136,6 @@ def test_no_thread_on_shutdown_no_errors(sentry_init): with auto_session_tracking(session_mode="request"): pass - sentry_sdk.Scope.get_isolation_scope().start_session(session_mode="request") - sentry_sdk.Scope.get_isolation_scope().end_session() + sentry_sdk.get_isolation_scope().start_session(session_mode="request") + sentry_sdk.get_isolation_scope().end_session() sentry_sdk.flush() diff --git a/tests/test_transport.py b/tests/test_transport.py index 5fc81d6817..f692b27736 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -11,10 +11,21 @@ from pytest_localserver.http import WSGIServer from werkzeug.wrappers import Request, Response -import sentry_sdk -from sentry_sdk import Client, add_breadcrumb, capture_message, Scope +from sentry_sdk import ( + Client, + add_breadcrumb, + capture_message, + get_global_scope, + isolation_scope, + get_isolation_scope, + Hub, +) from sentry_sdk.envelope import Envelope, Item, parse_json -from sentry_sdk.transport import KEEP_ALIVE_SOCKET_OPTIONS, _parse_rate_limits +from sentry_sdk.transport import ( + KEEP_ALIVE_SOCKET_OPTIONS, + _parse_rate_limits, + HttpTransport, +) from sentry_sdk.integrations.logging import LoggingIntegration, ignore_logger CapturedData = namedtuple("CapturedData", ["path", "event", "envelope", "compressed"]) @@ -128,8 +139,8 @@ def test_transport_works( if use_pickle: client = pickle.loads(pickle.dumps(client)) - sentry_sdk.Scope.get_global_scope().set_client(client) - request.addfinalizer(lambda: sentry_sdk.Scope.get_global_scope().set_client(None)) + get_global_scope().set_client(client) + request.addfinalizer(lambda: get_global_scope().set_client(None)) add_breadcrumb( level="info", message="i like bread", timestamp=datetime.now(timezone.utc) @@ -264,8 +275,8 @@ def test_transport_infinite_loop(capturing_server, request, make_client): # to an infinite loop ignore_logger("werkzeug") - sentry_sdk.Scope.get_global_scope().set_client(client) - with sentry_sdk.isolation_scope(): + get_global_scope().set_client(client) + with isolation_scope(): capture_message("hi") client.flush() @@ -280,8 +291,8 @@ def test_transport_no_thread_on_shutdown_no_errors(capturing_server, make_client "threading.Thread.start", side_effect=RuntimeError("can't create new thread at interpreter shutdown"), ): - sentry_sdk.Scope.get_global_scope().set_client(client) - with sentry_sdk.isolation_scope(): + get_global_scope().set_client(client) + with isolation_scope(): capture_message("hi") # nothing exploded but also no events can be sent anymore @@ -434,7 +445,7 @@ def intercepting_fetch(*args, **kwargs): client.transport._last_client_report_sent = 0 outcomes_enabled = True - scope = Scope() + scope = get_isolation_scope() scope.add_attachment(bytes=b"Hello World", filename="hello.txt") client.capture_event({"type": "error"}, scope=scope) client.flush() @@ -639,15 +650,15 @@ def test_metric_bucket_limits_with_all_namespaces( def test_hub_cls_backwards_compat(): - class TestCustomHubClass(sentry_sdk.Hub): + class TestCustomHubClass(Hub): pass - transport = sentry_sdk.transport.HttpTransport( + transport = HttpTransport( defaultdict(lambda: None, {"dsn": "https://123abc@example.com/123"}) ) with pytest.deprecated_call(): - assert transport.hub_cls is sentry_sdk.Hub + assert transport.hub_cls is Hub with pytest.deprecated_call(): transport.hub_cls = TestCustomHubClass diff --git a/tests/tracing/test_integration_tests.py b/tests/tracing/test_integration_tests.py index adab261745..47170af97b 100644 --- a/tests/tracing/test_integration_tests.py +++ b/tests/tracing/test_integration_tests.py @@ -4,9 +4,9 @@ import pytest import random +import sentry_sdk from sentry_sdk import ( capture_message, - Scope, start_span, start_transaction, ) @@ -66,7 +66,7 @@ def test_continue_from_headers(sentry_init, capture_envelopes, sampled, sample_r with start_span() as old_span: old_span.sampled = sampled headers = dict( - Scope.get_current_scope().iter_trace_propagation_headers(old_span) + sentry_sdk.get_current_scope().iter_trace_propagation_headers(old_span) ) headers["baggage"] = ( "other-vendor-value-1=foo;bar;baz, " @@ -101,7 +101,7 @@ def test_continue_from_headers(sentry_init, capture_envelopes, sampled, sample_r with start_transaction(child_transaction): # change the transaction name from "WRONG" to make sure the change # is reflected in the final data - Scope.get_current_scope().transaction = "ho" + sentry_sdk.get_current_scope().transaction = "ho" capture_message("hello") # in this case the child transaction won't be captured @@ -271,7 +271,7 @@ def test_trace_propagation_meta_head_sdk(sentry_init): with start_transaction(transaction): with start_span(op="foo", description="foodesc") as current_span: span = current_span - meta = Scope.get_current_scope().trace_propagation_meta() + meta = sentry_sdk.get_current_scope().trace_propagation_meta() ind = meta.find(">") + 1 sentry_trace, baggage = meta[:ind], meta[ind:] diff --git a/tests/tracing/test_misc.py b/tests/tracing/test_misc.py index fcfcf31b69..de25acd7d2 100644 --- a/tests/tracing/test_misc.py +++ b/tests/tracing/test_misc.py @@ -6,7 +6,7 @@ from unittest.mock import MagicMock import sentry_sdk -from sentry_sdk import Scope, start_span, start_transaction, set_measurement +from sentry_sdk import start_span, start_transaction, set_measurement from sentry_sdk.consts import MATCH_ALL from sentry_sdk.tracing import Span, Transaction from sentry_sdk.tracing_utils import should_propagate_trace @@ -84,7 +84,7 @@ def test_finds_transaction_on_scope(sentry_init): transaction = start_transaction(name="dogpark") - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() # See note in Scope class re: getters and setters of the `transaction` # property. For the moment, assigning to scope.transaction merely sets the @@ -113,7 +113,7 @@ def test_finds_transaction_when_descendent_span_is_on_scope( transaction = start_transaction(name="dogpark") child_span = transaction.start_child(op="sniffing") - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() scope._span = child_span # this is the same whether it's the transaction itself or one of its @@ -136,7 +136,7 @@ def test_finds_orphan_span_on_scope(sentry_init): span = start_span(op="sniffing") - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() scope._span = span assert scope._span is not None @@ -150,7 +150,7 @@ def test_finds_non_orphan_span_on_scope(sentry_init): transaction = start_transaction(name="dogpark") child_span = transaction.start_child(op="sniffing") - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() scope._span = child_span assert scope._span is not None @@ -357,7 +357,7 @@ def test_should_propagate_trace_to_sentry( def test_start_transaction_updates_scope_name_source(sentry_init): sentry_init(traces_sample_rate=1.0) - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() with start_transaction(name="foobar", source="route"): assert scope._transaction == "foobar" diff --git a/tests/tracing/test_noop_span.py b/tests/tracing/test_noop_span.py index c9aad60590..ec2c7782f3 100644 --- a/tests/tracing/test_noop_span.py +++ b/tests/tracing/test_noop_span.py @@ -15,7 +15,7 @@ def test_noop_start_transaction(sentry_init): op="task", name="test_transaction_name" ) as transaction: assert isinstance(transaction, NoOpSpan) - assert sentry_sdk.Scope.get_current_scope().span is transaction + assert sentry_sdk.get_current_scope().span is transaction transaction.name = "new name" @@ -25,7 +25,7 @@ def test_noop_start_span(sentry_init): with sentry_sdk.start_span(op="http", description="GET /") as span: assert isinstance(span, NoOpSpan) - assert sentry_sdk.Scope.get_current_scope().span is span + assert sentry_sdk.get_current_scope().span is span span.set_tag("http.response.status_code", 418) span.set_data("http.entity_type", "teapot") @@ -39,7 +39,7 @@ def test_noop_transaction_start_child(sentry_init): with transaction.start_child(op="child_task") as child: assert isinstance(child, NoOpSpan) - assert sentry_sdk.Scope.get_current_scope().span is child + assert sentry_sdk.get_current_scope().span is child def test_noop_span_start_child(sentry_init): @@ -49,4 +49,4 @@ def test_noop_span_start_child(sentry_init): with span.start_child(op="child_task") as child: assert isinstance(child, NoOpSpan) - assert sentry_sdk.Scope.get_current_scope().span is child + assert sentry_sdk.get_current_scope().span is child diff --git a/tests/tracing/test_sampling.py b/tests/tracing/test_sampling.py index 491281fa67..2e6ed0dab3 100644 --- a/tests/tracing/test_sampling.py +++ b/tests/tracing/test_sampling.py @@ -4,7 +4,8 @@ import pytest -from sentry_sdk import Scope, start_span, start_transaction, capture_exception +import sentry_sdk +from sentry_sdk import start_span, start_transaction, capture_exception from sentry_sdk.tracing import Transaction from sentry_sdk.utils import logger @@ -56,7 +57,7 @@ def test_get_transaction_and_span_from_scope_regardless_of_sampling_decision( with start_transaction(name="/", sampled=sampling_decision): with start_span(op="child-span"): with start_span(op="child-child-span"): - scope = Scope.get_current_scope() + scope = sentry_sdk.get_current_scope() assert scope.span.op == "child-child-span" assert scope.transaction.name == "/" From 6af28ad7b1c5cfbfc02149c46164e984e0ab9103 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Mon, 29 Jul 2024 11:53:14 +0200 Subject: [PATCH 2/6] Update CHANGELOG.md Co-authored-by: Ivana Kellyer --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4752726262..1f811b6d8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -504,7 +504,7 @@ For a shorter version of what you need to do, to upgrade to Sentry SDK 2.0 see: After: ```python - from sentry_sdkd import get_isolation_scope + from sentry_sdk import get_isolation_scope scope = get_isolation_scope() # do something with `scope` From ab2dec9d4153c89631bd3533270a7609a41c8920 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Mon, 29 Jul 2024 12:19:18 +0200 Subject: [PATCH 3/6] remove Scope._capture_internal_exception --- sentry_sdk/scope.py | 14 ++------------ tests/conftest.py | 5 ++--- tests/test_client.py | 46 +++++++++++++++++--------------------------- 3 files changed, 22 insertions(+), 43 deletions(-) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 0eaf3dc440..4e07e818c9 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -28,6 +28,7 @@ ) from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.utils import ( + capture_internal_exception, capture_internal_exceptions, ContextVar, event_from_exception, @@ -1193,21 +1194,10 @@ def capture_exception(self, error=None, scope=None, **scope_kwargs): try: return self.capture_event(event, hint=hint, scope=scope, **scope_kwargs) except Exception: - self._capture_internal_exception(sys.exc_info()) + capture_internal_exception(sys.exc_info()) return None - @staticmethod - def _capture_internal_exception(exc_info): - # type: (ExcInfo) -> None - """ - Capture an exception that is likely caused by a bug in the SDK - itself. - - These exceptions do not end up in Sentry and are just logged instead. - """ - logger.error("Internal error in sentry_sdk", exc_info=exc_info) - def start_session(self, *args, **kwargs): # type: (*Any, **Any) -> None """Starts a new session.""" diff --git a/tests/conftest.py b/tests/conftest.py index 70ca60614a..96363c7ab1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,6 +21,7 @@ eventlet = None import sentry_sdk +import sentry_sdk.utils from sentry_sdk.envelope import Envelope from sentry_sdk.integrations import ( # noqa: F401 _DEFAULT_INTEGRATIONS, @@ -91,9 +92,7 @@ def _(): for e in errors: reraise(*e) - monkeypatch.setattr( - sentry_sdk.Scope, "_capture_internal_exception", _capture_internal_exception - ) + sentry_sdk.utils.capture_internal_exception = _capture_internal_exception return errors diff --git a/tests/test_client.py b/tests/test_client.py index 099e8ef288..f6c2cec05c 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -21,6 +21,7 @@ capture_event, set_tag, ) +from sentry_sdk.utils import capture_internal_exception from sentry_sdk.integrations.executing import ExecutingIntegration from sentry_sdk.transport import Transport from sentry_sdk.serializer import MAX_DATABAG_BREADTH @@ -350,29 +351,24 @@ def test_simple_transport(sentry_init): def test_ignore_errors(sentry_init, capture_events): - with mock.patch( - "sentry_sdk.scope.Scope._capture_internal_exception" - ) as mock_capture_internal_exception: - - class MyDivisionError(ZeroDivisionError): - pass + sentry_init(ignore_errors=[ZeroDivisionError]) + events = capture_events() - sentry_init(ignore_errors=[ZeroDivisionError], transport=_TestTransport()) + class MyDivisionError(ZeroDivisionError): + pass - def e(exc): - try: - raise exc - except Exception: - capture_exception() + def e(exc): + try: + raise exc + except Exception: + capture_exception() - e(ZeroDivisionError()) - e(MyDivisionError()) - e(ValueError()) + e(ZeroDivisionError()) + e(MyDivisionError()) + e(ValueError()) - assert mock_capture_internal_exception.call_count == 1 - assert ( - mock_capture_internal_exception.call_args[0][0][0] == EnvelopeCapturedError - ) + assert len(events) == 1 + assert events[0]["exception"]["values"][0]["type"] == "ValueError" def test_include_local_variables_enabled(sentry_init, capture_events): @@ -599,9 +595,7 @@ def callback(scope): def test_client_debug_option_enabled(sentry_init, caplog): sentry_init(debug=True) - sentry_sdk.get_isolation_scope()._capture_internal_exception( - (ValueError, ValueError("OK"), None) - ) + capture_internal_exception((ValueError, ValueError("OK"), None)) assert "OK" in caplog.text @@ -611,9 +605,7 @@ def test_client_debug_option_disabled(with_client, sentry_init, caplog): if with_client: sentry_init() - sentry_sdk.get_isolation_scope()._capture_internal_exception( - (ValueError, ValueError("OK"), None) - ) + capture_internal_exception((ValueError, ValueError("OK"), None)) assert "OK" not in caplog.text @@ -1065,9 +1057,7 @@ def test_debug_option( else: sentry_init(debug=client_option) - sentry_sdk.get_isolation_scope()._capture_internal_exception( - (ValueError, ValueError("something is wrong"), None) - ) + capture_internal_exception((ValueError, ValueError("something is wrong"), None)) if debug_output_expected: assert "something is wrong" in caplog.text else: From 9fb1e63d1a31240529c415d90c4441b3ef61d7f9 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Mon, 29 Jul 2024 12:22:09 +0200 Subject: [PATCH 4/6] review fixes --- tests/test_transport.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/test_transport.py b/tests/test_transport.py index f692b27736..2e2ad3c4cd 100644 --- a/tests/test_transport.py +++ b/tests/test_transport.py @@ -11,11 +11,11 @@ from pytest_localserver.http import WSGIServer from werkzeug.wrappers import Request, Response +import sentry_sdk from sentry_sdk import ( Client, add_breadcrumb, capture_message, - get_global_scope, isolation_scope, get_isolation_scope, Hub, @@ -139,8 +139,8 @@ def test_transport_works( if use_pickle: client = pickle.loads(pickle.dumps(client)) - get_global_scope().set_client(client) - request.addfinalizer(lambda: get_global_scope().set_client(None)) + sentry_sdk.get_global_scope().set_client(client) + request.addfinalizer(lambda: sentry_sdk.get_global_scope().set_client(None)) add_breadcrumb( level="info", message="i like bread", timestamp=datetime.now(timezone.utc) @@ -275,7 +275,7 @@ def test_transport_infinite_loop(capturing_server, request, make_client): # to an infinite loop ignore_logger("werkzeug") - get_global_scope().set_client(client) + sentry_sdk.get_global_scope().set_client(client) with isolation_scope(): capture_message("hi") client.flush() @@ -291,7 +291,7 @@ def test_transport_no_thread_on_shutdown_no_errors(capturing_server, make_client "threading.Thread.start", side_effect=RuntimeError("can't create new thread at interpreter shutdown"), ): - get_global_scope().set_client(client) + sentry_sdk.get_global_scope().set_client(client) with isolation_scope(): capture_message("hi") From fa9a887c5565451220d9b8c187e4b54e9de1bc42 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Mon, 29 Jul 2024 13:39:44 +0200 Subject: [PATCH 5/6] remove staticmethod --- tests/conftest.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 96363c7ab1..c31a394fb5 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -76,12 +76,11 @@ def clean_scopes(): @pytest.fixture(autouse=True) -def internal_exceptions(request, monkeypatch): +def internal_exceptions(request): errors = [] if "tests_internal_exceptions" in request.keywords: return - @staticmethod def _capture_internal_exception(exc_info): errors.append(exc_info) From 1d6420c7aeea51174d29882aa3fed445a0035f88 Mon Sep 17 00:00:00 2001 From: Neel Shah Date: Mon, 29 Jul 2024 14:08:14 +0200 Subject: [PATCH 6/6] Fix sphinx circular import bs --- sentry_sdk/consts.py | 6 ++---- sentry_sdk/utils.py | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 9a7823dbfb..af36e34b08 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -32,8 +32,6 @@ class EndpointType(Enum): from typing import Tuple from typing_extensions import TypedDict - from sentry_sdk.integrations import Integration - from sentry_sdk._types import ( BreadcrumbProcessor, ContinuousProfilerMode, @@ -487,7 +485,7 @@ def __init__( environment=None, # type: Optional[str] server_name=None, # type: Optional[str] shutdown_timeout=2, # type: float - integrations=[], # type: Sequence[Integration] # noqa: B006 + integrations=[], # type: Sequence[sentry_sdk.integrations.Integration] # noqa: B006 in_app_include=[], # type: List[str] # noqa: B006 in_app_exclude=[], # type: List[str] # noqa: B006 default_integrations=True, # type: bool @@ -514,7 +512,7 @@ def __init__( profiles_sampler=None, # type: Optional[TracesSampler] profiler_mode=None, # type: Optional[ProfilerMode] auto_enabling_integrations=True, # type: bool - disabled_integrations=None, # type: Optional[Sequence[Integration]] + disabled_integrations=None, # type: Optional[Sequence[sentry_sdk.integrations.Integration]] auto_session_tracking=True, # type: bool send_client_reports=True, # type: bool _experiments={}, # type: Experiments # noqa: B006 diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 783cfbe361..862eedae9c 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -54,7 +54,6 @@ from gevent.hub import Hub - import sentry_sdk.integrations from sentry_sdk._types import Event, ExcInfo P = ParamSpec("P")