diff --git a/requirements-dev-frozen.txt b/requirements-dev-frozen.txt index 8d52ffa52e150..f55cd5a4194a3 100644 --- a/requirements-dev-frozen.txt +++ b/requirements-dev-frozen.txt @@ -180,7 +180,7 @@ selenium==4.16.0 sentry-arroyo==2.16.5 sentry-cli==2.16.0 sentry-devenv==1.7.0 -sentry-forked-django-stubs==5.0.2.post7 +sentry-forked-django-stubs==5.0.2.post8 sentry-forked-djangorestframework-stubs==3.15.0.post1 sentry-kafka-schemas==0.1.101 sentry-ophio==0.2.7 diff --git a/requirements-dev.txt b/requirements-dev.txt index 2ab4f9606f3d2..ae15e0f26195f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -35,7 +35,7 @@ pip-tools>=7.1.0 packaging>=21.3 # for type checking -sentry-forked-django-stubs>=5.0.2.post7 +sentry-forked-django-stubs>=5.0.2.post8 sentry-forked-djangorestframework-stubs>=3.15.0.post1 lxml-stubs msgpack-types>=0.2.0 diff --git a/src/sentry/backup/imports.py b/src/sentry/backup/imports.py index 62189d100438b..5d0bdb3acfbb9 100644 --- a/src/sentry/backup/imports.py +++ b/src/sentry/backup/imports.py @@ -72,7 +72,7 @@ def _clear_model_tables_before_import(): for model in reversed: using = router.db_for_write(model) manager = model.with_deleted if issubclass(model, ParanoidModel) else model.objects - manager.all().delete() # type: ignore[attr-defined] + manager.all().delete() # TODO(getsentry/team-ospo#190): Remove the "Node" kludge below in favor of a more permanent # solution. diff --git a/src/sentry/db/models/manager/base.py b/src/sentry/db/models/manager/base.py index 3161635d7a2f9..873ff080069ac 100644 --- a/src/sentry/db/models/manager/base.py +++ b/src/sentry/db/models/manager/base.py @@ -6,13 +6,13 @@ from collections.abc import Callable, Collection, Generator, Mapping, MutableMapping, Sequence from contextlib import contextmanager from enum import IntEnum, auto -from typing import Any, Generic +from typing import Any from django.conf import settings from django.db import models, router from django.db.models import Model from django.db.models.fields import Field -from django.db.models.manager import BaseManager as DjangoBaseManager +from django.db.models.manager import Manager as DjangoBaseManager from django.db.models.signals import class_prepared, post_delete, post_init, post_save from django.utils.encoding import smart_str @@ -69,7 +69,10 @@ def make_key(model: Any, prefix: str, kwargs: Mapping[str, Model | int | str]) - return f"{prefix}:{model.__name__}:{md5_text(kwargs_bits_str).hexdigest()}" -class BaseManager(DjangoBaseManager.from_queryset(BaseQuerySet), Generic[M]): # type: ignore[misc] +_base_manager_base = DjangoBaseManager.from_queryset(BaseQuerySet, "_base_manager_base") + + +class BaseManager(_base_manager_base[M]): lookup_handlers = {"iexact": lambda x: x.upper()} use_for_related_fields = True diff --git a/src/sentry/models/files/abstractfile.py b/src/sentry/models/files/abstractfile.py index 946e659214413..eba3e68cadf17 100644 --- a/src/sentry/models/files/abstractfile.py +++ b/src/sentry/models/files/abstractfile.py @@ -219,7 +219,8 @@ class Meta: def _get_chunked_blob(self, mode=None, prefetch=False, prefetch_to=None, delete=True): return ChunkedFileBlobIndexWrapper( - self.FILE_BLOB_INDEX_MODEL.objects.filter(file=self) + # TODO: file blob inheritance hierarchy is unsound + self.FILE_BLOB_INDEX_MODEL.objects.filter(file=self) # type: ignore[misc] .select_related("blob") .order_by("offset"), mode=mode, @@ -295,7 +296,8 @@ def putfile(self, fileobj, blob_size=DEFAULT_BLOB_SIZE, commit=True, logger=noop blob_fileobj = ContentFile(contents) blob = self.FILE_BLOB_MODEL.from_file(blob_fileobj, logger=logger) results.append( - self.FILE_BLOB_INDEX_MODEL.objects.create(file=self, blob=blob, offset=offset) + # TODO: file blob inheritance hierarchy is unsound + self.FILE_BLOB_INDEX_MODEL.objects.create(file=self, blob=blob, offset=offset) # type: ignore[misc] ) offset += blob.size self.size = offset @@ -334,7 +336,8 @@ def assemble_from_file_blob_ids(self, file_blob_ids, checksum): offset = 0 for blob in file_blobs: try: - self.FILE_BLOB_INDEX_MODEL.objects.create(file=self, blob=blob, offset=offset) + # TODO: file blob inheritance hierarchy is unsound + self.FILE_BLOB_INDEX_MODEL.objects.create(file=self, blob=blob, offset=offset) # type: ignore[misc] except IntegrityError: # Most likely a `ForeignKeyViolation` like `SENTRY-11P5`, because # the blob we want to link does not exist anymore diff --git a/src/sentry/models/files/abstractfileblob.py b/src/sentry/models/files/abstractfileblob.py index 6598e1da17a4c..eeac09357f539 100644 --- a/src/sentry/models/files/abstractfileblob.py +++ b/src/sentry/models/files/abstractfileblob.py @@ -92,7 +92,8 @@ def _ensure_blob_owned(blob): return try: with atomic_transaction(using=router.db_for_write(cls.FILE_BLOB_OWNER_MODEL)): - cls.FILE_BLOB_OWNER_MODEL.objects.create( + # TODO: file blob inheritance hierarchy is unsound + cls.FILE_BLOB_OWNER_MODEL.objects.create( # type: ignore[misc] organization_id=organization.id, blob=blob ) except IntegrityError: diff --git a/src/sentry/organizations/services/organization/impl.py b/src/sentry/organizations/services/organization/impl.py index 53761e90a80f3..947ad568e0866 100644 --- a/src/sentry/organizations/services/organization/impl.py +++ b/src/sentry/organizations/services/organization/impl.py @@ -475,7 +475,7 @@ def get_or_create_team_member( def update_membership_flags(self, *, organization_member: RpcOrganizationMember) -> None: model = OrganizationMember.objects.get(id=organization_member.id) - model.flags = self._deserialize_member_flags(organization_member.flags) + model.flags = self._deserialize_member_flags(organization_member.flags) # type: ignore[assignment] # TODO: make BitField a mypy plugin model.save() @classmethod @@ -518,7 +518,7 @@ def merge_users(self, *, organization_id: int, from_user_id: int, to_user_id: in return if to_member is None: - to_member = OrganizationMember.objects.create( + to_member = OrganizationMember.objects.create( # type: ignore[misc] # TODO: make BitField a mypy plugin organization_id=organization_id, user_id=to_user_id, role=from_member.role, diff --git a/src/sentry/reprocessing2.py b/src/sentry/reprocessing2.py index 00b778944384b..b103ebb3eb3aa 100644 --- a/src/sentry/reprocessing2.py +++ b/src/sentry/reprocessing2.py @@ -547,7 +547,7 @@ def start_group_reprocessing( # Create a duplicate row that has the same attributes by nulling out # the primary key and saving - group.pk = group.id = None + group.pk = group.id = None # type: ignore[assignment] # XXX: intentional resetting pk new_group = group # rename variable just to avoid confusion del group new_group.status = original_status diff --git a/tests/sentry/db/test_transactions.py b/tests/sentry/db/test_transactions.py index 0d4d9167b6d92..e9b836a8c8cf7 100644 --- a/tests/sentry/db/test_transactions.py +++ b/tests/sentry/db/test_transactions.py @@ -2,7 +2,7 @@ from unittest.mock import patch import pytest -from django.db import IntegrityError, router, transaction +from django.db import router, transaction from django.test import override_settings from sentry.db.postgres.transactions import ( @@ -30,11 +30,8 @@ def test_collect_transaction_queries(self): User.objects.filter(username="user1").first() with transaction.atomic(using=router.db_for_write(Organization)): - try: - with transaction.atomic(using=router.db_for_write(Organization)): - Organization.objects.create(name=None) - except (IntegrityError, MaxSnowflakeRetryError): - pass + with pytest.raises(MaxSnowflakeRetryError): + Organization.objects.create(name=None) # type: ignore[misc] # intentional to trigger error with transaction.atomic(using=router.db_for_write(Organization)): Organization.objects.create(name="org3")