From 6981035aecc960310ca131d551597649f233dc2b Mon Sep 17 00:00:00 2001 From: Roberto Villarreal Date: Mon, 12 Aug 2024 10:14:43 -0600 Subject: [PATCH] Ensure async generators are awaited (#2792) --- CHANGELOG.md | 2 ++ .../opentelemetry/instrumentation/asyncio/__init__.py | 2 +- .../tests/test_asyncio_anext.py | 10 +++++++--- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 49b66f69df..d4d996caeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ([#2589](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2589)) - `opentelemetry-instrumentation-celery` propagates baggage ([#2385](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2385)) +- `opentelemetry-instrumentation-asyncio` Fixes async generator coroutines not being awaited + ([#2792](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/2792)) ## Version 1.26.0/0.47b0 (2024-07-23) diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py index f5f0d34c4f..ae10560861 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/src/opentelemetry/instrumentation/asyncio/__init__.py @@ -262,7 +262,7 @@ def trace_item(self, coro_or_future): async def trace_coroutine(self, coro): if not hasattr(coro, "__name__"): - return coro + return await coro start = default_timer() attr = { "type": "coroutine", diff --git a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py index e51f059ca0..5241b3f2cc 100644 --- a/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py +++ b/instrumentation/opentelemetry-instrumentation-asyncio/tests/test_asyncio_anext.py @@ -43,19 +43,23 @@ def tearDown(self): # Asyncio anext() does not have __name__ attribute, which is used to determine if the coroutine should be traced. # This test is to ensure that the instrumentation does not break when the coroutine does not have __name__ attribute. + # Additionally, ensure the coroutine is actually awaited. @skipIf( sys.version_info < (3, 10), "anext is only available in Python 3.10+" ) def test_asyncio_anext(self): async def main(): async def async_gen(): - for it in range(2): + # nothing special about this range other than to avoid returning a zero + # from a function named 'main' (which might cause confusion about intent) + for it in range(2, 4): yield it async_gen_instance = async_gen() agen = anext(async_gen_instance) - await asyncio.create_task(agen) + return await asyncio.create_task(agen) - asyncio.run(main()) + ret = asyncio.run(main()) + self.assertEqual(ret, 2) # first iteration from range() spans = self.memory_exporter.get_finished_spans() self.assertEqual(len(spans), 0)