Skip to content

Commit c7f2675

Browse files
author
JasonXZLiu
committed
Override setattr and delattr for SpanContext + add tests
1 parent 1abdc02 commit c7f2675

File tree

2 files changed

+104
-11
lines changed

2 files changed

+104
-11
lines changed

opentelemetry-api/src/opentelemetry/trace/span.py

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ def get_default(cls) -> "TraceState":
143143
DEFAULT_TRACE_STATE = TraceState.get_default()
144144

145145

146-
class SpanContext:
146+
class SpanContext(tuple):
147147
"""The state of a Span to propagate between processes.
148148
149149
This class includes the immutable attributes of a :class:`.Span` that must
@@ -157,8 +157,8 @@ class SpanContext:
157157
is_remote: True if propagated from a remote parent.
158158
"""
159159

160-
def __init__(
161-
self,
160+
def __new__(
161+
cls,
162162
trace_id: int,
163163
span_id: int,
164164
is_remote: bool,
@@ -169,16 +169,47 @@ def __init__(
169169
trace_flags = DEFAULT_TRACE_OPTIONS
170170
if trace_state is None:
171171
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
172+
173+
is_valid = (
174+
trace_id != INVALID_TRACE_ID
175+
and span_id != INVALID_SPAN_ID
180176
)
181177

178+
return tuple.__new__(cls, (trace_id, span_id, trace_flags, trace_state, is_remote, is_valid))
179+
180+
@property
181+
def trace_id(self):
182+
return tuple.__getitem__(self, 0)
183+
184+
@property
185+
def span_id(self):
186+
return tuple.__getitem__(self, 1)
187+
188+
@property
189+
def trace_flags(self):
190+
return tuple.__getitem__(self, 2)
191+
192+
@property
193+
def trace_state(self):
194+
return tuple.__getitem__(self, 3)
195+
196+
@property
197+
def is_remote(self):
198+
return tuple.__getitem__(self, 4)
199+
200+
@property
201+
def is_valid(self):
202+
return tuple.__getitem__(self, 5)
203+
204+
def __getattr__(self, *args):
205+
raise TypeError
206+
207+
def __setattr__(self, *args):
208+
raise TypeError
209+
210+
def __delattr__(self, *args):
211+
raise TypeError
212+
182213
def __repr__(self) -> str:
183214
return (
184215
"{}(trace_id={}, span_id={}, trace_state={!r}, is_remote={})"
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Copyright The OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import unittest
16+
17+
from opentelemetry import trace
18+
19+
20+
class TestImmutableSpanContext(unittest.TestCase):
21+
def test_ctor(self):
22+
context = trace.SpanContext(
23+
1,
24+
1,
25+
is_remote=False,
26+
trace_flags=trace.DEFAULT_TRACE_OPTIONS,
27+
trace_state=trace.DEFAULT_TRACE_STATE,
28+
)
29+
30+
self.assertEqual(context.trace_id, 1)
31+
self.assertEqual(context.span_id, 1)
32+
self.assertEqual(context.is_remote, False)
33+
self.assertEqual(context.trace_flags, trace.DEFAULT_TRACE_OPTIONS)
34+
self.assertEqual(context.trace_state, trace.DEFAULT_TRACE_STATE)
35+
36+
def test_attempt_change_attributes(self):
37+
context = trace.SpanContext(
38+
1,
39+
1,
40+
is_remote=False,
41+
trace_flags=trace.DEFAULT_TRACE_OPTIONS,
42+
trace_state=trace.DEFAULT_TRACE_STATE,
43+
)
44+
45+
with self.assertRaises(TypeError):
46+
context.trace_id = 2
47+
with self.assertRaises(TypeError):
48+
context.span_id = 2
49+
with self.assertRaises(TypeError):
50+
context.is_remote = True
51+
with self.assertRaises(TypeError):
52+
context.trace_flags = 2
53+
with self.assertRaises(TypeError):
54+
context.trace_state = 2
55+
56+
self.assertEqual(context.trace_id, 1)
57+
self.assertEqual(context.span_id, 1)
58+
self.assertEqual(context.is_remote, False)
59+
self.assertEqual(context.trace_flags, trace.DEFAULT_TRACE_OPTIONS)
60+
self.assertEqual(context.trace_state, trace.DEFAULT_TRACE_STATE)
61+
62+
self.assertEqual(context.trace_id, 1)

0 commit comments

Comments
 (0)