Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Tracing typing #31943

Merged
merged 4 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ class OpenTelemetrySpan(HttpSpanMixin, object):
:paramtype context: Dict[str, str]
"""

def __init__(self, span: Optional[Span] = None, name: str = "span", **kwargs: Any) -> None:
def __init__(self, span: Optional[Span] = None, name: Optional[str] = "span", **kwargs: Any) -> None:
lmazuel marked this conversation as resolved.
Show resolved Hide resolved
self._context_tokens = []
self._current_ctxt_manager: Optional[ContextManager[Span]] = None

Expand Down Expand Up @@ -336,7 +336,7 @@ def get_current_tracer(cls) -> Tracer:
return trace.get_tracer(__name__, __version__)

@classmethod
def change_context(cls, span: Span) -> ContextManager:
def change_context(cls, span: Span) -> ContextManager[Span]:
"""Change the context for the life of this context manager.

:param span: The span to use as the current span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,14 @@


from azure.core.tracing.ext.opentelemetry_span import OpenTelemetrySpan
from azure.core.tracing import SpanKind
from azure.core.tracing import SpanKind, AbstractSpan
from azure.core import __version__ as core_version


@pytest.mark.skipif(int(core_version.split(".")[1]) < 30, reason="Test requires an azure-core with runtime-checkable")
def test_structural_subtyping():
# assert issubclass(OpenTelemetrySpan, AbstractSpan)
assert isinstance(OpenTelemetrySpan(), AbstractSpan)


class TestOpentelemetryWrapper:
Expand Down
24 changes: 13 additions & 11 deletions sdk/core/azure-core/azure/core/tracing/_abstract_span.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
from enum import Enum
from urllib.parse import urlparse

from typing import Any, Sequence, Optional, Union, Callable, Dict, Type
from typing import Any, Sequence, Optional, Union, Callable, Dict, Type, Generic, TypeVar
from types import TracebackType
from typing_extensions import Protocol, ContextManager
from typing_extensions import Protocol, ContextManager, runtime_checkable
from azure.core.pipeline.transport import HttpRequest, HttpResponse, AsyncHttpResponse
from azure.core.rest import (
HttpResponse as RestHttpResponse,
Expand All @@ -31,6 +31,7 @@
Sequence[float],
]
Attributes = Dict[str, AttributeValue]
SpanType = TypeVar("SpanType")


class SpanKind(Enum):
Expand All @@ -42,7 +43,8 @@ class SpanKind(Enum):
INTERNAL = 6


class AbstractSpan(Protocol):
@runtime_checkable
class AbstractSpan(Protocol, Generic[SpanType]):
lmazuel marked this conversation as resolved.
Show resolved Hide resolved
"""Wraps a span from a distributed tracing implementation.

If a span is given wraps the span. Else a new span is created.
Expand All @@ -55,11 +57,11 @@ class AbstractSpan(Protocol):
"""

def __init__( # pylint: disable=super-init-not-called
self, span: Optional[Any] = None, name: Optional[str] = None, **kwargs: Any
self, span: Optional[SpanType] = None, name: Optional[str] = None, **kwargs: Any
) -> None:
pass

def span(self, name: str = "child_span", **kwargs: Any) -> AbstractSpan:
def span(self, name: str = "child_span", **kwargs: Any) -> AbstractSpan[SpanType]:
"""
Create a child span for the current span and append it to the child spans list.
The child span must be wrapped by an implementation of AbstractSpan
Expand Down Expand Up @@ -89,7 +91,7 @@ def kind(self, value: SpanKind) -> None:
"""
...

def __enter__(self) -> AbstractSpan:
def __enter__(self) -> AbstractSpan[SpanType]:
"""Start a span."""
...

Expand Down Expand Up @@ -157,7 +159,7 @@ def get_trace_parent(self) -> str:
...

@property
def span_instance(self) -> Any:
def span_instance(self) -> SpanType:
"""
Returns the span the class is wrapping.
"""
Expand Down Expand Up @@ -188,7 +190,7 @@ def link_from_headers(cls, headers: Dict[str, str], attributes: Optional[Attribu
...

@classmethod
def get_current_span(cls) -> Any:
def get_current_span(cls) -> SpanType:
"""
Get the current span from the execution context. Return None otherwise.

Expand All @@ -208,7 +210,7 @@ def get_current_tracer(cls) -> Any:
...

@classmethod
def set_current_span(cls, span: Any) -> None:
def set_current_span(cls, span: SpanType) -> None:
"""Set the given span as the current span in the execution context.

:param span: The span to set as the current span
Expand All @@ -226,11 +228,11 @@ def set_current_tracer(cls, tracer: Any) -> None:
...

@classmethod
def change_context(cls, span: AbstractSpan) -> ContextManager[AbstractSpan]:
def change_context(cls, span: SpanType) -> ContextManager[SpanType]:
"""Change the context for the life of this context manager.

:param span: The span to run in the new context
:type span: AbstractSpan
:type span: Any
:rtype: contextmanager
:return: A context manager that will run the given span in the new context
"""
Expand Down