diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 990cce7547..3c94ea6bf0 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -71,7 +71,18 @@ def _get_options(*args, **kwargs): for key, value in iteritems(options): if key not in rv: + # Option "with_locals" was renamed to "include_local_variables" + if key == "with_locals": + msg = ( + "Deprecated: The option 'with_locals' was renamed to 'include_local_variables'. " + "Please use 'include_local_variables'. The option 'with_locals' will be removed in the future." + ) + logger.warning(msg) + rv["include_local_variables"] = value + continue + raise TypeError("Unknown option %r" % (key,)) + rv[key] = value if rv["dsn"] is None: @@ -213,7 +224,7 @@ def _prepare_event( "values": [ { "stacktrace": current_stacktrace( - self.options["with_locals"] + self.options["include_local_variables"] ), "crashed": False, "current": True, diff --git a/sentry_sdk/consts.py b/sentry_sdk/consts.py index 18add06f14..99f70cdc7f 100644 --- a/sentry_sdk/consts.py +++ b/sentry_sdk/consts.py @@ -89,7 +89,6 @@ class ClientConstructor(object): def __init__( self, dsn=None, # type: Optional[str] - with_locals=True, # type: bool max_breadcrumbs=DEFAULT_MAX_BREADCRUMBS, # type: int release=None, # type: Optional[str] environment=None, # type: Optional[str] @@ -125,6 +124,7 @@ def __init__( before_send_transaction=None, # type: Optional[TransactionProcessor] project_root=None, # type: Optional[str] enable_tracing=None, # type: Optional[bool] + include_local_variables=True, # type: Optional[bool] trace_propagation_targets=[ # noqa: B006 MATCH_ALL ], # type: Optional[Sequence[str]] diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index 86cea09bd8..1d48922076 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -219,7 +219,7 @@ def _emit(self, record): "values": [ { "stacktrace": current_stacktrace( - client_options["with_locals"] + client_options["include_local_variables"] ), "crashed": False, "current": True, diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 93301ccbf3..48098a885b 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -591,7 +591,7 @@ def filename_for_module(module, abs_path): return abs_path -def serialize_frame(frame, tb_lineno=None, with_locals=True): +def serialize_frame(frame, tb_lineno=None, include_local_variables=True): # type: (FrameType, Optional[int], bool) -> Dict[str, Any] f_code = getattr(frame, "f_code", None) if not f_code: @@ -620,13 +620,13 @@ def serialize_frame(frame, tb_lineno=None, with_locals=True): "context_line": context_line, "post_context": post_context, } # type: Dict[str, Any] - if with_locals: + if include_local_variables: rv["vars"] = frame.f_locals return rv -def current_stacktrace(with_locals=True): +def current_stacktrace(include_local_variables=True): # type: (bool) -> Any __tracebackhide__ = True frames = [] @@ -634,7 +634,9 @@ def current_stacktrace(with_locals=True): f = sys._getframe() # type: Optional[FrameType] while f is not None: if not should_hide_frame(f): - frames.append(serialize_frame(f, with_locals=with_locals)) + frames.append( + serialize_frame(f, include_local_variables=include_local_variables) + ) f = f.f_back frames.reverse() @@ -668,12 +670,16 @@ def single_exception_from_error_tuple( ) if client_options is None: - with_locals = True + include_local_variables = True else: - with_locals = client_options["with_locals"] + include_local_variables = client_options["include_local_variables"] frames = [ - serialize_frame(tb.tb_frame, tb_lineno=tb.tb_lineno, with_locals=with_locals) + serialize_frame( + tb.tb_frame, + tb_lineno=tb.tb_lineno, + include_local_variables=include_local_variables, + ) for tb in iter_stacks(tb) ] diff --git a/tests/integrations/pure_eval/test_pure_eval.py b/tests/integrations/pure_eval/test_pure_eval.py index e7da025144..2d1a92026e 100644 --- a/tests/integrations/pure_eval/test_pure_eval.py +++ b/tests/integrations/pure_eval/test_pure_eval.py @@ -8,8 +8,8 @@ @pytest.mark.parametrize("integrations", [[], [PureEvalIntegration()]]) -def test_with_locals_enabled(sentry_init, capture_events, integrations): - sentry_init(with_locals=True, integrations=integrations) +def test_include_local_variables_enabled(sentry_init, capture_events, integrations): + sentry_init(include_local_variables=True, integrations=integrations) events = capture_events() def foo(): diff --git a/tests/test_client.py b/tests/test_client.py index a85ac08e31..bf7a956ea2 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -1,6 +1,7 @@ # coding: utf-8 import os import json +import mock import pytest import subprocess import sys @@ -22,6 +23,7 @@ from sentry_sdk.transport import Transport from sentry_sdk._compat import reraise, text_type, PY2 from sentry_sdk.utils import HAS_CHAINED_EXCEPTIONS +from sentry_sdk.utils import logger from sentry_sdk.serializer import MAX_DATABAG_BREADTH from sentry_sdk.consts import DEFAULT_MAX_BREADCRUMBS @@ -291,8 +293,48 @@ def e(exc): pytest.raises(EventCapturedError, lambda: e(ValueError())) -def test_with_locals_enabled(sentry_init, capture_events): - sentry_init(with_locals=True) +def test_with_locals_deprecation_enabled(sentry_init): + with mock.patch.object(logger, "warning", mock.Mock()) as fake_warning: + sentry_init(with_locals=True) + + client = Hub.current.client + assert "with_locals" not in client.options + assert "include_local_variables" in client.options + assert client.options["include_local_variables"] + + fake_warning.assert_called_once_with( + "Deprecated: The option 'with_locals' was renamed to 'include_local_variables'. Please use 'include_local_variables'. The option 'with_locals' will be removed in the future." + ) + + +def test_with_locals_deprecation_disabled(sentry_init): + with mock.patch.object(logger, "warning", mock.Mock()) as fake_warning: + sentry_init(with_locals=False) + + client = Hub.current.client + assert "with_locals" not in client.options + assert "include_local_variables" in client.options + assert not client.options["include_local_variables"] + + fake_warning.assert_called_once_with( + "Deprecated: The option 'with_locals' was renamed to 'include_local_variables'. Please use 'include_local_variables'. The option 'with_locals' will be removed in the future." + ) + + +def test_include_local_variables_deprecation(sentry_init): + with mock.patch.object(logger, "warning", mock.Mock()) as fake_warning: + sentry_init(include_local_variables=False) + + client = Hub.current.client + assert "with_locals" not in client.options + assert "include_local_variables" in client.options + assert not client.options["include_local_variables"] + + fake_warning.assert_not_called() + + +def test_include_local_variables_enabled(sentry_init, capture_events): + sentry_init(include_local_variables=True) events = capture_events() try: 1 / 0 @@ -307,8 +349,8 @@ def test_with_locals_enabled(sentry_init, capture_events): ) -def test_with_locals_disabled(sentry_init, capture_events): - sentry_init(with_locals=False) +def test_include_local_variables_disabled(sentry_init, capture_events): + sentry_init(include_local_variables=False) events = capture_events() try: 1 / 0 @@ -372,7 +414,7 @@ def bar(): def test_attach_stacktrace_enabled_no_locals(sentry_init, capture_events): - sentry_init(attach_stacktrace=True, with_locals=False) + sentry_init(attach_stacktrace=True, include_local_variables=False) events = capture_events() def foo():