From 0cf16478f47232d7c09c60d4415082e826cab59a Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Thu, 27 Feb 2020 15:53:47 -0800 Subject: [PATCH 1/2] Freeze sequence-valued span attributes --- opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 5 ++++- opentelemetry-sdk/tests/trace/test_trace.py | 6 +++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index dd0169ea9f7..17c55c2ef6d 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -20,7 +20,7 @@ from contextlib import contextmanager from numbers import Number from types import TracebackType -from typing import Iterator, Optional, Sequence, Tuple, Type +from typing import Iterator, MutableSequence, Optional, Sequence, Tuple, Type from opentelemetry import context as context_api from opentelemetry import trace as trace_api @@ -237,6 +237,9 @@ def set_attribute(self, key: str, value: types.AttributeValue) -> None: if error_message is not None: logger.warning("%s in attribute value sequence", error_message) return + # Freeze mutable sequences defensively + if isinstance(value, MutableSequence): + value = tuple(value) elif not isinstance(value, (bool, str, Number, Sequence)): logger.warning("invalid type for attribute value") return diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 982df896678..984fed230f3 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -406,12 +406,12 @@ def test_attributes(self): self.assertEqual(root.attributes["http.status_text"], "OK") self.assertEqual(root.attributes["misc.pi"], 3.14) self.assertEqual(root.attributes["attr-key"], "attr-value2") - self.assertEqual(root.attributes["empty-list"], []) + self.assertEqual(root.attributes["empty-list"], ()) self.assertEqual( - root.attributes["list-of-bools"], [True, True, False] + root.attributes["list-of-bools"], (True, True, False) ) self.assertEqual( - root.attributes["list-of-numerics"], [123, 3.14, 0] + root.attributes["list-of-numerics"], (123, 3.14, 0) ) attributes = { From 290f2743cc6db896b6879472fbd3d02915918503 Mon Sep 17 00:00:00 2001 From: Chris Kleinknecht Date: Fri, 28 Feb 2020 12:21:34 -0800 Subject: [PATCH 2/2] Address comments --- opentelemetry-sdk/tests/trace/test_trace.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/opentelemetry-sdk/tests/trace/test_trace.py b/opentelemetry-sdk/tests/trace/test_trace.py index 984fed230f3..71dbd6732c9 100644 --- a/opentelemetry-sdk/tests/trace/test_trace.py +++ b/opentelemetry-sdk/tests/trace/test_trace.py @@ -392,8 +392,10 @@ def test_attributes(self): root.set_attribute("attr-key", "attr-value2") root.set_attribute("empty-list", []) - root.set_attribute("list-of-bools", [True, True, False]) - root.set_attribute("list-of-numerics", [123, 3.14, 0]) + list_of_bools = [True, True, False] + root.set_attribute("list-of-bools", list_of_bools) + list_of_numerics = [123, 3.14, 0] + root.set_attribute("list-of-numerics", list_of_numerics) self.assertEqual(len(root.attributes), 10) self.assertEqual(root.attributes["component"], "http") @@ -410,6 +412,14 @@ def test_attributes(self): self.assertEqual( root.attributes["list-of-bools"], (True, True, False) ) + list_of_bools.append(False) + self.assertEqual( + root.attributes["list-of-bools"], (True, True, False) + ) + self.assertEqual( + root.attributes["list-of-numerics"], (123, 3.14, 0) + ) + list_of_numerics.append(22 / 7) self.assertEqual( root.attributes["list-of-numerics"], (123, 3.14, 0) )