Skip to content

Commit

Permalink
make immutable attributes consistent (#1909)
Browse files Browse the repository at this point in the history
  • Loading branch information
alrex authored Jun 14, 2021
1 parent bab5011 commit 32b83a0
Show file tree
Hide file tree
Showing 6 changed files with 27 additions and 11 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Ignore calls to `Span.set_status` with `StatusCode.UNSET` and also if previous status already
had `StatusCode.OK`.
([#1902](https://github.com/open-telemetry/opentelemetry-python/pull/1902))
- Attributes for `Link` and `Resource` are immutable as they are for `Event`, which means
any attempt to modify attributes directly will result in a `TypeError` exception.
([#1909](https://github.com/open-telemetry/opentelemetry-python/pull/1909))

## [1.3.0-0.22b0](https://github.com/open-telemetry/opentelemetry-python/releases/tag/v1.3.0-0.22b0) - 2021-06-01

Expand Down
9 changes: 7 additions & 2 deletions opentelemetry-api/src/opentelemetry/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@
from typing import Iterator, Optional, Sequence, cast

from opentelemetry import context as context_api
from opentelemetry.attributes import ( # type: ignore
_create_immutable_attributes,
)
from opentelemetry.context.context import Context
from opentelemetry.environment_variables import OTEL_PYTHON_TRACER_PROVIDER
from opentelemetry.trace.propagation import (
Expand Down Expand Up @@ -126,7 +129,7 @@ def attributes(self) -> types.Attributes:


class Link(_LinkBase):
"""A link to a `Span`.
"""A link to a `Span`. The attributes of a Link are immutable.
Args:
context: `SpanContext` of the `Span` to link to.
Expand All @@ -139,7 +142,9 @@ def __init__(
attributes: types.Attributes = None,
) -> None:
super().__init__(context)
self._attributes = attributes
self._attributes = _create_immutable_attributes(
attributes
) # type: types.Attributes

@property
def attributes(self) -> types.Attributes:
Expand Down
13 changes: 8 additions & 5 deletions opentelemetry-sdk/src/opentelemetry/sdk/resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@

import pkg_resources

from opentelemetry.attributes import _filter_attributes
from opentelemetry.attributes import (
_create_immutable_attributes,
_filter_attributes,
)
from opentelemetry.sdk.environment_variables import (
OTEL_RESOURCE_ATTRIBUTES,
OTEL_SERVICE_NAME,
Expand Down Expand Up @@ -145,7 +148,7 @@ def __init__(
self, attributes: Attributes, schema_url: typing.Optional[str] = None
):
_filter_attributes(attributes)
self._attributes = attributes.copy()
self._attributes = _create_immutable_attributes(attributes)
if schema_url is None:
schema_url = ""
self._schema_url = schema_url
Expand Down Expand Up @@ -187,7 +190,7 @@ def get_empty() -> "Resource":

@property
def attributes(self) -> Attributes:
return self._attributes.copy()
return self._attributes

@property
def schema_url(self) -> str:
Expand All @@ -210,7 +213,7 @@ def merge(self, other: "Resource") -> "Resource":
Returns:
The newly-created Resource.
"""
merged_attributes = self.attributes
merged_attributes = self.attributes.copy()
merged_attributes.update(other.attributes)

if self.schema_url == "":
Expand Down Expand Up @@ -239,7 +242,7 @@ def __eq__(self, other: object) -> bool:

def __hash__(self):
return hash(
f"{dumps(self._attributes, sort_keys=True)}|{self._schema_url}"
f"{dumps(self._attributes.copy(), sort_keys=True)}|{self._schema_url}"
)


Expand Down
5 changes: 3 additions & 2 deletions opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,8 @@ def attributes(self) -> types.Attributes:


class Event(EventBase):
"""A text annotation with a set of attributes.
"""A text annotation with a set of attributes. The attributes of an event
are immutable.
Args:
name: Name of the event.
Expand Down Expand Up @@ -456,7 +457,7 @@ def to_json(self, indent=4):
f_span["attributes"] = self._format_attributes(self._attributes)
f_span["events"] = self._format_events(self._events)
f_span["links"] = self._format_links(self._links)
f_span["resource"] = self._resource.attributes
f_span["resource"] = self._format_attributes(self._resource.attributes)

return json.dumps(f_span, indent=indent)

Expand Down
3 changes: 2 additions & 1 deletion opentelemetry-sdk/tests/resources/test_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ def test_immutability(self):
resource = resources.Resource.create(attributes)
self.assertEqual(resource.attributes, attributes_copy)

resource.attributes["has_bugs"] = False
with self.assertRaises(TypeError):
resource.attributes["has_bugs"] = False
self.assertEqual(resource.attributes, attributes_copy)

attributes["cost"] = 999.91
Expand Down
5 changes: 4 additions & 1 deletion opentelemetry-sdk/tests/trace/test_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -805,7 +805,7 @@ def test_links(self):
self.assertEqual(
root.links[0].context.span_id, other_context1.span_id
)
self.assertEqual(root.links[0].attributes, None)
self.assertEqual(0, len(root.links[0].attributes))
self.assertEqual(
root.links[1].context.trace_id, other_context2.trace_id
)
Expand All @@ -814,6 +814,9 @@ def test_links(self):
)
self.assertEqual(root.links[1].attributes, {"name": "neighbor"})

with self.assertRaises(TypeError):
root.links[1].attributes["name"] = "new_neighbour"

def test_update_name(self):
with self.tracer.start_as_current_span("root") as root:
# name
Expand Down

0 comments on commit 32b83a0

Please sign in to comment.