Skip to content

Commit a82eeb9

Browse files
ref: stricter typing for a few utils modules (#93184)
<!-- Describe your PR here. -->
1 parent b2a755c commit a82eeb9

File tree

8 files changed

+60
-32
lines changed

8 files changed

+60
-32
lines changed

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,19 +406,25 @@ module = [
406406
"sentry.utils.env",
407407
"sentry.utils.event",
408408
"sentry.utils.event_tracker",
409+
"sentry.utils.forms",
409410
"sentry.utils.function_cache",
410411
"sentry.utils.geo",
411412
"sentry.utils.imports",
412413
"sentry.utils.iterators",
413414
"sentry.utils.javascript",
415+
"sentry.utils.kafka",
414416
"sentry.utils.kvstore.*",
415417
"sentry.utils.lazy_service_wrapper",
416418
"sentry.utils.locking.*",
419+
"sentry.utils.math",
420+
"sentry.utils.memory",
421+
"sentry.utils.metrics",
417422
"sentry.utils.migrations",
418423
"sentry.utils.numbers",
419424
"sentry.utils.otp",
420425
"sentry.utils.performance_issues.detectors.*",
421426
"sentry.utils.performance_issues.performance_detection",
427+
"sentry.utils.projectflags",
422428
"sentry.utils.pubsub",
423429
"sentry.utils.redis",
424430
"sentry.utils.redis_metrics",
@@ -429,6 +435,7 @@ module = [
429435
"sentry.utils.services",
430436
"sentry.utils.sms",
431437
"sentry.utils.snowflake",
438+
"sentry.utils.snuba_rpc",
432439
"sentry.utils.urls",
433440
"sentry.utils.uwsgi",
434441
"sentry.utils.warnings",

src/sentry/utils/forms.py

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,34 @@
1+
from __future__ import annotations
2+
13
from collections.abc import Sequence
4+
from typing import TYPE_CHECKING, NotRequired, TypedDict
25

36
from django import forms
47
from django.forms import ChoiceField
58

9+
if TYPE_CHECKING:
10+
from django.utils.functional import _StrPromise
11+
12+
13+
class _FieldConfig(TypedDict):
14+
name: str
15+
label: str | _StrPromise
16+
placeholder: str | None
17+
help: str | _StrPromise
18+
required: bool
19+
default: object
20+
type: NotRequired[str]
21+
choices: NotRequired[object]
622

7-
def field_to_config(name, field):
8-
config = {
23+
24+
def field_to_config(name: str, field: forms.Field) -> _FieldConfig:
25+
config: _FieldConfig = {
926
"name": name,
1027
"label": field.label or name.replace("_", " ").title(),
1128
"placeholder": field.widget.attrs.get("placeholder"),
1229
"help": field.help_text,
1330
"required": field.required,
31+
"default": field.initial,
1432
}
1533
if isinstance(field, forms.URLField):
1634
config["type"] = "url"
@@ -33,13 +51,8 @@ def field_to_config(name, field):
3351
return config
3452

3553

36-
def form_to_config(form):
37-
config = []
38-
for name, field in form.base_fields.items():
39-
row = field_to_config(name, field)
40-
row["default"] = field.initial
41-
config.append(row)
42-
return config
54+
def form_to_config(form: forms.Form) -> list[_FieldConfig]:
55+
return [field_to_config(name, field) for name, field in form.base_fields.items()]
4356

4457

4558
def set_field_choices(field: forms.Field, choices: Sequence[tuple[object, object]]) -> None:

src/sentry/utils/kafka.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import signal
33
import time
44
from threading import Thread
5+
from typing import Any
6+
7+
from arroyo.processing.processor import StreamProcessor
58

69
logger = logging.getLogger(__name__)
710

@@ -25,19 +28,21 @@ def delay_kafka_rebalance(configured_delay: int) -> None:
2528
time.sleep(sleep_secs)
2629

2730

28-
def delay_shutdown(processor, quantized_rebalance_delay_secs) -> None:
31+
def delay_shutdown(processor: StreamProcessor[Any], quantized_rebalance_delay_secs: int) -> None:
2932
if quantized_rebalance_delay_secs:
3033
delay_kafka_rebalance(quantized_rebalance_delay_secs)
3134

3235
processor.signal_shutdown()
3336

3437

35-
def run_processor_with_signals(processor, quantized_rebalance_delay_secs: int | None = None):
38+
def run_processor_with_signals(
39+
processor: StreamProcessor[Any], quantized_rebalance_delay_secs: int | None = None
40+
) -> None:
3641
if quantized_rebalance_delay_secs:
3742
# delay startup for quantization
3843
delay_kafka_rebalance(quantized_rebalance_delay_secs)
3944

40-
def handler(signum, frame):
45+
def handler(signum: object, frame: object) -> None:
4146
# delay shutdown for quantization
4247
t = Thread(target=delay_shutdown, args=(processor, quantized_rebalance_delay_secs))
4348
t.start()

src/sentry/utils/math.py

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
1+
from __future__ import annotations
2+
13
import math
24
from abc import ABC, abstractmethod
35

46

5-
def mean(values):
6-
return sum(values) / len(values)
7-
8-
9-
def median(values):
10-
values = sorted(values)
11-
size = len(values)
12-
if size % 2 == 1:
13-
return values[int((size - 1) / 2)]
14-
return (values[int(size / 2 - 1)] + values[int(size / 2)]) / 2
15-
16-
17-
def nice_int(x):
7+
def nice_int(x: float) -> int:
188
"""
199
Round away from zero to the nearest "nice" number.
2010
"""

src/sentry/utils/memory.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
from __future__ import annotations
2+
13
import resource
4+
from collections.abc import Generator
25
from contextlib import contextmanager
6+
from typing import Any
37

48
from sentry.utils import metrics
59

610

7-
def get_rss_usage():
11+
def get_rss_usage() -> int:
812
return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss
913

1014

1115
@contextmanager
12-
def track_memory_usage(metric, **kwargs):
16+
def track_memory_usage(metric: str, **kwargs: Any) -> Generator[None]:
1317
before = get_rss_usage()
1418
try:
1519
yield

src/sentry/utils/metrics.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import functools
24
import logging
35
import time
@@ -6,7 +8,7 @@
68
from queue import Queue
79
from random import random
810
from threading import Thread
9-
from typing import Any, TypeVar
11+
from typing import TYPE_CHECKING, Any, TypeVar
1012

1113
import sentry_sdk
1214
from django.conf import settings
@@ -15,6 +17,9 @@
1517
from sentry.metrics.base import MetricsBackend, MutableTags, Tags
1618
from sentry.metrics.middleware import MiddlewareWrapper, add_global_tags, global_tags
1719

20+
if TYPE_CHECKING:
21+
from sentry.models.organization import Organization
22+
1823
metrics_skip_all_internal = settings.SENTRY_METRICS_SKIP_ALL_INTERNAL
1924
metrics_skip_internal_prefixes = tuple(settings.SENTRY_METRICS_SKIP_INTERNAL_PREFIXES)
2025

@@ -264,11 +269,11 @@ def event(
264269
def ensure_crash_rate_in_bounds(
265270
data: Any,
266271
request: Request,
267-
organization,
272+
organization: Organization,
268273
CRASH_RATE_METRIC_KEY: str,
269274
lower_bound: float = 0.0,
270275
upper_bound: float = 1.0,
271-
):
276+
) -> None:
272277
"""
273278
Ensures that crash rate metric will always have value in expected bounds, and
274279
that invalid value is never returned to the customer by replacing all the invalid values with

src/sentry/utils/projectflags.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
from __future__ import annotations
22

3+
from typing import Any
4+
35
from django.db.models import F
46
from django.dispatch import Signal
57

68
from sentry.models.project import Project
79

810

9-
def set_project_flag_and_signal(project: Project, flag_name: str, signal: Signal, **kwargs) -> bool:
11+
def set_project_flag_and_signal(
12+
project: Project, flag_name: str, signal: Signal, **kwargs: Any
13+
) -> bool:
1014
"""
1115
Helper function to set a project flag and send a signal.
1216
Returns True if the flag was set, False if it was already set.

src/sentry/utils/snuba_rpc.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ class MultiRpcResponse:
5959
timeseries_response: list[TimeSeriesResponse]
6060

6161

62-
def log_snuba_info(content):
62+
def log_snuba_info(content: str) -> None:
6363
if SNUBA_INFO_FILE:
6464
with open(SNUBA_INFO_FILE, "a") as file:
6565
file.writelines(content)

0 commit comments

Comments
 (0)