@@ -186,6 +186,7 @@ def _span(
186
186
_span_name : str | None = None ,
187
187
_level : LevelName | int | None = None ,
188
188
_links : Sequence [tuple [SpanContext , otel_types .Attributes ]] = (),
189
+ _warn_if_inside_generator : bool = True ,
189
190
) -> LogfireSpan :
190
191
try :
191
192
if _level is not None :
@@ -196,6 +197,20 @@ def _span(
196
197
else :
197
198
level_attributes = None
198
199
200
+ # we go two levels back to find the caller frame, as this method is called by logfire.span() method
201
+ caller_frame = inspect .currentframe ().f_back .f_back # type: ignore
202
+ # check if the caller is a generator function by checking the co_flags attribute of the code object
203
+ # and doing bit-wise AND checking for CO_GENERATOR or CO_ASYNC_GENERATOR value match
204
+ caller_is_generator = bool (
205
+ caller_frame and caller_frame .f_code .co_flags & (inspect .CO_GENERATOR | inspect .CO_ASYNC_GENERATOR )
206
+ )
207
+
208
+ if caller_is_generator and _warn_if_inside_generator :
209
+ warnings .warn (
210
+ 'Span is inside a generator function. See https://logfire.pydantic.dev/docs/reference/advanced/generators/#move-the-span-outside-the-generator.' ,
211
+ RuntimeWarning ,
212
+ )
213
+
199
214
stack_info = get_user_stack_info ()
200
215
merged_attributes = {** stack_info , ** attributes }
201
216
@@ -538,6 +553,7 @@ def span(
538
553
_span_name : str | None = None ,
539
554
_level : LevelName | None = None ,
540
555
_links : Sequence [tuple [SpanContext , otel_types .Attributes ]] = (),
556
+ _warn_if_inside_generator : bool = True ,
541
557
** attributes : Any ,
542
558
) -> LogfireSpan :
543
559
"""Context manager for creating a span.
@@ -557,18 +573,21 @@ def span(
557
573
_tags: An optional sequence of tags to include in the span.
558
574
_level: An optional log level name.
559
575
_links: An optional sequence of links to other spans. Each link is a tuple of a span context and attributes.
576
+ _warn_if_inside_generator: Set to `False` to prevent a warning when instrumenting a generator function.
560
577
attributes: The arguments to include in the span and format the message template with.
561
578
Attributes starting with an underscore are not allowed.
562
579
"""
563
580
if any (k .startswith ('_' ) for k in attributes ):
564
581
raise ValueError ('Attribute keys cannot start with an underscore.' )
582
+
565
583
return self ._span (
566
584
msg_template ,
567
585
attributes ,
568
586
_tags = _tags ,
569
587
_span_name = _span_name ,
570
588
_level = _level ,
571
589
_links = _links ,
590
+ _warn_if_inside_generator = _warn_if_inside_generator ,
572
591
)
573
592
574
593
@overload
0 commit comments