Repository: getsentry/sentry-python

Issue:
Add `include_source_context` option
### Problem Statement

Some users do not like the source context to be there and want to disable it.

### Solution Brainstorm

For this we need to add a SDK option `include_source_context` that defaults to `True`.
If set to false, the source context should not be included.

Here is probably the place where to decide whether to add the source context or not: 
https://github.com/getsentry/sentry-python/blob/antonpirker/celery-beat-wo-restart/sentry_sdk/utils.py#L614-L625


Discussion:

Resolving patch:
diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py
--- a/sentry_sdk/utils.py
+++ b/sentry_sdk/utils.py
@@ -594,8 +594,10 @@ def filename_for_module(module, abs_path):
         return abs_path
 
 
-def serialize_frame(frame, tb_lineno=None, include_local_variables=True):
-    # type: (FrameType, Optional[int], bool) -> Dict[str, Any]
+def serialize_frame(
+    frame, tb_lineno=None, include_local_variables=True, include_source_context=True
+):
+    # type: (FrameType, Optional[int], bool, bool) -> Dict[str, Any]
     f_code = getattr(frame, "f_code", None)
     if not f_code:
         abs_path = None
@@ -611,18 +613,19 @@ def serialize_frame(frame, tb_lineno=None, include_local_variables=True):
     if tb_lineno is None:
         tb_lineno = frame.f_lineno
 
-    pre_context, context_line, post_context = get_source_context(frame, tb_lineno)
-
     rv = {
         "filename": filename_for_module(module, abs_path) or None,
         "abs_path": os.path.abspath(abs_path) if abs_path else None,
         "function": function or "<unknown>",
         "module": module,
         "lineno": tb_lineno,
-        "pre_context": pre_context,
-        "context_line": context_line,
-        "post_context": post_context,
     }  # type: Dict[str, Any]
+
+    if include_source_context:
+        rv["pre_context"], rv["context_line"], rv["post_context"] = get_source_context(
+            frame, tb_lineno
+        )
+
     if include_local_variables:
         rv["vars"] = frame.f_locals
 
@@ -1240,7 +1243,6 @@ def sanitize_url(url, remove_authority=True, remove_query_values=True):
 
 
 def parse_url(url, sanitize=True):
-
     # type: (str, bool) -> ParsedUrl
     """
     Splits a URL into a url (including path), query and fragment. If sanitize is True, the query


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,14 @@
 import pytest
 import re
+import sys
 
-from sentry_sdk.utils import is_valid_sample_rate, logger, parse_url, sanitize_url
+from sentry_sdk.utils import (
+    is_valid_sample_rate,
+    logger,
+    parse_url,
+    sanitize_url,
+    serialize_frame,
+)
 
 try:
     from unittest import mock  # python 3.3 and above
@@ -221,3 +228,16 @@ def test_warns_on_invalid_sample_rate(rate, StringContaining):  # noqa: N803
         result = is_valid_sample_rate(rate, source="Testing")
         logger.warning.assert_any_call(StringContaining("Given sample rate is invalid"))
         assert result is False
+
+
+@pytest.mark.parametrize(
+    "include_source_context",
+    [True, False],
+)
+def test_include_source_context_when_serializing_frame(include_source_context):
+    frame = sys._getframe()
+    result = serialize_frame(frame, include_source_context=include_source_context)
+
+    assert include_source_context ^ ("pre_context" in result) ^ True
+    assert include_source_context ^ ("context_line" in result) ^ True
+    assert include_source_context ^ ("post_context" in result) ^ True