Skip to content

Drop support for old frameworks #4246

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

Merged
merged 6 commits into from
Apr 9, 2025
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
3 changes: 3 additions & 0 deletions MIGRATION_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh
- `Transport.capture_event` has been removed. Use `Transport.capture_envelope` instead.
- Function transports are no longer supported. Subclass the `Transport` instead.
- `start_transaction` (`start_span`) no longer takes a `baggage` argument. Use the `continue_trace()` context manager instead to propagate baggage.
- Dropped support for Django versions below 2.0.
- Dropped support for trytond versions below 5.0.
- Dropped support for Falcon versions below 3.0.

### Deprecated

Expand Down
2 changes: 1 addition & 1 deletion scripts/populate_tox/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"package": "django",
"deps": {
"*": [
"channels[daphne]",
"psycopg2-binary",
"djangorestframework",
"pytest-django",
Expand All @@ -45,7 +46,6 @@
"Werkzeug<2.1.0",
],
"<3.1": ["pytest-django<4.0"],
">=2.0": ["channels[daphne]"],
},
},
"dramatiq": {
Expand Down
5 changes: 3 additions & 2 deletions sentry_sdk/integrations/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ def iter_default_integrations(with_auto_enabling_integrations):
"celery": (4, 4, 7),
"chalice": (1, 16, 0),
"clickhouse_driver": (0, 2, 0),
"django": (1, 8),
"django": (2, 0),
"dramatiq": (1, 9),
"falcon": (1, 4),
"falcon": (3, 0),
"fastapi": (0, 79, 0),
"flask": (1, 1, 4),
"gql": (3, 4, 1),
Expand All @@ -157,6 +157,7 @@ def iter_default_integrations(with_auto_enabling_integrations):
"statsig": (0, 55, 3),
"strawberry": (0, 209, 5),
"tornado": (6, 0),
"trytond": (5, 0),
"typer": (0, 15),
"unleash": (6, 0, 1),
}
Expand Down
38 changes: 6 additions & 32 deletions sentry_sdk/integrations/django/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
except ImportError:
raise DidNotEnable("Django not installed")

