Skip to content

Commit 8a946b5

Browse files
author
Andrew Xue
authored
bugfix: deep copy empty attributes (#714)
Addresses #713. Previously it was possible for a user (acting against the api) to mutate a default variable.
1 parent 64b3cf2 commit 8a946b5

File tree

2 files changed

+20
-18
lines changed

2 files changed

+20
-18
lines changed

opentelemetry-sdk/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
([#724](https://github.com/open-telemetry/opentelemetry-python/pull/724))
1111
- bugfix: Fix error message
1212
([#729](https://github.com/open-telemetry/opentelemetry-python/pull/729))
13+
- deep copy empty attributes
14+
([#714](https://github.com/open-telemetry/opentelemetry-python/pull/714))
1315

1416
## 0.7b1
1517

opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,6 @@ class Span(trace_api.Span):
252252
this `Span`.
253253
"""
254254

255-
# Initialize these lazily assuming most spans won't have them.
256-
_empty_attributes = BoundedDict(MAX_NUM_ATTRIBUTES)
257-
_empty_events = BoundedList(MAX_NUM_EVENTS)
258-
_empty_links = BoundedList(MAX_NUM_LINKS)
259-
260255
def __init__(
261256
self,
262257
name: str,
@@ -289,22 +284,20 @@ def __init__(
289284

290285
self._filter_attribute_values(attributes)
291286
if not attributes:
292-
self.attributes = Span._empty_attributes
287+
self.attributes = self._new_attributes()
293288
else:
294289
self.attributes = BoundedDict.from_map(
295290
MAX_NUM_ATTRIBUTES, attributes
296291
)
297292

298-
if events is None:
299-
self.events = Span._empty_events
300-
else:
301-
self.events = BoundedList(MAX_NUM_EVENTS)
293+
self.events = self._new_events()
294+
if events:
302295
for event in events:
303296
self._filter_attribute_values(event.attributes)
304297
self.events.append(event)
305298

306299
if links is None:
307-
self.links = Span._empty_links
300+
self.links = self._new_links()
308301
else:
309302
self.links = BoundedList.from_seq(MAX_NUM_LINKS, links)
310303

@@ -325,6 +318,18 @@ def __repr__(self):
325318
type(self).__name__, self.name, self.context
326319
)
327320

321+
@staticmethod
322+
def _new_attributes():
323+
return BoundedDict(MAX_NUM_ATTRIBUTES)
324+
325+
@staticmethod
326+
def _new_events():
327+
return BoundedList(MAX_NUM_EVENTS)
328+
329+
@staticmethod
330+
def _new_links():
331+
return BoundedList(MAX_NUM_LINKS)
332+
328333
@staticmethod
329334
def _format_context(context):
330335
x_ctx = OrderedDict()
@@ -407,9 +412,6 @@ def set_attribute(self, key: str, value: types.AttributeValue) -> None:
407412
if not self.is_recording_events():
408413
return
409414
has_ended = self.end_time is not None
410-
if not has_ended:
411-
if self.attributes is Span._empty_attributes:
412-
self.attributes = BoundedDict(MAX_NUM_ATTRIBUTES)
413415
if has_ended:
414416
logger.warning("Setting attribute on ended span.")
415417
return
@@ -442,9 +444,7 @@ def _add_event(self, event: EventBase) -> None:
442444
if not self.is_recording_events():
443445
return
444446
has_ended = self.end_time is not None
445-
if not has_ended:
446-
if self.events is Span._empty_events:
447-
self.events = BoundedList(MAX_NUM_EVENTS)
447+
448448
if has_ended:
449449
logger.warning("Calling add_event() on an ended span.")
450450
return
@@ -458,7 +458,7 @@ def add_event(
458458
) -> None:
459459
self._filter_attribute_values(attributes)
460460
if not attributes:
461-
attributes = Span._empty_attributes
461+
attributes = self._new_attributes()
462462
self._add_event(
463463
Event(
464464
name=name,

0 commit comments

Comments
 (0)