Skip to content

Commit 77d4230

Browse files
committed
Merge branch 'major/3.0' into ivana/major/drop-support-sqlalchemy
2 parents 7145bf8 + de8652b commit 77d4230

61 files changed

Lines changed: 2964 additions & 1626 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

MIGRATION_GUIDE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
2727
## Removed
2828

2929
- The SDK no longer supports Python 3.6. The oldest supported version is now 3.7.
30+
- Dropped support for Django versions below 2.0.
31+
- Dropped support for gevent versions below 20.9.
32+
- Dropped support for greenlet versions below 0.4.17.
3033
- The `enable_tracing` option was removed. Use `traces_sample_rate=1.0` instead.
3134
- The deprecated `push_scope` and `configure_scope` APIs have been removed. Use `with new_scope():` to push a new scope and `scope = get_current_scope()` to retrieve the current scope instead.
3235
- Transaction profiling and related code was removed.

scripts/generate-test-files.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,5 @@ cd "$(dirname "$0")"
88

99
export UV_PROJECT_ENVIRONMENT=toxgen.venv
1010

11-
uv run --python 3.14t --group toxgen --with-editable .. python populate_tox/populate_tox.py
11+
uv run --python 3.14t --group toxgen --with-editable .. python populate_tox/populate_tox.py "$@"
1212
uv run --python 3.14t --group toxgen --with-editable .. python split_tox_gh_actions/split_tox_gh_actions.py