from sentry_sdk.integrations.django.caching import patch_caching
from sentry_sdk.integrations.django.transactions import LEGACY_RESOLVER
from sentry_sdk.integrations.django.templates import (
get_template_frame_from_exception,
Expand All @@ -65,11 +66,6 @@
from sentry_sdk.integrations.django.signals_handlers import patch_signals
from sentry_sdk.integrations.django.views import patch_views

if DJANGO_VERSION[:2] > (1, 8):
from sentry_sdk.integrations.django.caching import patch_caching
else:
patch_caching = None # type: ignore

from typing import TYPE_CHECKING

if TYPE_CHECKING:
Expand All @@ -90,19 +86,6 @@
from sentry_sdk._types import Event, Hint, EventProcessor, NotImplementedType


if DJANGO_VERSION < (1, 10):

def is_authenticated(request_user):
# type: (Any) -> bool
return request_user.is_authenticated()

else:

def is_authenticated(request_user):
# type: (Any) -> bool
return request_user.is_authenticated


TRANSACTION_STYLE_VALUES = ("function_name", "url")


Expand Down Expand Up @@ -597,7 +580,7 @@ def _set_user_info(request, event):

user = getattr(request, "user", None)

if user is None or not is_authenticated(user):
if user is None or not user.is_authenticated:
return

try:
Expand All @@ -624,20 +607,11 @@ def install_sql_hook():
except ImportError:
from django.db.backends.util import CursorWrapper

try:
# django 1.6 and 1.7 compatability
from django.db.backends import BaseDatabaseWrapper
except ImportError:
# django 1.8 or later
from django.db.backends.base.base import BaseDatabaseWrapper
from django.db.backends.base.base import BaseDatabaseWrapper

try:
real_execute = CursorWrapper.execute
real_executemany = CursorWrapper.executemany
real_connect = BaseDatabaseWrapper.connect
except AttributeError:
# This won't work on Django versions < 1.6
return
real_execute = CursorWrapper.execute
real_executemany = CursorWrapper.executemany
real_connect = BaseDatabaseWrapper.connect

@ensure_integration_enabled(DjangoIntegration, real_execute)
def execute(self, sql, params=None):
Expand Down
11 changes: 1 addition & 10 deletions sentry_sdk/integrations/django/templates.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import functools

from django.template import TemplateSyntaxError
from django.template.base import Origin
from django.utils.safestring import mark_safe
from django import VERSION as DJANGO_VERSION

import sentry_sdk
from sentry_sdk.consts import OP
Expand All @@ -17,13 +17,6 @@
from typing import Iterator
from typing import Tuple

try:
# support Django 1.9
from django.template.base import Origin
except ImportError:
# backward compatibility
from django.template.loader import LoaderOrigin as Origin


def get_template_frame_from_exception(exc_value):
# type: (Optional[BaseException]) -> Optional[Dict[str, Any]]
Expand Down Expand Up @@ -81,8 +74,6 @@ def rendered_content(self):

SimpleTemplateResponse.rendered_content = rendered_content

if DJANGO_VERSION < (1, 7):
return
import django.shortcuts

real_render = django.shortcuts.render
Expand Down
7 changes: 1 addition & 6 deletions sentry_sdk/integrations/django/transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,7 @@
from typing import Union
from re import Pattern

from django import VERSION as DJANGO_VERSION

if DJANGO_VERSION >= (2, 0):
from django.urls.resolvers import RoutePattern
else:
RoutePattern = None
from django.urls.resolvers import RoutePattern

try:
from django.urls import get_resolver
Expand Down
30 changes: 6 additions & 24 deletions sentry_sdk/integrations/falcon.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@

from sentry_sdk._types import Event, EventProcessor

# In Falcon 3.0 `falcon.api_helpers` is renamed to `falcon.app_helpers`
# and `falcon.API` to `falcon.App`

try:
import falcon # type: ignore
Expand All @@ -29,24 +27,15 @@
except ImportError:
raise DidNotEnable("Falcon not installed")

try:
import falcon.app_helpers # type: ignore

falcon_helpers = falcon.app_helpers
falcon_app_class = falcon.App
FALCON3 = True
except ImportError:
import falcon.api_helpers # type: ignore
import falcon.app_helpers # type: ignore

falcon_helpers = falcon.api_helpers
falcon_app_class = falcon.API
FALCON3 = False
falcon_helpers = falcon.app_helpers
falcon_app_class = falcon.App


_FALCON_UNSET = None # type: Optional[object]
if FALCON3: # falcon.request._UNSET is only available in Falcon 3.0+
with capture_internal_exceptions():
from falcon.request import _UNSET as _FALCON_UNSET # type: ignore[import-not-found, no-redef]
with capture_internal_exceptions():
from falcon.request import _UNSET as _FALCON_UNSET # type: ignore[import-not-found, no-redef]


class FalconRequestExtractor(RequestExtractor):
Expand Down Expand Up @@ -232,14 +221,7 @@ def _exception_leads_to_http_5xx(ex, response):
ex, (falcon.HTTPError, falcon.http_status.HTTPStatus)
)

# We only check the HTTP status on Falcon 3 because in Falcon 2, the status on the response
# at the stage where we capture it is listed as 200, even though we would expect to see a 500
# status. Since at the time of this change, Falcon 2 is ca. 4 years old, we have decided to
# only perform this check on Falcon 3+, despite the risk that some handled errors might be
# reported to Sentry as unhandled on Falcon 2.
return (is_server_error or is_unhandled_error) and (
not FALCON3 or _has_http_5xx_status(response)
)
return (is_server_error or is_unhandled_error) and _has_http_5xx_status(response)


