Skip to content

Commit 3f1f4bf

Browse files
committed
chore: warn if span()'s caller function is a generator
1 parent 8e90d67 commit 3f1f4bf

File tree

1 file changed

+19
-0
lines changed

1 file changed

+19
-0
lines changed

logfire/_internal/main.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ def _span(
181181
_span_name: str | None = None,
182182
_level: LevelName | int | None = None,
183183
_links: Sequence[tuple[SpanContext, otel_types.Attributes]] = (),
184+
_warn_if_inside_generator: bool = True,
184185
) -> LogfireSpan:
185186
try:
186187
if _level is not None:
@@ -191,6 +192,20 @@ def _span(
191192
else:
192193
level_attributes = None
193194

195+
# we go two levels back to find the caller frame, as this method is called by logfire.span() method
196+
caller_frame = inspect.currentframe().f_back.f_back # type: ignore
197+
# check if the caller is a generator function by checking the co_flags attribute of the code object
198+
# and doing bit-wise AND checking for CO_GENERATOR or CO_ASYNC_GENERATOR value match
199+
caller_is_generator = bool(
200+
caller_frame and caller_frame.f_code.co_flags & (inspect.CO_GENERATOR | inspect.CO_ASYNC_GENERATOR)
201+
)
202+
203+
if caller_is_generator and _warn_if_inside_generator:
204+
warnings.warn(
205+
'Span is inside a generator function. See https://logfire.pydantic.dev/docs/reference/advanced/generators/#move-the-span-outside-the-generator.',
206+
RuntimeWarning,
207+
)
208+
194209
stack_info = get_user_stack_info()
195210
merged_attributes = {**stack_info, **attributes}
196211

@@ -533,6 +548,7 @@ def span(
533548
_span_name: str | None = None,
534549
_level: LevelName | None = None,
535550
_links: Sequence[tuple[SpanContext, otel_types.Attributes]] = (),
551+
_warn_if_inside_generator: bool = True,
536552
**attributes: Any,
537553
) -> LogfireSpan:
538554
"""Context manager for creating a span.
@@ -552,18 +568,21 @@ def span(
552568
_tags: An optional sequence of tags to include in the span.
553569
_level: An optional log level name.
554570
_links: An optional sequence of links to other spans. Each link is a tuple of a span context and attributes.
571+
_warn_if_inside_generator: Set to `False` to prevent a warning when instrumenting a generator function.
555572
attributes: The arguments to include in the span and format the message template with.
556573
Attributes starting with an underscore are not allowed.
557574
"""
558575
if any(k.startswith('_') for k in attributes):
559576
raise ValueError('Attribute keys cannot start with an underscore.')
577+
560578
return self._span(
561579
msg_template,
562580
attributes,
563581
_tags=_tags,
564582
_span_name=_span_name,
565583
_level=_level,
566584
_links=_links,
585+
_warn_if_inside_generator=_warn_if_inside_generator,
567586
)
568587

569588
@overload

0 commit comments

Comments
 (0)