Skip to content

Commit

Permalink
Make event attributes immutable (#1195)
Browse files Browse the repository at this point in the history
  • Loading branch information
Eoin Noble authored Oct 9, 2020
1 parent c7cc4d9 commit 5760c0e
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
2 changes: 2 additions & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
([#1105](https://github.com/open-telemetry/opentelemetry-python/pull/1120))
- Allow for Custom Trace and Span IDs Generation - `IdsGenerator` for TracerProvider
([#1153](https://github.com/open-telemetry/opentelemetry-python/pull/1153))
- Event attributes are now immutable
([#1195](https://github.com/open-telemetry/opentelemetry-python/pull/1195))
- Renaming metrics Batcher to Processor
([#1203](https://github.com/open-telemetry/opentelemetry-python/pull/1203))
- Protect access to Span implementation
Expand Down
14 changes: 10 additions & 4 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@
import concurrent.futures
import json
import logging
import random
import threading
import traceback
from collections import OrderedDict
from contextlib import contextmanager
from types import TracebackType
from types import MappingProxyType, TracebackType
from typing import (
Any,
Callable,
Expand Down Expand Up @@ -340,6 +339,10 @@ def _filter_attribute_values(attributes: types.Attributes):
attributes.pop(attr_key)


def _create_immutable_attributes(attributes):
return MappingProxyType(attributes.copy() if attributes else {})


class Span(trace_api.Span):
"""See `opentelemetry.trace.Span`.
Expand Down Expand Up @@ -408,6 +411,10 @@ def __init__(
if events:
for event in events:
_filter_attribute_values(event.attributes)
# pylint: disable=protected-access
event._attributes = _create_immutable_attributes(
event.attributes
)
self.events.append(event)

if links is None:
Expand Down Expand Up @@ -566,8 +573,7 @@ def add_event(
timestamp: Optional[int] = None,
) -> None:
_filter_attribute_values(attributes)
if not attributes:
attributes = self._new_attributes()
attributes = _create_immutable_attributes(attributes)
self._add_event(
Event(
name=name,
Expand Down
25 changes: 24 additions & 1 deletion opentelemetry-sdk/tests/trace/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,6 @@ def test_events(self):
root.add_event("event0")

# event name and attributes
now = time_ns()
root.add_event(
"event1", {"name": "pluto", "some_bools": [True, False]}
)
Expand Down Expand Up @@ -628,6 +627,30 @@ def test_events(self):
root.events[3].attributes, {"name": ("original_contents",)}
)

def test_events_are_immutable(self):
event_properties = [
prop for prop in dir(trace.EventBase) if not prop.startswith("_")
]

with self.tracer.start_as_current_span("root") as root:
root.add_event("event0", {"name": ["birthday"]})
event = root.events[0]

for prop in event_properties:
with self.assertRaises(AttributeError):
setattr(event, prop, "something")

def test_event_attributes_are_immutable(self):
with self.tracer.start_as_current_span("root") as root:
root.add_event("event0", {"name": ["birthday"]})
event = root.events[0]

with self.assertRaises(TypeError):
event.attributes["name"][0] = "happy"

with self.assertRaises(TypeError):
event.attributes["name"] = "hello"

def test_invalid_event_attributes(self):
self.assertEqual(trace_api.get_current_span(), trace_api.INVALID_SPAN)

Expand Down

0 comments on commit 5760c0e

Please sign in to comment.