Skip to content

Commit 9acd5b8

Browse files
authored
Revert "Revert "Reapply "ref: enable local_partial_types=True (#89854)" (#90001)"" (#90272)
This reverts commit 89cf46b. This commit was reverted as part of an incident as it went out in a suspect release, but this change was not a contributing factor. Refs #90001
1 parent ec04588 commit 9acd5b8

File tree

22 files changed

+146
-193
lines changed

22 files changed

+146
-193
lines changed

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ warn_unused_configs = true
6262
warn_unused_ignores = true
6363
warn_redundant_casts = true
6464
enable_error_code = ["ignore-without-code", "redundant-self"]
65+
local_partial_types = true # compat with dmypy
6566

6667
[tool.django-stubs]
6768
django_settings_module = "sentry.conf.server_mypy"

src/sentry/api/endpoints/organization_details.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,8 @@
5757
REQUIRE_SCRUB_DEFAULTS_DEFAULT,
5858
REQUIRE_SCRUB_IP_ADDRESS_DEFAULT,
5959
ROLLBACK_ENABLED_DEFAULT,
60-
SAFE_FIELDS_DEFAULT,
6160
SAMPLING_MODE_DEFAULT,
6261
SCRAPE_JAVASCRIPT_DEFAULT,
63-
SENSITIVE_FIELDS_DEFAULT,
6462
TARGET_SAMPLE_RATE_DEFAULT,
6563
ObjectStatus,
6664
)
@@ -124,8 +122,8 @@
124122
ACCOUNT_RATE_LIMIT_DEFAULT,
125123
),
126124
("dataScrubber", "sentry:require_scrub_data", bool, REQUIRE_SCRUB_DATA_DEFAULT),
127-
("sensitiveFields", "sentry:sensitive_fields", list, SENSITIVE_FIELDS_DEFAULT),
128-
("safeFields", "sentry:safe_fields", list, SAFE_FIELDS_DEFAULT),
125+
("sensitiveFields", "sentry:sensitive_fields", list, None),
126+
("safeFields", "sentry:safe_fields", list, None),
129127
(
130128
"scrapeJavaScript",
131129
"sentry:scrape_javascript",

src/sentry/api/serializers/models/organization.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,8 @@
4646
REQUIRE_SCRUB_IP_ADDRESS_DEFAULT,
4747
RESERVED_ORGANIZATION_SLUGS,
4848
ROLLBACK_ENABLED_DEFAULT,
49-
SAFE_FIELDS_DEFAULT,
5049
SAMPLING_MODE_DEFAULT,
5150
SCRAPE_JAVASCRIPT_DEFAULT,
52-
SENSITIVE_FIELDS_DEFAULT,
53-
STREAMLINE_UI_ONLY,
5451
TARGET_SAMPLE_RATE_DEFAULT,
5552
ObjectStatus,
5653
)
@@ -645,9 +642,8 @@ def serialize( # type: ignore[explicit-override, override]
645642
"dataScrubberDefaults": bool(
646643
obj.get_option("sentry:require_scrub_defaults", REQUIRE_SCRUB_DEFAULTS_DEFAULT)
647644
),
648-
"sensitiveFields": obj.get_option("sentry:sensitive_fields", SENSITIVE_FIELDS_DEFAULT)
649-
or [],
650-
"safeFields": obj.get_option("sentry:safe_fields", SAFE_FIELDS_DEFAULT) or [],
645+
"sensitiveFields": obj.get_option("sentry:sensitive_fields", None) or [],
646+
"safeFields": obj.get_option("sentry:safe_fields", None) or [],
651647
"storeCrashReports": convert_crashreport_count(
652648
obj.get_option("sentry:store_crash_reports")
653649
),
@@ -699,7 +695,7 @@ def serialize( # type: ignore[explicit-override, override]
699695
"rollbackEnabled": bool(
700696
obj.get_option("sentry:rollback_enabled", ROLLBACK_ENABLED_DEFAULT)
701697
),
702-
"streamlineOnly": obj.get_option("sentry:streamline_ui_only", STREAMLINE_UI_ONLY),
698+
"streamlineOnly": obj.get_option("sentry:streamline_ui_only", None),
703699
"trustedRelays": [
704700
# serialize trusted relays info into their external form
705701
_relay_internal_to_external(raw)

src/sentry/auth/authenticators/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
1-
from .base import AuthenticatorInterface # NOQA
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
5+
from .base import AuthenticatorInterface
26
from .recovery_code import RecoveryCodeInterface
37
from .sms import SmsInterface
48
from .totp import TotpInterface
59
from .u2f import U2fInterface
610

7-
AUTHENTICATOR_INTERFACES = {}
8-
AUTHENTICATOR_INTERFACES_BY_TYPE = {}
9-
AUTHENTICATOR_CHOICES = []
11+
if TYPE_CHECKING:
12+
from django.utils.functional import _StrPromise
13+
14+
AUTHENTICATOR_INTERFACES: dict[str, type[AuthenticatorInterface]] = {}
15+
AUTHENTICATOR_INTERFACES_BY_TYPE: dict[int, type[AuthenticatorInterface]] = {}
16+
AUTHENTICATOR_CHOICES: list[tuple[int, str | _StrPromise]] = []
1017

1118

1219
def register_authenticator(cls: type[AuthenticatorInterface]) -> None:

src/sentry/auth/providers/oauth2.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ def _get_redirect_url() -> str:
2626

2727

2828
class OAuth2Login(AuthView):
29-
authorize_url = None
30-
client_id = None
29+
authorize_url: str | None = None
30+
client_id: str | None = None
3131
scope = ""
3232

3333
def __init__(self, authorize_url=None, client_id=None, scope=None, *args, **kwargs):
@@ -71,9 +71,9 @@ def dispatch(self, request: HttpRequest, helper) -> HttpResponse:
7171

7272

7373
class OAuth2Callback(AuthView):
74-
access_token_url = None
75-
client_id = None
76-
client_secret = None
74+
access_token_url: str | None = None
75+
client_id: str | None = None
76+
client_secret: str | None = None
7777

7878
def __init__(self, access_token_url=None, client_id=None, client_secret=None, *args, **kwargs):
7979
super().__init__(*args, **kwargs)

src/sentry/auth/system.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ class SystemToken:
4444

4545
id = "<system>"
4646
token = "<system.secret-key>"
47-
application = None
48-
organization_id = None
49-
scoping_organization_id = None
47+
application: None = None
48+
organization_id: None = None
49+
scoping_organization_id: None = None
5050

5151
@classmethod
5252
def from_request(cls, request: HttpRequest, token: str) -> SystemToken | None:

src/sentry/conf/server.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
import tempfile
1313
from collections.abc import Callable, Mapping, MutableSequence
1414
from datetime import datetime, timedelta
15-
from typing import Any, Final, Union, overload
15+
from typing import Any, Final, Literal, Union, overload
1616
from urllib.parse import urlparse
1717

1818
import sentry
@@ -359,7 +359,7 @@ def env(
359359
# Once relay's fully rolled out, that can be deleted.
360360
# Until then, the safest and easiest thing to do is to disable this check
361361
# to leave things the way they were with Django <1.9.
362-
DATA_UPLOAD_MAX_MEMORY_SIZE = None
362+
DATA_UPLOAD_MAX_MEMORY_SIZE: int | None = None
363363

364364
TEMPLATES = [
365365
{
@@ -616,7 +616,7 @@ def env(
616616
# this breaks certain IDP flows where we need cookies sent to us on a redirected POST
617617
# request, and `Lax` doesnt permit this.
618618
# See here: https://docs.djangoproject.com/en/2.1/ref/settings/#session-cookie-samesite
619-
SESSION_COOKIE_SAMESITE = None
619+
SESSION_COOKIE_SAMESITE: Literal["Strict", "Lax", None] = None
620620

621621
BITBUCKET_CONSUMER_KEY = ""
622622
BITBUCKET_CONSUMER_SECRET = ""
@@ -747,7 +747,7 @@ def SOCIAL_AUTH_DEFAULT_USERNAME() -> str:
747747
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
748748
CELERY_IGNORE_RESULT = True
749749
CELERY_SEND_EVENTS = False
750-
CELERY_RESULT_BACKEND = None
750+
CELERY_RESULT_BACKEND: str | None = None
751751
CELERY_TASK_RESULT_EXPIRES = 1
752752
CELERY_DISABLE_RATE_LIMITS = True
753753
CELERY_DEFAULT_QUEUE = "default"
@@ -3215,9 +3215,6 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]:
32153215
# Similarity-v1: uses hardcoded set of event properties for diffing
32163216
SENTRY_SIMILARITY_INDEX_REDIS_CLUSTER = "default"
32173217

3218-
# Unused legacy option, there to satisfy getsentry CI. Remove from getsentry, then here
3219-
SENTRY_SIMILARITY2_INDEX_REDIS_CLUSTER = None
3220-
32213218
# How long the migration phase for grouping lasts
32223219
SENTRY_GROUPING_UPDATE_MIGRATION_PHASE = 30 * 24 * 3600 # 30 days
32233220

@@ -3280,7 +3277,7 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]:
32803277
# Zero Downtime Migrations settings as defined at
32813278
# https://github.com/tbicr/django-pg-zero-downtime-migrations#settings
32823279
ZERO_DOWNTIME_MIGRATIONS_RAISE_FOR_UNSAFE = True
3283-
ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT = None
3280+
ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT: str | None = None
32843281
ZERO_DOWNTIME_MIGRATIONS_STATEMENT_TIMEOUT: str | None = None
32853282
ZERO_DOWNTIME_MIGRATIONS_LOCK_TIMEOUT_FORCE = False
32863283
ZERO_DOWNTIME_MIGRATIONS_IDEMPOTENT_SQL = False
@@ -3413,7 +3410,7 @@ def custom_parameter_sort(parameter: dict) -> tuple[str, int]:
34133410
SENTRY_PROFILE_CHUNKS_FUTURES_MAX_LIMIT = 10000
34143411

34153412
# How long we should wait for a gateway proxy request to return before giving up
3416-
GATEWAY_PROXY_TIMEOUT = None
3413+
GATEWAY_PROXY_TIMEOUT: int | None = None
34173414

34183415
SENTRY_SLICING_LOGICAL_PARTITION_COUNT = 256
34193416
# This maps a Sliceable for slicing by name and (lower logical partition, upper physical partition)

src/sentry/constants.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -691,14 +691,11 @@ class InsightModules(Enum):
691691
ACCOUNT_RATE_LIMIT_DEFAULT = 0
692692
REQUIRE_SCRUB_DATA_DEFAULT = False
693693
REQUIRE_SCRUB_DEFAULTS_DEFAULT = False
694-
SENSITIVE_FIELDS_DEFAULT = None
695-
SAFE_FIELDS_DEFAULT = None
696694
ATTACHMENTS_ROLE_DEFAULT = settings.SENTRY_DEFAULT_ROLE
697695
DEBUG_FILES_ROLE_DEFAULT = "admin"
698696
EVENTS_ADMIN_ROLE_DEFAULT = settings.SENTRY_DEFAULT_ROLE
699697
REQUIRE_SCRUB_IP_ADDRESS_DEFAULT = False
700698
SCRAPE_JAVASCRIPT_DEFAULT = True
701-
TRUSTED_RELAYS_DEFAULT = None
702699
JOIN_REQUESTS_DEFAULT = True
703700
HIDE_AI_FEATURES_DEFAULT = False
704701
GITHUB_COMMENT_BOT_DEFAULT = True
@@ -709,7 +706,6 @@ class InsightModules(Enum):
709706
TARGET_SAMPLE_RATE_DEFAULT = 1.0
710707
SAMPLING_MODE_DEFAULT = "organization"
711708
ROLLBACK_ENABLED_DEFAULT = True
712-
STREAMLINE_UI_ONLY = None
713709

714710
# `sentry:events_member_admin` - controls whether the 'member' role gets the event:admin scope
715711
EVENTS_MEMBER_ADMIN_DEFAULT = True

src/sentry/deletions/__init__.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
from __future__ import annotations
8282

83+
import functools
8384
from typing import TYPE_CHECKING, Any
8485

8586
if TYPE_CHECKING:
@@ -193,9 +194,7 @@ def load_defaults(manager: DeletionTaskManager) -> None:
193194
# fmt: on
194195

195196

196-
_default_manager = None
197-
198-
197+
@functools.cache
199198
def get_manager() -> DeletionTaskManager:
200199
"""
201200
Get the deletions default_manager
@@ -205,13 +204,10 @@ def get_manager() -> DeletionTaskManager:
205204
"""
206205
from sentry.deletions.base import ModelDeletionTask
207206

208-
global _default_manager
209-
210-
if _default_manager is None:
211-
_default_manager = DeletionTaskManager(default_task=ModelDeletionTask)
212-
load_defaults(_default_manager)
207+
default_manager = DeletionTaskManager(default_task=ModelDeletionTask)
208+
load_defaults(default_manager)
213209

214-
return _default_manager
210+
return default_manager
215211

216212

217213
def get(

src/sentry/filestore/gcs.py

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -226,22 +226,25 @@ def _try_upload():
226226

227227

228228
class GoogleCloudStorage(Storage):
229-
project_id = None
230-
credentials = None
231-
bucket_name = None
232-
file_name_charset = "utf-8"
233-
file_overwrite = True
234-
download_url = "https://www.googleapis.com"
235-
# The max amount of memory a returned file can take up before being
236-
# rolled over into a temporary file on disk. Default is 0: Do not roll over.
237-
max_memory_size = 0
238-
239-
def __init__(self, **settings):
240-
# check if some of the settings we've provided as class attributes
241-
# need to be overwritten with values passed in here
242-
for name, value in settings.items():
243-
if hasattr(self, name):
244-
setattr(self, name, value)
229+
def __init__(
230+
self,
231+
project_id=None,
232+
credentials=None,
233+
bucket_name=None,
234+
file_name_charset="utf-8",
235+
file_overwrite=True,
236+
download_url="https://www.googleapis.com",
237+
# The max amount of memory a returned file can take up before being
238+
# rolled over into a temporary file on disk. Default is 0: Do not roll over.
239+
max_memory_size=0,
240+
):
241+
self.project_id = project_id
242+
self.credentials = credentials
243+
self.bucket_name = bucket_name
244+
self.file_name_charset = file_name_charset
245+
self.file_overwrite = file_overwrite
246+
self.download_url = download_url
247+
self.max_memory_size = max_memory_size
245248

246249
self._bucket = None
247250
self._client = None

src/sentry/filestore/s3.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -255,28 +255,28 @@ class S3Boto3Storage(Storage):
255255
connection_response_error = ClientError
256256
file_class = S3Boto3StorageFile
257257
# If config provided in init, signature_version and addressing_style settings/args are ignored.
258-
config = None
258+
config: Config | None = None
259259

260260
# used for looking up the access and secret key from env vars
261261
access_key_names = ["AWS_S3_ACCESS_KEY_ID", "AWS_ACCESS_KEY_ID"]
262262
secret_key_names = ["AWS_S3_SECRET_ACCESS_KEY", "AWS_SECRET_ACCESS_KEY"]
263263

264-
access_key = None
265-
secret_key = None
264+
access_key: str | None = None
265+
secret_key: str | None = None
266266
file_overwrite = True
267267
object_parameters: dict[str, str] = {}
268-
bucket_name = None
268+
bucket_name: str | None = None
269269
auto_create_bucket = False
270270
default_acl = "public-read"
271271
bucket_acl = default_acl
272272
querystring_auth = True
273273
querystring_expire = 3600
274-
signature_version = None
274+
signature_version: str | None = None
275275
reduced_redundancy = False
276276
location = ""
277277
encryption = False
278278
custom_domain: str | None = None
279-
addressing_style = None
279+
addressing_style: str | None = None
280280
secure_urls = True
281281
file_name_charset = "utf-8"
282282
gzip = False
@@ -289,8 +289,8 @@ class S3Boto3Storage(Storage):
289289
"image/svg+xml",
290290
)
291291
url_protocol = "https:"
292-
endpoint_url = None
293-
region_name = None
292+
endpoint_url: str | None = None
293+
region_name: str | None = None
294294
use_ssl = True
295295

296296
def __init__(self, acl=None, bucket=None, **settings):

src/sentry/identity/oauth2.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ def record_event(event: IntegrationPipelineViewType, provider: str):
244244

245245

246246
class OAuth2LoginView(PipelineView):
247-
authorize_url = None
248-
client_id = None
247+
authorize_url: str | None = None
248+
client_id: str | None = None
249249
scope = ""
250250

251251
def __init__(self, authorize_url=None, client_id=None, scope=None, *args, **kwargs):
@@ -294,9 +294,9 @@ def dispatch(self, request: HttpRequest, pipeline: Pipeline) -> HttpResponseBase
294294

295295

296296
class OAuth2CallbackView(PipelineView):
297-
access_token_url = None
298-
client_id = None
299-
client_secret = None
297+
access_token_url: str | None = None
298+
client_id: str | None = None
299+
client_secret: str | None = None
300300

301301
def __init__(self, access_token_url=None, client_id=None, client_secret=None, *args, **kwargs):
302302
super().__init__(*args, **kwargs)

0 commit comments

Comments
 (0)