scripts/populate_tox/config.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -414,10 +414,9 @@
414414
"redis": {
415415
"package": "redis",
416416
"deps": {
417-
"*": ["fakeredis!=1.7.4", "pytest<8.0.0"],
417+
"*": ["fakeredis!=1.7.4", "pytest<8.0.0", "pytest-asyncio"],
418418
">=4.0,<5.0": ["fakeredis<2.31.0"],
419419
"py3.7,py3.8": ["fakeredis<2.26.0"],
420-
"py3.7,py3.8,py3.9,py3.10,py3.11,py3.12,py3.13": ["pytest-asyncio"],
421420
},
422421
},
423422
"redis_py_cluster_legacy": {

scripts/populate_tox/package_dependencies.jsonl

Lines changed: 474 additions & 54 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

scripts/populate_tox/populate_tox.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,13 +1208,13 @@ def get_releases_to_test(integration, package) -> list[Version] | None:
12081208
def parse_args() -> argparse.Namespace:
12091209
parser = argparse.ArgumentParser()
12101210
parser.add_argument(
1211-
"--skip-version-update",
1211+
"--skip",
12121212
nargs="*",
12131213
default=[],
12141214
help="Integrations to skip version updates for.",
12151215
)
12161216
parser.add_argument(
1217-
"--only-update",
1217+
"--only",
12181218
nargs="*",
12191219
default=[],
12201220
help="Only update versions for these integrations (all others will be skipped).",
@@ -1281,12 +1281,17 @@ def main() -> dict[str, list]:
12811281
}
12821282

12831283
args = parse_args()
1284-
if args.skip_version_update and args.only_update:
1285-
print("--skip-version-update and --only-update are mutually exclusive.")
1284+
if args.skip and args.only:
1285+
print("--skip and --only are mutually exclusive.")
12861286
sys.exit(1)
12871287

1288-
only_update = set(args.only_update)
1289-
skip_version_updates = set(args.skip_version_update)
1288+
only_update = set(args.only)
1289+
if only_update:
1290+
print(f"Only updating {' '.join(only_update)}.")
1291+
1292+
skip_update = set(args.skip)
1293+
if skip_update:
1294+
print(f"Skipping updates for {' '.join(skip_update)}.")
12901295

12911296
# Process packages
12921297
packages = defaultdict(list)
@@ -1301,7 +1306,7 @@ def main() -> dict[str, list]:
13011306
package, extra = _get_package_name(integration)
13021307

13031308
test_releases = None
1304-
skip = integration in skip_version_updates or (
1309+
skip = integration in skip_update or (
13051310
only_update and integration not in only_update
13061311
)
13071312
if skip:

scripts/populate_tox/releases.jsonl

Lines changed: 676 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sentry_sdk/_init_implementation.py

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import re
12
import warnings
23
from typing import TYPE_CHECKING
34

45
import sentry_sdk
6+
from sentry_sdk.utils import logger, parse_version
57

68
if TYPE_CHECKING:
79
from typing import Any, ContextManager, Optional
@@ -41,11 +43,32 @@ def __exit__(self, exc_type: "Any", exc_value: "Any", tb: "Any") -> None:
4143
c.close()
4244

4345

44-
def _check_python_deprecations() -> None:
45-
# Since we're likely to deprecate Python versions in the future, I'm keeping
46-
# this handy function around. Use this to detect the Python version used and
47-
# to output logger.warning()s if it's deprecated.
48-
pass
46+
def _check_version_deprecations() -> None:
47+
try:
48+
import gevent
49+
50+
gevent_version = tuple(
51+
int(part) for part in re.split(r"a|b|rc|\.", gevent.__version__)[:2]
52+
)
53+
if gevent_version < (20, 9):
54+
logger.warning(
55+
"sentry-sdk 3.x supports gevent 20.9.0 or newer. "
56+
"Please upgrade gevent or downgrade to sentry-sdk 2.x."
57+
)
58+
except Exception:
59+
pass
60+
61+
try:
62+
import greenlet
63+
64+
greenlet_version = parse_version(greenlet.__version__)
65+
if greenlet_version is not None and greenlet_version < (0, 4, 17):
66+
logger.warning(
67+
"sentry-sdk 3.x supports greenlet 0.4.17 or newer. "
68+
"Please upgrade greenlet or downgrade to sentry-sdk 2.x."
69+
)
70+
except Exception:
71+
pass
4972

5073

5174
def _init(*args: "Optional[str]", **kwargs: "Any") -> "ContextManager[Any]":
@@ -55,7 +78,7 @@ def _init(*args: "Optional[str]", **kwargs: "Any") -> "ContextManager[Any]":
5578
"""
5679
client = sentry_sdk.Client(*args, **kwargs)
5780
sentry_sdk.get_global_scope().set_client(client)
58-
_check_python_deprecations()
81+
_check_version_deprecations()
5982
rv = _InitGuard(client)
6083
return rv
6184

sentry_sdk/ai/monitoring.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import inspect
22
import sys
3+
import warnings
4+
from contextvars import ContextVar
35
from functools import wraps
46
from typing import TYPE_CHECKING
57

@@ -10,14 +12,16 @@
1012
from sentry_sdk.traces import StreamedSpan
1113
from sentry_sdk.tracing import Span
1214
from sentry_sdk.tracing_utils import has_span_streaming_enabled
13-
from sentry_sdk.utils import ContextVar, capture_internal_exceptions, reraise
15+
from sentry_sdk.utils import capture_internal_exceptions, reraise
1416

1517
if TYPE_CHECKING:
1618
from typing import Any, Awaitable, Callable, Optional, TypeVar, Union
1719

1820
F = TypeVar("F", bound=Union[Callable[..., Any], Callable[..., Awaitable[Any]]])
1921

20-
_ai_pipeline_name = ContextVar("ai_pipeline_name", default=None)
22+
_ai_pipeline_name: "ContextVar[Optional[str]]" = ContextVar(
23+
"ai_pipeline_name", default=None
24+
)
2125

2226

2327
def set_ai_pipeline_name(name: "Optional[str]") -> None:
@@ -29,6 +33,13 @@ def get_ai_pipeline_name() -> "Optional[str]":
2933

3034

3135
def ai_track(description: str, **span_kwargs: "Any") -> "Callable[[F], F]":
36+
warnings.warn(
37+
"sentry_sdk.ai.ai_track is deprecated and will be removed in version 3.0 of sentry-sdk. "
38+
"Use the manual span API instead, e.g. sentry_sdk.start_span().",
39+
DeprecationWarning,
40+
stacklevel=2,
41+
)
42+
3243
def decorator(f: "F") -> "F":
3344
def sync_wrapped(*args: "Any", **kwargs: "Any") -> "Any":
3445
client = sentry_sdk.get_client()

sentry_sdk/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import uuid
88
import warnings
99
from collections.abc import Iterable, Mapping
10+
from contextvars import ContextVar
1011
from datetime import datetime, timezone
1112
from importlib import import_module
1213
from typing import TYPE_CHECKING, Dict, List, cast, overload
@@ -44,7 +45,6 @@
4445
)
4546
from sentry_sdk.utils import (
4647
AnnotatedValue,
47-
ContextVar,
4848
capture_internal_exceptions,
4949
current_stacktrace,
5050
datetime_from_isoformat,
@@ -87,7 +87,7 @@
8787

8888
I = TypeVar("I", bound=Integration) # noqa: E741
8989

90-
_client_init_debug = ContextVar("client_init_debug")
90+
_client_init_debug: "ContextVar[bool]" = ContextVar("client_init_debug")
9191

9292

9393
SDK_INFO: "SDKInfo" = {

sentry_sdk/integrations/__init__.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ def iter_default_integrations(
131131
"beam": (2, 12),
132132
"boto3": (1, 16), # botocore
133133
"bottle": (0, 12),
134-
"celery": (4, 4, 7),
134+
"celery": (5, 0, 0),
135135
"chalice": (1, 16, 0),
136136
"clickhouse_driver": (0, 2, 0),
137137
"cohere": (5, 4, 0),
138-
"django": (1, 8),
138+
"django": (2, 0),
139139
"dramatiq": (1, 9),
140140
"falcon": (1, 4),
141141
"fastapi": (0, 79, 0),
@@ -146,10 +146,12 @@ def iter_default_integrations(
146146
"grpc": (1, 32, 0), # grpcio
147147
"httpx": (0, 16, 0),
148148
"httpx2": (2, 0, 0),
149+
"huey": (2, 0),
149150
"huggingface_hub": (0, 24, 7),
150151
"langchain": (0, 1, 0),
151152
"langgraph": (0, 6, 6),
152153
"launchdarkly": (9, 8, 0),
154+
"litestar": (2, 0, 0),
153155
"litellm": (1, 77, 5),
154156
"loguru": (0, 7, 0),
155157
"mcp": (1, 15, 0),
@@ -158,18 +160,22 @@ def iter_default_integrations(
158160
"openfeature": (0, 7, 1),
159161
"pydantic_ai": (1, 0, 0),
160162
"pymongo": (3, 5, 0),
163+
"pyramid": (1, 8),
161164
"pyreqwest": (0, 11, 6),
162165
"quart": (0, 16, 0),
163166
"ray": (2, 7, 0),
164-
"requests": (2, 0, 0),
167+
"redis": (2, 10, 0),
168+
"requests": (2, 30, 0),
165169
"rq": (0, 6),
166170
"sanic": (0, 8),
171+
"spark": (3, 0), # pyspark
167172
"sqlalchemy": (1, 4),
168173
"starlette": (0, 16),
169174
"starlite": (1, 48),
170175
"statsig": (0, 55, 3),
171176
"strawberry": (0, 209, 5),
172177
"tornado": (6, 0),
178+
"trytond": (4, 6),
173179
"typer": (0, 15),
174180
"unleash": (6, 0, 1),
175181
}

0 commit comments

Comments
 (0)