From 946decc9ff9b9f057612f39a297b4df95a5ab0dd Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:08:24 +0100 Subject: [PATCH 1/8] ref: Remove flag storage from StreamedSpan --- sentry_sdk/traces.py | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 531a06b1fd..e0235268f0 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -17,9 +17,6 @@ from sentry_sdk._types import Attributes, AttributeValue -FLAGS_CAPACITY = 10 - - class SpanStatus(str, Enum): OK = "ok" ERROR = "error" @@ -65,10 +62,10 @@ class StreamedSpan: """ A span holds timing information of a block of code. - Spans can have multiple child spans thus forming a span tree. + Spans can have multiple child spans, thus forming a span tree. - This is the Span First span implementation. The original transaction-based - span implementation lives in tracing.Span. + This is the Span First span implementation that streams spans. The original + transaction-based span implementation lives in tracing.Span. """ __slots__ = ( @@ -77,7 +74,6 @@ class StreamedSpan: "_span_id", "_trace_id", "_status", - "_flags", ) def __init__( @@ -99,8 +95,6 @@ def __init__( self.set_status(SpanStatus.OK) self.set_source(SegmentSource.CUSTOM) - self._flags: dict[str, bool] = {} - def get_attributes(self) -> "Attributes": return self._attributes @@ -143,10 +137,6 @@ def get_name(self) -> str: def set_name(self, name: str) -> None: self._name = name - def set_flag(self, flag: str, result: bool) -> None: - if len(self._flags) < FLAGS_CAPACITY: - self._flags[flag] = result - def set_op(self, op: str) -> None: self.set_attribute("sentry.op", op) From f3ee55c909ee080c6807f32fc5943e77b44fde20 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:12:51 +0100 Subject: [PATCH 2/8] ref: Tweak StreamedSpan interface --- sentry_sdk/traces.py | 53 ++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 29 deletions(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index e0235268f0..333a9a5c5f 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -92,8 +92,16 @@ def __init__( self._span_id: "Optional[str]" = None self._trace_id: "Optional[str]" = trace_id - self.set_status(SpanStatus.OK) - self.set_source(SegmentSource.CUSTOM) + self._status = SpanStatus.OK.value + self.set_attribute("sentry.span.source", SegmentSource.CUSTOM.value) + + def __repr__(self) -> str: + return ( + f"<{self.__class__.__name__}(" + f"name={self._name}, " + f"trace_id={self.trace_id}, " + f"span_id={self.span_id}>" + ) def get_attributes(self) -> "Attributes": return self._attributes @@ -111,44 +119,31 @@ def remove_attribute(self, key: str) -> None: except KeyError: pass - def get_status(self) -> "Union[SpanStatus, str]": - if self._status in {s.value for s in SpanStatus}: - return SpanStatus(self._status) - + @property + def status(self) -> "str": return self._status - def set_status(self, status: "Union[SpanStatus, str]") -> None: + @status.setter + def status(self, status: "Union[SpanStatus, str]") -> None: if isinstance(status, Enum): status = status.value - self._status = status - - def set_http_status(self, http_status: int) -> None: - self.set_attribute(SPANDATA.HTTP_STATUS_CODE, http_status) + if status not in {e.value for e in SpanStatus}: + logger.debug( + f'Unsupported span status {status}. Expected one of: "ok", "error"' + ) + return - if http_status >= 400: - self.set_status(SpanStatus.ERROR) - else: - self.set_status(SpanStatus.OK) + self._status = status - def get_name(self) -> str: + @property + def name(self) -> str: return self._name - def set_name(self, name: str) -> None: + @name.setter + def name(self, name: str) -> None: self._name = name - def set_op(self, op: str) -> None: - self.set_attribute("sentry.op", op) - - def set_origin(self, origin: str) -> None: - self.set_attribute("sentry.origin", origin) - - def set_source(self, source: "Union[str, SegmentSource]") -> None: - if isinstance(source, Enum): - source = source.value - - self.set_attribute("sentry.span.source", source) - @property def span_id(self) -> str: if not self._span_id: From 47ed910d32d99c66d2a142a21d8494aa02740492 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:21:15 +0100 Subject: [PATCH 3/8] Add missing logger --- sentry_sdk/traces.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 333a9a5c5f..4a1ad8d396 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -10,7 +10,7 @@ from typing import TYPE_CHECKING from sentry_sdk.consts import SPANDATA -from sentry_sdk.utils import format_attribute +from sentry_sdk.utils import format_attribute, logger if TYPE_CHECKING: from typing import Optional, Union From 5023c76a6248ab91e23939e7225d093bcad41ac5 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:40:02 +0100 Subject: [PATCH 4/8] fixes --- sentry_sdk/traces.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 4a1ad8d396..d733899e4b 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -9,7 +9,6 @@ from enum import Enum from typing import TYPE_CHECKING -from sentry_sdk.consts import SPANDATA from sentry_sdk.utils import format_attribute, logger if TYPE_CHECKING: @@ -100,7 +99,7 @@ def __repr__(self) -> str: f"<{self.__class__.__name__}(" f"name={self._name}, " f"trace_id={self.trace_id}, " - f"span_id={self.span_id}>" + f"span_id={self.span_id})>" ) def get_attributes(self) -> "Attributes": From 644544705c10cb26a5c238ff9475742eb7a132ee Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:40:34 +0100 Subject: [PATCH 5/8] ref: Add active to StreamedSpan --- sentry_sdk/traces.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index d733899e4b..768e658b5b 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -70,6 +70,7 @@ class StreamedSpan: __slots__ = ( "_name", "_attributes", + "_active", "_span_id", "_trace_id", "_status", @@ -80,9 +81,11 @@ def __init__( *, name: str, attributes: "Optional[Attributes]" = None, + active: bool = True, trace_id: "Optional[str]" = None, ): self._name: str = name + self._active: bool = active self._attributes: "Attributes" = {} if attributes: for attribute, value in attributes.items(): @@ -99,7 +102,8 @@ def __repr__(self) -> str: f"<{self.__class__.__name__}(" f"name={self._name}, " f"trace_id={self.trace_id}, " - f"span_id={self.span_id})>" + f"span_id={self.span_id}, " + f"active={self._active})>" ) def get_attributes(self) -> "Attributes": From 47e6211f473ebad9caf55762ce83dd3b73136a81 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:24:32 +0100 Subject: [PATCH 6/8] Add property --- sentry_sdk/traces.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 768e658b5b..859bebdacd 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -147,6 +147,10 @@ def name(self) -> str: def name(self, name: str) -> None: self._name = name + @property + def active(self) -> bool: + return self._active + @property def span_id(self) -> str: if not self._span_id: From 1e7b694d9f1e9ac9d3ff9b86d20cb9d83178247a Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:33:20 +0100 Subject: [PATCH 7/8] ref: Add no-op streaming span class --- sentry_sdk/traces.py | 53 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 859bebdacd..4f0807d007 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -164,3 +164,56 @@ def trace_id(self) -> str: self._trace_id = uuid.uuid4().hex return self._trace_id + + +class NoOpStreamedSpan(StreamedSpan): + __slots__ = ( + ) + + def __init__( + self, + ) -> None: + pass + + def __repr__(self) -> str: + return f"<{self.__class__.__name__}(sampled={self.sampled})>" + + def get_attributes(self) -> "Attributes": + return {} + + def set_attribute(self, key: str, value: "AttributeValue") -> None: + pass + + def set_attributes(self, attributes: "Attributes") -> None: + pass + + def remove_attribute(self, key: str) -> None: + pass + + @property + def status(self) -> "str": + return SpanStatus.OK.value + + @status.setter + def status(self, status: "Union[SpanStatus, str]") -> None: + pass + + @property + def name(self) -> str: + return "" + + @name.setter + def name(self, value: str) -> None: + pass + + @property + def active(self) -> bool: + return True + + @property + def span_id(self) -> str: + return "0000000000000000" + + @property + def trace_id(self) -> str: + return "00000000000000000000000000000000" From 80bfe5a2af99d568a51135a842c9398154d48751 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Thu, 5 Mar 2026 12:37:30 +0100 Subject: [PATCH 8/8] Remove redundant stuff --- sentry_sdk/traces.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sentry_sdk/traces.py b/sentry_sdk/traces.py index 4f0807d007..e09d7191c3 100644 --- a/sentry_sdk/traces.py +++ b/sentry_sdk/traces.py @@ -167,17 +167,6 @@ def trace_id(self) -> str: class NoOpStreamedSpan(StreamedSpan): - __slots__ = ( - ) - - def __init__( - self, - ) -> None: - pass - - def __repr__(self) -> str: - return f"<{self.__class__.__name__}(sampled={self.sampled})>" - def get_attributes(self) -> "Attributes": return {}