Skip to content

Commit 46096df

Browse files
committed
fix(tracing): preserve generator return values in @tracer.wrap() decorator [backport 3.9]
1 parent e0e451c commit 46096df

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

ddtrace/_trace/tracer.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,8 @@ def func_wrapper(*args, **kwargs):
775775
)
776776

777777
with self.trace(span_name, service=service, resource=resource, span_type=span_type):
778-
yield from f(*args, **kwargs)
778+
return_value = yield from f(*args, **kwargs)
779+
return return_value
779780

780781
return func_wrapper
781782

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
fixes:
3+
- |
4+
tracing: This fix resolves an issue where the ``@tracer.wrap()`` decorator failed to preserve return values from generator functions, causing ``StopIteration.value`` to be ``None`` instead of the actual returned value.

tests/tracer/test_tracer.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,28 @@ def wrapper():
355355
"visible to the caller"
356356
)
357357

358+
def test_tracer_wrap_generator_with_return_value(self):
359+
@self.tracer.wrap()
360+
def iter_signals():
361+
for i in range(10):
362+
yield i
363+
return 10
364+
365+
with self.trace("root") as span:
366+
signals = iter_signals()
367+
while True:
368+
try:
369+
# DEV: We don't need the return value
370+
next(signals)
371+
except StopIteration as e:
372+
assert e.value == 10
373+
span.set_metric("num_signals", e.value)
374+
break
375+
376+
self.assert_span_count(2)
377+
root_span = self.get_root_span()
378+
root_span.assert_matches(name="root", metrics={"num_signals": 10})
379+
358380
def test_tracer_disabled(self):
359381
self.tracer.enabled = True
360382
with self.trace("foo") as s:

0 commit comments

Comments
 (0)