11import abc
2+ import logging
23import types as python_types
34import typing
45
56from opentelemetry .trace .status import Status
67from opentelemetry .util import types
78
9+ _logger = logging .getLogger (__name__ )
10+
811
912class Span (abc .ABC ):
1013 """A span represents a single operation within a trace."""
@@ -143,7 +146,9 @@ def get_default(cls) -> "TraceState":
143146DEFAULT_TRACE_STATE = TraceState .get_default ()
144147
145148
146- class SpanContext :
149+ class SpanContext (
150+ typing .Tuple [int , int , bool , "TraceFlags" , "TraceState" , bool ]
151+ ):
147152 """The state of a Span to propagate between processes.
148153
149154 This class includes the immutable attributes of a :class:`.Span` that must
@@ -157,26 +162,58 @@ class SpanContext:
157162 is_remote: True if propagated from a remote parent.
158163 """
159164
160- def __init__ (
161- self ,
165+ def __new__ (
166+ cls ,
162167 trace_id : int ,
163168 span_id : int ,
164169 is_remote : bool ,
165170 trace_flags : "TraceFlags" = DEFAULT_TRACE_OPTIONS ,
166171 trace_state : "TraceState" = DEFAULT_TRACE_STATE ,
167- ) -> None :
172+ ) -> "SpanContext" :
168173 if trace_flags is None :
169174 trace_flags = DEFAULT_TRACE_OPTIONS
170175 if trace_state is None :
171176 trace_state = DEFAULT_TRACE_STATE
172- self .trace_id = trace_id
173- self .span_id = span_id
174- self .trace_flags = trace_flags
175- self .trace_state = trace_state
176- self .is_remote = is_remote
177- self .is_valid = (
178- self .trace_id != INVALID_TRACE_ID
179- and self .span_id != INVALID_SPAN_ID
177+
178+ is_valid = trace_id != INVALID_TRACE_ID and span_id != INVALID_SPAN_ID
179+
180+ return tuple .__new__ (
181+ cls ,
182+ (trace_id , span_id , is_remote , trace_flags , trace_state , is_valid ),
183+ )
184+
185+ @property
186+ def trace_id (self ) -> int :
187+ return self [0 ] # pylint: disable=unsubscriptable-object
188+
189+ @property
190+ def span_id (self ) -> int :
191+ return self [1 ] # pylint: disable=unsubscriptable-object
192+
193+ @property
194+ def is_remote (self ) -> bool :
195+ return self [2 ] # pylint: disable=unsubscriptable-object
196+
197+ @property
198+ def trace_flags (self ) -> "TraceFlags" :
199+ return self [3 ] # pylint: disable=unsubscriptable-object
200+
201+ @property
202+ def trace_state (self ) -> "TraceState" :
203+ return self [4 ] # pylint: disable=unsubscriptable-object
204+
205+ @property
206+ def is_valid (self ) -> bool :
207+ return self [5 ] # pylint: disable=unsubscriptable-object
208+
209+ def __setattr__ (self , * args : str ) -> None :
210+ _logger .debug (
211+ "Immutable type, ignoring call to set attribute" , stack_info = True
212+ )
213+
214+ def __delattr__ (self , * args : str ) -> None :
215+ _logger .debug (
216+ "Immutable type, ignoring call to set attribute" , stack_info = True
180217 )
181218
182219 def __repr__ (self ) -> str :
0 commit comments