You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[DO NOT MERGE] Add experimental span type to Tracer API and SDK - #5819
Adds _start_span_with_options and _start_as_current_span_with_options. Existing positional arguments and exception-handling defaults match start_span and start_as_current_span.
type_ is a top-level, keyword-only argument. A separate keyword-only options: _SpanOptions | None = None provides an extension point for future inputs.
_SpanOptions is currently an empty, frozen, keyword-only dataclass. Future fields must have defaults; implementations ignore unsupported fields.
Both methods have concrete fallback implementations that discard type_ and options and delegate to the existing methods. Existing Tracer subclasses need no changes.
ProxyTracer forwards both methods with explicit signatures.
The methods and options class remain experimental. The methods are intended to become start_span_with_options and start_as_current_span_with_options once stable.
This follows the separate-methods-with-options approach discussed in #5877, with span type kept as a top-level argument.
SDK
Validates span type against the spec syntax. Invalid values are logged and dropped while span creation continues. The type is exposed as experimental ReadableSpan._type.
Compatibility
Adding an argument to the existing start_span or start_as_current_span contract would break third-party overrides when callers pass it, and can cause incompatible-override typing errors. New concrete methods preserve the existing contracts and provide a fallback for implementations that do not support span type.
Validation
Updated API compatibility tests for unchanged third-party-style tracers and proxy forwarding.
SDK coverage includes validation, export, decorators, exception handling, empty/reused options, and ignoring future options.
All 24 focused compatibility and span-type tests passed after the final API adjustment.
Pre-commit checks passed for changed files.
Benchmark cases were updated for the new method names. Earlier timing results have been removed because benchmarks have not been rerun for this API shape.
Follow-ups
Span type as a sampler input, OTLP serialization, and declarative configuration are outside this PR. OTLP serialization waits on opentelemetry-proto#882.
Adds experimental typed-span creation to the tracing API and SDK while preserving existing tracer signatures. Sampler inputs and OTLP serialization remain outside this PR.
Changes:
Adds keyword-only typed-span methods with legacy fallbacks and proxy forwarding.
Adds SDK span-type validation and storage on ReadableSpan.
Adds compatibility tests and SDK coverage for typed-span behavior.
File
Description
opentelemetry-sdk/tests/trace/test_trace.py
Tests validation, export, decorators, and span lifecycle behavior.
The reason will be displayed to describe this comment to others. Learn more.
We should benchmark this, some thoughts:
I think you can use Never for kwargs type to make it just a placeholder, and not make typechecker be overly permissive. If that doesn't work you can use an empty Unpack[EmptyTypedDict].
I think **kwargs forces cpython to not use vectorcall calling protocol, and kwargs forces a dict allocation which escapes to heap.
That said, we did use this pattern for user-implementable SDK components in metrics like Exporter
Typed as Unpack[_SpanOptions] now. Type checkers catch typos, SDK warns on unknown keys.
SDK skips kwargs when empty.
AI-based research, confirmed by benchmarks:
**kwargs doesn't affect vectorcall. Every Python function gets _PyFunction_Vectorcall (funcobject.c), and the kwargs dict is built later, inside frame setup (ceval.c).
Specialization is the same too. **kwargs and keyword-only params both rule out the exact-args fast path (specialize.c), and these methods are keyword-only anyway. Keyword calls specialize to CALL_KW_PY either way (specialize.c). I checked with dis(adaptive=True) on 3.12-3.14.
The dict comes from the freelist (dictobject.c), and an empty one shares the static empty keys table (dictobject.c). No extra allocations in tracemalloc, 0 GC collections over 1M calls.
The remaining delta is span type validation (median, py3.14):
- Type typed-span kwargs as Unpack[_SpanOptions] so type checkers catch typos.
- SDK logs a warning for unknown span options.
- SDK skips reading kwargs when none are passed and reads them once otherwise.
- Validate span type with a compiled regex instead of a per-character check.
- Add typed span and span type validation benchmarks with allocation tracking.
Assisted-by: Antigravity
Both new proxy overrides use untyped *args/**kwargs, so callers typed as ProxyTracer lose the keyword-only and _SpanOptions checks and can pass arguments that fail at runtime. Mirror the base signatures for _start_typed_span and _start_as_current_typed_span, and forward their arguments explicitly. This also removes the new blanket typing suppressions prohibited by AGENTS.md:62.
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can reference #5877 and repurpose it to be about generally making ABCs evolvable. There were some ideas floated there to avoid needing separate methods.
Typed span methods now take the same (positional) arguments as start_span and start_as_current_span, with type_ as a trailing keyword-only argument. record_exception and set_status_on_exception are regular arguments again; _SpanOptions is reserved for future options.
lmolkova
changed the title
Add experimental span type to Tracer API and SDK
[DO NOT MERGE] Add experimental span type to Tracer API and SDK
Oct 29, 2026
The reason will be displayed to describe this comment to others. Learn more.
since it's a new method altogether, can we move the * to be right after name to force other params to be passed by name? It makes it possible to reorder params or introduce deprecated overloads.
The reason will be displayed to describe this comment to others. Learn more.
Thanks! A one nit, but design-wise looks good. We'll still want to update this once @aabmass's compatibility changes are added so we can just add type_ directly to existing tracer methods.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds experimental span type support using separate creation methods, preserving existing third-party
Tracerimplementations.Implements spec#5378, following OTEP 5233.
Warning
The spec change is not merged yet. Reviews and approvals are requested as a prerequisite for the spec change.
API
_start_span_with_optionsand_start_as_current_span_with_options. Existing positional arguments and exception-handling defaults matchstart_spanandstart_as_current_span.type_is a top-level, keyword-only argument. A separate keyword-onlyoptions: _SpanOptions | None = Noneprovides an extension point for future inputs._SpanOptionsis currently an empty, frozen, keyword-only dataclass. Future fields must have defaults; implementations ignore unsupported fields.type_andoptionsand delegate to the existing methods. ExistingTracersubclasses need no changes.ProxyTracerforwards both methods with explicit signatures.start_span_with_optionsandstart_as_current_span_with_optionsonce stable.This follows the separate-methods-with-options approach discussed in #5877, with span type kept as a top-level argument.
SDK
Validates span type against the spec syntax. Invalid values are logged and dropped while span creation continues. The type is exposed as experimental
ReadableSpan._type.Compatibility
Adding an argument to the existing
start_spanorstart_as_current_spancontract would break third-party overrides when callers pass it, and can cause incompatible-override typing errors. New concrete methods preserve the existing contracts and provide a fallback for implementations that do not support span type.Validation
Follow-ups
Span type as a sampler input, OTLP serialization, and declarative configuration are outside this PR. OTLP serialization waits on opentelemetry-proto#882.
Stacked follow-ups: #5820, #5821.