def _has_http_5xx_status(response):
Expand Down
5 changes: 4 additions & 1 deletion sentry_sdk/integrations/trytond.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import sentry_sdk
from sentry_sdk.integrations import Integration
from sentry_sdk.integrations import _check_minimum_version, Integration
from sentry_sdk.integrations.wsgi import SentryWsgiMiddleware
from sentry_sdk.utils import ensure_integration_enabled, event_from_exception

from trytond import __version__ as trytond_version # type: ignore
from trytond.exceptions import TrytonException # type: ignore
from trytond.wsgi import app # type: ignore

Expand All @@ -19,6 +20,8 @@ def __init__(self): # type: () -> None

@staticmethod
def setup_once(): # type: () -> None
_check_minimum_version(TrytondWSGIIntegration, trytond_version)

app.wsgi_app = SentryWsgiMiddleware(
app.wsgi_app,
span_origin=TrytondWSGIIntegration.origin,
Expand Down
22 changes: 9 additions & 13 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# The file (and all resulting CI YAMLs) then need to be regenerated via
# "scripts/generate-test-files.sh".
#
# Last generated: 2025-04-04T12:20:40.475012+00:00
# Last generated: 2025-04-04T13:09:23.106982+00:00

[tox]
requires =
Expand Down Expand Up @@ -227,7 +227,7 @@ envlist =


# ~~~ Web 1 ~~~
{py3.7}-django-v1.11.29
{py3.7}-django-v2.0.9
{py3.7,py3.8,py3.9}-django-v2.2.28
{py3.7,py3.9,py3.10}-django-v3.2.25
{py3.8,py3.11,py3.12}-django-v4.2.20
Expand All @@ -249,7 +249,7 @@ envlist =
{py3.7}-bottle-v0.12.25
{py3.7,py3.8,py3.9}-bottle-v0.13.2

{py3.7}-falcon-v2.0.0
{py3.7,py3.8,py3.9}-falcon-v3.0.1
{py3.7,py3.11,py3.12}-falcon-v3.1.3
{py3.8,py3.11,py3.12}-falcon-v4.0.2

Expand Down Expand Up @@ -601,12 +601,13 @@ deps =


# ~~~ Web 1 ~~~
django-v1.11.29: django==1.11.29
django-v2.0.9: django==2.0.9
django-v2.2.28: django==2.2.28
django-v3.2.25: django==3.2.25
django-v4.2.20: django==4.2.20
django-v5.0.9: django==5.0.9
django-v5.2: django==5.2
django: channels[daphne]
django: psycopg2-binary
django: djangorestframework
django: pytest-django
Expand All @@ -616,19 +617,14 @@ deps =
django-v5.0.9: pytest-asyncio
django-v5.2: pytest-asyncio
django-v2.2.28: six
django-v1.11.29: djangorestframework>=3.0,<4.0
django-v1.11.29: Werkzeug<2.1.0
django-v2.0.9: djangorestframework>=3.0,<4.0
django-v2.0.9: Werkzeug<2.1.0
django-v2.2.28: djangorestframework>=3.0,<4.0
django-v2.2.28: Werkzeug<2.1.0
django-v3.2.25: djangorestframework>=3.0,<4.0
django-v3.2.25: Werkzeug<2.1.0
django-v1.11.29: pytest-django<4.0
django-v2.0.9: pytest-django<4.0
django-v2.2.28: pytest-django<4.0
django-v2.2.28: channels[daphne]
django-v3.2.25: channels[daphne]
django-v4.2.20: channels[daphne]
django-v5.0.9: channels[daphne]
django-v5.2: channels[daphne]

flask-v1.1.4: flask==1.1.4
flask-v2.3.3: flask==2.3.3
Expand Down Expand Up @@ -660,7 +656,7 @@ deps =
bottle-v0.13.2: bottle==0.13.2
bottle: werkzeug<2.1.0

falcon-v2.0.0: falcon==2.0.0
falcon-v3.0.1: falcon==3.0.1
falcon-v3.1.3: falcon==3.1.3
falcon-v4.0.2: falcon==4.0.2

Expand Down
Loading