Skip to content

Commit

Permalink
Fix non scope related types (#3970)
Browse files Browse the repository at this point in the history
part of #3929
  • Loading branch information
sl0thentr0py authored Jan 21, 2025
1 parent 3c7bb1e commit 37d8599
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 86 deletions.
2 changes: 2 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
- You can no longer change the sampled status of a span with `span.sampled = False` after starting it.
- The `Span()` constructor does not accept a `hub` parameter anymore.
- `Span.finish()` does not accept a `hub` parameter anymore.
- `Span.finish()` no longer returns the `event_id` if the event is sent to sentry.
- The `Profile()` constructor does not accept a `hub` parameter anymore.
- A `Profile` object does not have a `.hub` property anymore.
- `sentry_sdk.continue_trace` no longer returns a `Transaction` and is now a context manager.
Expand Down Expand Up @@ -146,6 +147,7 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
- `continue_from_headers`, `continue_from_environ` and `from_traceparent` have been removed, please use top-level API `sentry_sdk.continue_trace` instead.
- `PropagationContext` constructor no longer takes a `dynamic_sampling_context` but takes a `baggage` object instead.
- `ThreadingIntegration` no longer takes the `propagate_hub` argument.
- `Baggage.populate_from_transaction` has been removed.

### Deprecated

Expand Down
10 changes: 5 additions & 5 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ def _prepare_event(
)
return None

event = event_
event = event_ # type: Optional[Event] # type: ignore[no-redef]

spans_delta = spans_before - len(event.get("spans", []))
if is_transaction and spans_delta > 0 and self.transport is not None:
Expand Down Expand Up @@ -483,7 +483,7 @@ def _prepare_event(

for key in "release", "environment", "server_name", "dist":
if event.get(key) is None and self.options[key] is not None:
event[key] = str(self.options[key]).strip()
event[key] = str(self.options[key]).strip() # type: ignore[literal-required]
if event.get("sdk") is None:
sdk_info = dict(SDK_INFO)
sdk_info["integrations"] = sorted(self.integrations.keys())
Expand Down Expand Up @@ -523,7 +523,7 @@ def _prepare_event(
and event is not None
and event.get("type") != "transaction"
):
new_event = None
new_event = None # type: Optional[Event]
with capture_internal_exceptions():
new_event = before_send(event, hint or {})
if new_event is None:
Expand All @@ -532,7 +532,7 @@ def _prepare_event(
self.transport.record_lost_event(
"before_send", data_category="error"
)
event = new_event
event = new_event # type: Optional[Event] # type: ignore[no-redef]

before_send_transaction = self.options["before_send_transaction"]
if (
Expand Down Expand Up @@ -562,7 +562,7 @@ def _prepare_event(
reason="before_send", data_category="span", quantity=spans_delta
)

event = new_event
event = new_event # type: Optional[Event] # type: ignore[no-redef]

return event

Expand Down
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/asyncpg.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ async def _inner(*args: Any, **kwargs: Any) -> T:

def _get_db_data(
conn: Any = None,
addr: Optional[tuple[str]] = None,
addr: Optional[tuple[str, ...]] = None,
database: Optional[str] = None,
user: Optional[str] = None,
) -> dict[str, str]:
Expand Down Expand Up @@ -218,6 +218,6 @@ def _get_db_data(
return data


def _set_on_span(span: Span, data: dict[str, Any]):
def _set_on_span(span: Span, data: dict[str, Any]) -> None:
for key, value in data.items():
span.set_attribute(key, value)
21 changes: 13 additions & 8 deletions sentry_sdk/integrations/clickhouse_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
ensure_integration_enabled,
)

from typing import TYPE_CHECKING, Any, Dict, TypeVar
from typing import TYPE_CHECKING, cast, Any, Dict, TypeVar

# Hack to get new Python features working in older versions
# without introducing a hard dependency on `typing_extensions`
Expand Down Expand Up @@ -94,6 +94,7 @@ def _inner(*args: P.args, **kwargs: P.kwargs) -> T:
connection._sentry_span = span # type: ignore[attr-defined]

data = _get_db_data(connection)
data = cast("dict[str, Any]", data)
data["db.query.text"] = query

if query_id:
Expand All @@ -116,9 +117,10 @@ def _inner(*args: P.args, **kwargs: P.kwargs) -> T:
def _wrap_end(f: Callable[P, T]) -> Callable[P, T]:
def _inner_end(*args: P.args, **kwargs: P.kwargs) -> T:
res = f(*args, **kwargs)
connection = args[0].connection
client = cast("clickhouse_driver.client.Client", args[0])
connection = client.connection

span = getattr(connection, "_sentry_span", None) # type: ignore[attr-defined]
span = getattr(connection, "_sentry_span", None)
if span is not None:
data = getattr(connection, "_sentry_db_data", {})

Expand Down Expand Up @@ -148,17 +150,20 @@ def _inner_end(*args: P.args, **kwargs: P.kwargs) -> T:

def _wrap_send_data(f: Callable[P, T]) -> Callable[P, T]:
def _inner_send_data(*args: P.args, **kwargs: P.kwargs) -> T:
connection = args[0].connection
db_params_data = args[2]
client = cast("clickhouse_driver.client.Client", args[0])
connection = client.connection
db_params_data = cast("list[Any]", args[2])
span = getattr(connection, "_sentry_span", None)

if span is not None:
data = _get_db_data(connection)
_set_on_span(span, data)

if should_send_default_pii():
saved_db_data = getattr(connection, "_sentry_db_data", {})
db_params = saved_db_data.get("db.params") or []
saved_db_data = getattr(
connection, "_sentry_db_data", {}
) # type: dict[str, Any]
db_params = saved_db_data.get("db.params") or [] # type: list[Any]
db_params.extend(db_params_data)
saved_db_data["db.params"] = db_params
span.set_attribute("db.params", _serialize_span_attribute(db_params))
Expand All @@ -178,6 +183,6 @@ def _get_db_data(connection: clickhouse_driver.connection.Connection) -> Dict[st
}


def _set_on_span(span: Span, data: Dict[str, Any]):
def _set_on_span(span: Span, data: Dict[str, Any]) -> None:
for key, value in data.items():
span.set_attribute(key, _serialize_span_attribute(value))
4 changes: 2 additions & 2 deletions sentry_sdk/integrations/opentelemetry/integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ def _patch_readable_span():
def sentry_patched_readable_span(self):
# type: (Span) -> ReadableSpan
readable_span = old_readable_span(self)
readable_span._sentry_meta = getattr(self, "_sentry_meta", {})
readable_span._sentry_meta = getattr(self, "_sentry_meta", {}) # type: ignore[attr-defined]
return readable_span

Span._readable_span = sentry_patched_readable_span
Span._readable_span = sentry_patched_readable_span # type: ignore[method-assign]


def _setup_sentry_tracing():
Expand Down
24 changes: 15 additions & 9 deletions sentry_sdk/integrations/opentelemetry/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,15 @@ def should_sample(
# parent_span_context.is_valid means this span has a parent, remote or local
is_root_span = not parent_span_context.is_valid or parent_span_context.is_remote

sample_rate = None

# Explicit sampled value provided at start_span
if attributes.get(SentrySpanAttribute.CUSTOM_SAMPLED) is not None:
custom_sampled = cast(
"Optional[bool]", attributes.get(SentrySpanAttribute.CUSTOM_SAMPLED)
)
if custom_sampled is not None:
if is_root_span:
sample_rate = float(attributes[SentrySpanAttribute.CUSTOM_SAMPLED])
sample_rate = float(custom_sampled)
if sample_rate > 0:
return sampled_result(parent_span_context, attributes, sample_rate)
else:
Expand All @@ -145,8 +150,6 @@ def should_sample(
f"[Tracing] Ignoring sampled param for non-root span {name}"
)

sample_rate = None

# Check if there is a traces_sampler
# Traces_sampler is responsible to check parent sampled to have full transactions.
has_traces_sampler = callable(client.options.get("traces_sampler"))
Expand Down Expand Up @@ -190,16 +193,19 @@ def get_description(self) -> str:


def create_sampling_context(name, attributes, parent_span_context, trace_id):
# type: (str, Attributes, SpanContext, str) -> dict[str, Any]
# type: (str, Attributes, Optional[SpanContext], int) -> dict[str, Any]
sampling_context = {
"transaction_context": {
"name": name,
"op": attributes.get(SentrySpanAttribute.OP),
"source": attributes.get(SentrySpanAttribute.SOURCE),
"op": attributes.get(SentrySpanAttribute.OP) if attributes else None,
"source": (
attributes.get(SentrySpanAttribute.SOURCE) if attributes else None
),
},
"parent_sampled": get_parent_sampled(parent_span_context, trace_id),
}
} # type: dict[str, Any]

sampling_context.update(attributes)
if attributes is not None:
sampling_context.update(attributes)

return sampling_context
8 changes: 6 additions & 2 deletions sentry_sdk/integrations/opentelemetry/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@
import sentry_sdk
from sentry_sdk.utils import Dsn
from sentry_sdk.consts import SPANSTATUS, OP, SPANDATA
from sentry_sdk.tracing import get_span_status_from_http_code, DEFAULT_SPAN_ORIGIN
from sentry_sdk.tracing_utils import Baggage, LOW_QUALITY_TRANSACTION_SOURCES
from sentry_sdk.tracing import (
get_span_status_from_http_code,
DEFAULT_SPAN_ORIGIN,
LOW_QUALITY_TRANSACTION_SOURCES,
)
from sentry_sdk.tracing_utils import Baggage
from sentry_sdk.integrations.opentelemetry.consts import SentrySpanAttribute

from sentry_sdk._types import TYPE_CHECKING
Expand Down
27 changes: 17 additions & 10 deletions sentry_sdk/tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def finish(
scope=None, # type: Optional[sentry_sdk.Scope]
end_timestamp=None, # type: Optional[Union[float, datetime]]
):
# type: (...) -> Optional[str]
# type: (...) -> None
pass

def set_measurement(self, name, value, unit=""):
Expand Down Expand Up @@ -375,7 +375,9 @@ def __init__(
self.set_status(status)

def __eq__(self, other):
# type: (Span) -> bool
# type: (object) -> bool
if not isinstance(other, Span):
return False
return self._otel_span == other._otel_span

def __repr__(self):
Expand Down Expand Up @@ -526,7 +528,6 @@ def sample_rate(self):
sample_rate = self._otel_span.get_span_context().trace_state.get(
TRACESTATE_SAMPLE_RATE_KEY
)
sample_rate = cast("Optional[str]", sample_rate)
return float(sample_rate) if sample_rate is not None else None

@property
Expand Down Expand Up @@ -668,18 +669,24 @@ def set_data(self, key, value):

def get_attribute(self, name):
# type: (str) -> Optional[Any]
if not isinstance(self._otel_span, ReadableSpan):
if (
not isinstance(self._otel_span, ReadableSpan)
or not self._otel_span.attributes
):
return None
return self._otel_span.attributes.get(name)

def set_attribute(self, key, value):
# type: (str, Any) -> None
# otel doesn't support None as values, preferring to not set the key
# at all instead
if value is None:
# otel doesn't support None as values, preferring to not set the key
# at all instead
return
serialized_value = _serialize_span_attribute(value)
if serialized_value is None:
return

self._otel_span.set_attribute(key, _serialize_span_attribute(value))
self._otel_span.set_attribute(key, serialized_value)

@property
def status(self):
Expand All @@ -690,7 +697,7 @@ def status(self):
Sentry `SPANSTATUS` it can not be guaranteed that the status
set in `set_status()` will be the same as the one returned here.
"""
if not hasattr(self._otel_span, "status"):
if not isinstance(self._otel_span, ReadableSpan):
return None

if self._otel_span.status.status_code == StatusCode.UNSET:
Expand Down Expand Up @@ -740,10 +747,10 @@ def set_http_status(self, http_status):

def is_success(self):
# type: () -> bool
return self._otel_span.status.code == StatusCode.OK
return self.status == SPANSTATUS.OK

def finish(self, end_timestamp=None):
# type: (Optional[Union[float, datetime]]) -> Optional[str]
# type: (Optional[Union[float, datetime]]) -> None
if end_timestamp is not None:
from sentry_sdk.integrations.opentelemetry.utils import (
convert_to_otel_timestamp,
Expand Down
47 changes: 0 additions & 47 deletions sentry_sdk/tracing_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,52 +525,6 @@ def from_options(cls, scope):

return Baggage(sentry_items, third_party_items, mutable)

@classmethod
def populate_from_transaction(cls, transaction):
# type: (sentry_sdk.tracing.Transaction) -> Baggage
"""
Populate fresh baggage entry with sentry_items and make it immutable
if this is the head SDK which originates traces.
"""
client = sentry_sdk.get_client()
sentry_items = {} # type: Dict[str, str]

if not client.is_active():
return Baggage(sentry_items)

options = client.options or {}

sentry_items["trace_id"] = transaction.trace_id

if options.get("environment"):
sentry_items["environment"] = options["environment"]

if options.get("release"):
sentry_items["release"] = options["release"]

if options.get("dsn"):
sentry_items["public_key"] = Dsn(options["dsn"]).public_key

if (
transaction.name
and transaction.source not in LOW_QUALITY_TRANSACTION_SOURCES
):
sentry_items["transaction"] = transaction.name

if transaction.sample_rate is not None:
sentry_items["sample_rate"] = str(transaction.sample_rate)

if transaction.sampled is not None:
sentry_items["sampled"] = "true" if transaction.sampled else "false"

# there's an existing baggage but it was mutable,
# which is why we are creating this new baggage.
# However, if by chance the user put some sentry items in there, give them precedence.
if transaction._baggage and transaction._baggage.sentry_items:
sentry_items.update(transaction._baggage.sentry_items)

return Baggage(sentry_items, mutable=False)

def freeze(self):
# type: () -> None
self.mutable = False
Expand Down Expand Up @@ -722,6 +676,5 @@ def get_current_span(scope=None):
# Circular imports
from sentry_sdk.tracing import (
BAGGAGE_HEADER_NAME,
LOW_QUALITY_TRANSACTION_SOURCES,
SENTRY_TRACE_HEADER_NAME,
)
3 changes: 2 additions & 1 deletion sentry_sdk/transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from sentry_sdk.worker import BackgroundWorker
from sentry_sdk.envelope import Envelope, Item, PayloadRef

from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, cast

if TYPE_CHECKING:
from typing import Any
Expand Down Expand Up @@ -179,6 +179,7 @@ def _parse_rate_limits(header, now=None):

retry_after = now + timedelta(seconds=int(retry_after_val))
for category in categories and categories.split(";") or (None,):
category = cast("Optional[EventDataCategory]", category)
yield category, retry_after
except (LookupError, ValueError):
continue
Expand Down

0 comments on commit 37d8599

Please sign in to comment.