From f789126044855278da7969275d48138c2bc267e8 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 19 Dec 2025 09:19:51 +0100 Subject: [PATCH 1/3] tests: Test preserialization of attributes --- tests/test_logs.py | 29 +++++++++++++++++++++++++++++ tests/test_metrics.py | 30 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tests/test_logs.py b/tests/test_logs.py index 7bdf80365f..376f201871 100644 --- a/tests/test_logs.py +++ b/tests/test_logs.py @@ -548,3 +548,32 @@ def record_lost_event(reason, data_category=None, item=None, *, quantity=1): } ] } + + +def test_preserialization(sentry_init, capture_envelopes): + """We don't store references to objects in attributes.""" + sentry_init(enable_logs=True) + + envelopes = capture_envelopes() + + class Cat: + pass + + instance = Cat() + dictionary = {"color": "tortoiseshell"} + + sentry_sdk.logger.warning( + "Hello world!", + attributes={ + "instance": instance, + "dictionary": dictionary, + }, + ) + + get_client().flush() + + logs = envelopes_to_logs(envelopes) + (log,) = logs + + assert isinstance(log["attributes"]["instance"], str) + assert isinstance(log["attributes"]["dictionary"], str) diff --git a/tests/test_metrics.py b/tests/test_metrics.py index ee37ee467c..f54ec2b8ea 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -290,3 +290,33 @@ def record_lost_event(reason, data_category, quantity): assert len(lost_event_calls) == 5 for lost_event_call in lost_event_calls: assert lost_event_call == ("queue_overflow", "trace_metric", 1) + + +def test_preserialization(sentry_init, capture_envelopes): + """We don't store references to objects in attributes.""" + sentry_init() + + envelopes = capture_envelopes() + + class Cat: + pass + + instance = Cat() + dictionary = {"color": "tortoiseshell"} + + sentry_sdk.metrics.count( + "test.counter", + 1, + attributes={ + "instance": instance, + "dictionary": dictionary, + }, + ) + + get_client().flush() + + metrics = envelopes_to_metrics(envelopes) + (metric,) = metrics + + assert isinstance(metric["attributes"]["instance"], str) + assert isinstance(metric["attributes"]["dictionary"], str) From 5cb726414a3e418a79ef6e9744fee96137932a65 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 19 Dec 2025 09:36:26 +0100 Subject: [PATCH 2/3] . --- tests/test_logs.py | 13 ++++++++++--- tests/test_metrics.py | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/tests/test_logs.py b/tests/test_logs.py index eab3ab472f..f2ddab7888 100644 --- a/tests/test_logs.py +++ b/tests/test_logs.py @@ -600,9 +600,16 @@ def test_log_attributes_override_scope_attributes(sentry_init, capture_envelopes @minimum_python_37 -def test_preserialization(sentry_init, capture_envelopes): - """We don't store references to objects in attributes.""" - sentry_init(enable_logs=True) +def test_attributes_preserialized_in_before_send(sentry_init, capture_envelopes): + """We don't surface references to objects in attributes.""" + + def before_send_log(log, _): + assert isinstance(log["attributes"]["instance"], str) + assert isinstance(log["attributes"]["dictionary"], str) + + return log + + sentry_init(enable_logs=True, before_send_log=before_send_log) envelopes = capture_envelopes() diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 004a249ae6..d64ce748e4 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -337,9 +337,16 @@ def test_metric_attributes_override_scope_attributes(sentry_init, capture_envelo assert metric["attributes"]["temp.attribute"] == "value2" -def test_preserialization(sentry_init, capture_envelopes): - """We don't store references to objects in attributes.""" - sentry_init() +def test_attributes_preserialized_in_before_send(sentry_init, capture_envelopes): + """We don't surface references to objects in attributes.""" + + def before_send_metric(metric, _): + assert isinstance(metric["attributes"]["instance"], str) + assert isinstance(metric["attributes"]["dictionary"], str) + + return metric + + sentry_init(before_send_metric=before_send_metric) envelopes = capture_envelopes() From f6e1222a5318df29788a105f76412925a38c8979 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 19 Dec 2025 09:41:35 +0100 Subject: [PATCH 3/3] add a scope attrs test too --- tests/test_attributes.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/tests/test_attributes.py b/tests/test_attributes.py index b4ba2d77a7..40b31fa7f1 100644 --- a/tests/test_attributes.py +++ b/tests/test_attributes.py @@ -117,3 +117,41 @@ def test_remove_attribute(sentry_init, capture_envelopes): (metric,) = metrics assert "some.attribute" not in metric["attributes"] + + +def test_scope_attributes_preserialized(sentry_init, capture_envelopes): + def before_send_metric(metric, _): + # Scope attrs show up serialized in before_send + assert isinstance(metric["attributes"]["instance"], str) + assert isinstance(metric["attributes"]["dictionary"], str) + + return metric + + sentry_init(before_send_metric=before_send_metric) + + envelopes = capture_envelopes() + + class Cat: + pass + + instance = Cat() + dictionary = {"color": "tortoiseshell"} + + with sentry_sdk.new_scope() as scope: + scope.set_attribute("instance", instance) + scope.set_attribute("dictionary", dictionary) + + # Scope attrs are stored preserialized + assert isinstance(scope._attributes["instance"], str) + assert isinstance(scope._attributes["dictionary"], str) + + sentry_sdk.metrics.count("test", 1) + + sentry_sdk.get_client().flush() + + metrics = envelopes_to_metrics(envelopes) + (metric,) = metrics + + # Attrs originally from the scope are serialized when sent + assert isinstance(metric["attributes"]["instance"], str) + assert isinstance(metric["attributes"]["dictionary"], str)