From de6134b432d8070f536a31986af660265cdcd92b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 14:42:37 +0000 Subject: [PATCH 1/3] build(deps): bump djangorestframework from 3.17.2 to 3.18.2 Bumps [djangorestframework](https://github.com/encode/django-rest-framework) from 3.17.2 to 3.18.2. - [Release notes](https://github.com/encode/django-rest-framework/releases) - [Commits](https://github.com/encode/django-rest-framework/compare/3.17.2...3.18.2) --- updated-dependencies: - dependency-name: djangorestframework dependency-version: 3.18.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pyproject.toml | 2 +- uv.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a79bfad134bd..cb8abfab0bab 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,7 +25,7 @@ dependencies = [ "django-crispy-forms>=1.14.0", "django-csp>=3.8", "django-pg-zero-downtime-migrations>=0.18", - "djangorestframework>=3.16.1", + "djangorestframework>=3.18.2", "drf-spectacular>=0.27.2", "emmett55>=1.3.0", "emmett-prometheus>=0.3.0", diff --git a/uv.lock b/uv.lock index 7972f0b8bd00..1edd019db299 100644 --- a/uv.lock +++ b/uv.lock @@ -375,13 +375,13 @@ wheels = [ [[package]] name = "djangorestframework" -version = "3.17.2" +version = "3.18.2" source = { registry = "https://pypi.devinfra.sentry.io/simple" } dependencies = [ { name = "django" }, ] wheels = [ - { url = "https://pypi.devinfra.sentry.io/wheels/djangorestframework-3.17.2-py3-none-any.whl", hash = "sha256:cb0546a7415d5b46c04e0f4fe0a54b2109f4fdd5e83ca773c8c6183a6493d042" }, + { url = "https://pypi.devinfra.sentry.io/wheels/djangorestframework-3.18.2-py3-none-any.whl", hash = "sha256:a92d6a4e128a2550bd2fe2e02008a9e47fe52c180e130bb438f5ba70ee933a3f" }, ] [[package]] @@ -2379,7 +2379,7 @@ requires-dist = [ { name = "django-crispy-forms", specifier = ">=1.14.0" }, { name = "django-csp", specifier = ">=3.8" }, { name = "django-pg-zero-downtime-migrations", specifier = ">=0.18" }, - { name = "djangorestframework", specifier = ">=3.16.1" }, + { name = "djangorestframework", specifier = ">=3.18.2" }, { name = "drf-spectacular", specifier = ">=0.27.2" }, { name = "emmett-prometheus", specifier = ">=0.3.0" }, { name = "emmett-sentry", specifier = ">=0.9.0" }, From bc2d17aafed19e4257cc02eaeada633058f6d3bc Mon Sep 17 00:00:00 2001 From: Alexander Tarasov Date: Fri, 23 Oct 2026 17:36:26 +0200 Subject: [PATCH 2/3] fix(api): Keep list-based serializer errors on DRF 3.18 DRF 3.18 returns many=True validation errors as a dict keyed by index. CamelSnakeSerializer, the dashboard error formatter and several callers expect lists, and the change would alter API error responses. Opt back into the list format and ignore its deprecation warning in tests. DRF now reads the Authorization header via the cached request.headers, so the HMAC test builds a fresh request instead of mutating META. --- pyproject.toml | 4 ++++ src/sentry/conf/server.py | 1 + tests/sentry/api/test_authentication.py | 3 +++ 3 files changed, 8 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index cb8abfab0bab..e948611a1d25 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -324,6 +324,10 @@ filterwarnings = [ # PyJWT 2.12.0 introduced InsecureKeyLengthWarning for HMAC keys shorter than # 32 bytes. Tests use short secrets intentionally; production secrets are long enough. "ignore:.*HMAC key.*below the minimum recommended length.*:jwt.warnings.InsecureKeyLengthWarning", + + # DRF 3.18 deprecated the list-based ListSerializer error format; we keep it until + # callers handle the dict format (removed in DRF 3.20). + "ignore:The list-based error format for `ListSerializer` is deprecated.*:rest_framework.deprecation.RemovedInDRF320Warning", ] looponfailroots = ["src", "tests"] diff --git a/src/sentry/conf/server.py b/src/sentry/conf/server.py index ed4e95c0a2d0..604c5abdc6fe 100644 --- a/src/sentry/conf/server.py +++ b/src/sentry/conf/server.py @@ -1440,6 +1440,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str: "DEFAULT_PERMISSION_CLASSES": ("sentry.api.permissions.NoPermission",), "EXCEPTION_HANDLER": "sentry.api.handlers.custom_exception_handler", "DEFAULT_SCHEMA_CLASS": "sentry.apidocs.schema.SentrySchema", + "LIST_SERIALIZER_ERRORS_AS_DICT": False, } diff --git a/tests/sentry/api/test_authentication.py b/tests/sentry/api/test_authentication.py index 1ff0c050b10d..2ea042c1b007 100644 --- a/tests/sentry/api/test_authentication.py +++ b/tests/sentry/api/test_authentication.py @@ -785,6 +785,9 @@ class UrlInSignatureAuth(HmacSignatureAuthentication): # Signature without URL should fail + request = drf_request_from_request( + RequestFactory().post(url_path, data=data, content_type="application/json") + ) signature_without_url = generate_service_request_signature( request.path_info, request.body, From 65f15e4b707a4f8227e576c890a6e9aef60b3378 Mon Sep 17 00:00:00 2001 From: Alexander Tarasov Date: Fri, 23 Oct 2026 17:59:18 +0200 Subject: [PATCH 3/3] test: Match DRF list-error warning by builtin category rest_framework.deprecation does not exist before DRF 3.18, so name the PendingDeprecationWarning base class to keep the filter version-agnostic, same as getsentry. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e948611a1d25..d43740e580d0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -327,7 +327,7 @@ filterwarnings = [ # DRF 3.18 deprecated the list-based ListSerializer error format; we keep it until # callers handle the dict format (removed in DRF 3.20). - "ignore:The list-based error format for `ListSerializer` is deprecated.*:rest_framework.deprecation.RemovedInDRF320Warning", + "ignore:The list-based error format for `ListSerializer` is deprecated.*:PendingDeprecationWarning", ] looponfailroots = ["src", "tests"]