From 1dadd33d27fa83586d41f6be7380886a4772d396 Mon Sep 17 00:00:00 2001 From: hyoinandout Date: Thu, 29 Aug 2024 15:49:39 +0900 Subject: [PATCH 1/5] Handle TypeError from opentelemetry.context.contextvars_context in detach --- opentelemetry-api/src/opentelemetry/context/__init__.py | 2 ++ .../src/opentelemetry/context/contextvars_context.py | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/context/__init__.py b/opentelemetry-api/src/opentelemetry/context/__init__.py index a932c644a0e..cc07155bd35 100644 --- a/opentelemetry-api/src/opentelemetry/context/__init__.py +++ b/opentelemetry-api/src/opentelemetry/context/__init__.py @@ -152,6 +152,8 @@ def detach(token: object) -> None: """ try: _RUNTIME_CONTEXT.detach(token) + except TypeError: + logger.exception("Expected an instance of Token, got None") except Exception: # pylint: disable=broad-exception-caught logger.exception("Failed to detach context") diff --git a/opentelemetry-api/src/opentelemetry/context/contextvars_context.py b/opentelemetry-api/src/opentelemetry/context/contextvars_context.py index 5f606764fcc..9136f09df0c 100644 --- a/opentelemetry-api/src/opentelemetry/context/contextvars_context.py +++ b/opentelemetry-api/src/opentelemetry/context/contextvars_context.py @@ -47,7 +47,10 @@ def detach(self, token: object) -> None: Args: token: A reference to a previous Context. """ - self._current_context.reset(token) # type: ignore + try: + self._current_context.reset(token) + except TypeError: + raise TypeError __all__ = ["ContextVarsRuntimeContext"] From 8c6b4c6ca0daf0299437be9006f6a1e212d466a5 Mon Sep 17 00:00:00 2001 From: hyoinandout Date: Wed, 4 Sep 2024 15:07:52 +0900 Subject: [PATCH 2/5] Add type annotations --- CHANGELOG.md | 4 ++++ .../src/opentelemetry/context/__init__.py | 7 +++---- .../src/opentelemetry/context/context.py | 5 +++-- .../src/opentelemetry/context/contextvars_context.py | 11 ++++------- opentelemetry-api/tests/context/base_context.py | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de7013d0cbf..40c1407124d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Add type annotations to context's attach & detach + ([#4164](https://github.com/open-telemetry/opentelemetry-python/pull/4164)) + + ## Version 1.27.0/0.48b0 (2024-08-28) - Implementation of Events API diff --git a/opentelemetry-api/src/opentelemetry/context/__init__.py b/opentelemetry-api/src/opentelemetry/context/__init__.py index cc07155bd35..88a9b9f4ac0 100644 --- a/opentelemetry-api/src/opentelemetry/context/__init__.py +++ b/opentelemetry-api/src/opentelemetry/context/__init__.py @@ -14,6 +14,7 @@ import logging import typing +from contextvars import Token from os import environ from uuid import uuid4 @@ -130,7 +131,7 @@ def get_current() -> Context: return _RUNTIME_CONTEXT.get_current() -def attach(context: Context) -> object: +def attach(context: Context) -> Token[Context]: """Associates a Context with the caller's current execution unit. Returns a token that can be used to restore the previous Context. @@ -143,7 +144,7 @@ def attach(context: Context) -> object: return _RUNTIME_CONTEXT.attach(context) -def detach(token: object) -> None: +def detach(token: Token[Context]) -> None: """Resets the Context associated with the caller's current execution unit to the value it had before attaching a specified Context. @@ -152,8 +153,6 @@ def detach(token: object) -> None: """ try: _RUNTIME_CONTEXT.detach(token) - except TypeError: - logger.exception("Expected an instance of Token, got None") except Exception: # pylint: disable=broad-exception-caught logger.exception("Failed to detach context") diff --git a/opentelemetry-api/src/opentelemetry/context/context.py b/opentelemetry-api/src/opentelemetry/context/context.py index 518f09f2b8f..1214b62e166 100644 --- a/opentelemetry-api/src/opentelemetry/context/context.py +++ b/opentelemetry-api/src/opentelemetry/context/context.py @@ -14,6 +14,7 @@ import typing from abc import ABC, abstractmethod +from contextvars import Token class Context(typing.Dict[str, object]): @@ -29,7 +30,7 @@ class _RuntimeContext(ABC): """ @abstractmethod - def attach(self, context: Context) -> object: + def attach(self, context: Context) -> Token[Context]: """Sets the current `Context` object. Returns a token that can be used to reset to the previous `Context`. @@ -42,7 +43,7 @@ def get_current(self) -> Context: """Returns the current `Context` object.""" @abstractmethod - def detach(self, token: object) -> None: + def detach(self, token: Token[Context]) -> None: """Resets Context to a previous value Args: diff --git a/opentelemetry-api/src/opentelemetry/context/contextvars_context.py b/opentelemetry-api/src/opentelemetry/context/contextvars_context.py index 9136f09df0c..9479839fe57 100644 --- a/opentelemetry-api/src/opentelemetry/context/contextvars_context.py +++ b/opentelemetry-api/src/opentelemetry/context/contextvars_context.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from contextvars import ContextVar +from contextvars import ContextVar, Token from opentelemetry.context.context import Context, _RuntimeContext @@ -28,7 +28,7 @@ def __init__(self) -> None: self._CONTEXT_KEY, default=Context() ) - def attach(self, context: Context) -> object: + def attach(self, context: Context) -> Token[Context]: """Sets the current `Context` object. Returns a token that can be used to reset to the previous `Context`. @@ -41,16 +41,13 @@ def get_current(self) -> Context: """Returns the current `Context` object.""" return self._current_context.get() - def detach(self, token: object) -> None: + def detach(self, token: Token[Context]) -> None: """Resets Context to a previous value Args: token: A reference to a previous Context. """ - try: - self._current_context.reset(token) - except TypeError: - raise TypeError + self._current_context.reset(token) __all__ = ["ContextVarsRuntimeContext"] diff --git a/opentelemetry-api/tests/context/base_context.py b/opentelemetry-api/tests/context/base_context.py index 05acc95d89a..5c628225fce 100644 --- a/opentelemetry-api/tests/context/base_context.py +++ b/opentelemetry-api/tests/context/base_context.py @@ -64,7 +64,7 @@ def test_attach(self): self.assertEqual("yyy", context.get_value("a")) with self.assertLogs(level=ERROR): - context.detach("some garbage") + context.detach("some garbage") # type:ignore def test_detach_out_of_order(self): t1 = context.attach(context.set_value("c", 1)) From 311e7ad110651144eb074ae8b17140537b557f51 Mon Sep 17 00:00:00 2001 From: Dustin Kaiser Date: Wed, 11 Dec 2024 15:23:54 +0100 Subject: [PATCH 3/5] In changelog update PR number --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f878960b6ec..6a4c2f00d0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased - Add type annotations to context's attach & detach - ([#4164](https://github.com/open-telemetry/opentelemetry-python/pull/4164)) + ([#4164](https://github.com/open-telemetry/opentelemetry-python/pull/4346)) - Fix crash exporting a log record with None body ([#4276](https://github.com/open-telemetry/opentelemetry-python/pull/4276)) - Fix metrics export with exemplar and no context and filtering observable instruments From bbe97699285e56f5f52649b4a7523433b2a556c2 Mon Sep 17 00:00:00 2001 From: Dustin Kaiser <8209087+mrnicegyu11@users.noreply.github.com> Date: Thu, 2 Jan 2025 08:05:29 +0000 Subject: [PATCH 4/5] remove unnecessary type:ignore --- opentelemetry-api/tests/context/base_context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-api/tests/context/base_context.py b/opentelemetry-api/tests/context/base_context.py index 5c628225fce..05acc95d89a 100644 --- a/opentelemetry-api/tests/context/base_context.py +++ b/opentelemetry-api/tests/context/base_context.py @@ -64,7 +64,7 @@ def test_attach(self): self.assertEqual("yyy", context.get_value("a")) with self.assertLogs(level=ERROR): - context.detach("some garbage") # type:ignore + context.detach("some garbage") def test_detach_out_of_order(self): t1 = context.attach(context.set_value("c", 1)) From 6347121b05391ee213a2c9e092cb963ff6dffa88 Mon Sep 17 00:00:00 2001 From: Dustin Kaiser <8209087+mrnicegyu11@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:06:01 +0100 Subject: [PATCH 5/5] fix tox -e mypy tests --- mypy.ini | 4 +++- opentelemetry-api/tests/context/base_context.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mypy.ini b/mypy.ini index dca41f8c6be..4c368fcd944 100644 --- a/mypy.ini +++ b/mypy.ini @@ -17,4 +17,6 @@ strict_equality = True strict_optional = True no_implicit_optional = True - no_implicit_reexport = True \ No newline at end of file + no_implicit_reexport = True + # https://mypy.readthedocs.io/en/stable/running_mypy.html#follow-imports + follow_imports = silent diff --git a/opentelemetry-api/tests/context/base_context.py b/opentelemetry-api/tests/context/base_context.py index 05acc95d89a..395229b5208 100644 --- a/opentelemetry-api/tests/context/base_context.py +++ b/opentelemetry-api/tests/context/base_context.py @@ -64,7 +64,7 @@ def test_attach(self): self.assertEqual("yyy", context.get_value("a")) with self.assertLogs(level=ERROR): - context.detach("some garbage") + context.detach(token) def test_detach_out_of_order(self): t1 = context.attach(context.set_value("c", 1))