Describe your environment
OS: macOS
Python version: Python 3.9 - 3.13 (reproducible across all)
API: 1.43.0
SDK: 1.43.0
What happened?
The Context object in the OpenTelemetry Python API is mutable despite the MUST be immutable requirement in the specification.
Because Context subclasses dict but only overrides __setitem__, inherited dict mutation methods (update, pop, clear, etc.) bypass the override at the CPython level and silently mutate the Context object in place.
Steps to Reproduce
from opentelemetry.context.context import Context
# update
ctx = Context({"a": 1})
ctx.update({"b": 2})
assert ctx == {"a": 1, "b": 2}
# setdefault
ctx = Context({"a": 1})
ctx.setdefault("c", 3)
assert ctx == {"a": 1, "c": 3}
# pop
ctx = Context({"a": 1})
ctx.pop("a")
assert ctx == {}
# clear
ctx = Context({"a": 1})
ctx.clear()
assert ctx == {}
# |=
ctx = Context({"a": 1})
ctx |= {"d": 4}
assert ctx == {"a": 1, "d": 4}
print("Context mutated successfully.")
Expected Result
The OpenTelemetry Context specification states:
“A Context MUST be immutable, and its write operations MUST result in the creation of a new Context.”
The Python SDK already enforces this for direct item assignment by overriding __setitem__ to raise ValueError, and the existing test tests/context/test_context.py::test_context_is_immutable verifies that behavior.
Accordingly, Context should not expose mutation APIs that allow in-place modification.
Actual Result
Several inherited mutating methods remain available, including update, setdefault, pop, popitem, clear, and __ior__ (|=).
These methods mutate the existing Context instance in place without raising an exception.
Because these operations are implemented by CPython’s built-in dict type, they bypass the Python-level __setitem__ / __delitem__ overrides and directly modify the underlying dictionary.
The reproducer code above successfully mutates the existing Context instance in place, demonstrating that Context does not satisfy the immutability guarantee described by the specification.
Additional context
The current implementation enforces immutability only for direct item assignment.
Code that relies on the documented immutability guarantee can still accidentally mutate shared Context objects through inherited dict methods, potentially leading to subtle and difficult-to-diagnose behavior.
Because the issue stems from inheriting dict, it also applies to any current or future mutating APIs exposed by the base class unless they are explicitly handled.
Would you like to implement a fix?
Yes
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding +1 or me too, to help us triage it. Learn more here.
Describe your environment
OS: macOS
Python version: Python 3.9 - 3.13 (reproducible across all)
API: 1.43.0
SDK: 1.43.0
What happened?
The
Contextobject in the OpenTelemetry Python API is mutable despite theMUST be immutablerequirement in the specification.Because
Contextsubclassesdictbut only overrides__setitem__, inheriteddictmutation methods (update,pop,clear, etc.) bypass the override at the CPython level and silently mutate theContextobject in place.Steps to Reproduce
Expected Result
The OpenTelemetry Context specification states:
The Python SDK already enforces this for direct item assignment by overriding
__setitem__to raiseValueError, and the existing testtests/context/test_context.py::test_context_is_immutableverifies that behavior.Accordingly,
Contextshould not expose mutation APIs that allow in-place modification.Actual Result
Several inherited mutating methods remain available, including
update,setdefault,pop,popitem,clear, and__ior__(|=).These methods mutate the existing
Contextinstance in place without raising an exception.Because these operations are implemented by CPython’s built-in
dicttype, they bypass the Python-level__setitem__/__delitem__overrides and directly modify the underlying dictionary.The reproducer code above successfully mutates the existing
Contextinstance in place, demonstrating thatContextdoes not satisfy the immutability guarantee described by the specification.Additional context
The current implementation enforces immutability only for direct item assignment.
Code that relies on the documented immutability guarantee can still accidentally mutate shared
Contextobjects through inheriteddictmethods, potentially leading to subtle and difficult-to-diagnose behavior.Because the issue stems from inheriting
dict, it also applies to any current or future mutating APIs exposed by the base class unless they are explicitly handled.Would you like to implement a fix?
Yes
Tip
React with 👍 to help prioritize this issue. Please use comments to provide useful context, avoiding
+1orme too, to help us triage it. Learn more here.