Browse Source

ref: fix typing for sentry.rules.actions.notify_event_service (#72121)

<!-- Describe your PR here. -->
anthony sottile 9 months ago
parent
commit
8993b72a58
3 changed files with 16 additions and 8 deletions
  1. 0 1
      pyproject.toml
  2. 6 6
      src/sentry/rules/actions/notify_event_service.py
  3. 10 1
      src/sentry/utils/forms.py

+ 0 - 1
pyproject.toml

@@ -378,7 +378,6 @@ module = [
     "sentry.rules.actions.integrations.base",
     "sentry.rules.actions.integrations.create_ticket.form",
     "sentry.rules.actions.integrations.create_ticket.utils",
-    "sentry.rules.actions.notify_event_service",
     "sentry.rules.filters.assigned_to",
     "sentry.rules.history.preview",
     "sentry.scim.endpoints.members",

+ 6 - 6
src/sentry/rules/actions/notify_event_service.py

@@ -22,6 +22,7 @@ from sentry.services.hybrid_cloud.integration import integration_service
 from sentry.services.hybrid_cloud.organization.serial import serialize_rpc_organization
 from sentry.tasks.sentry_apps import notify_sentry_app
 from sentry.utils import json, metrics
+from sentry.utils.forms import set_field_choices, set_widget_choices
 
 logger = logging.getLogger("sentry.integrations.sentry_app")
 PLUGINS_WITH_FIRST_PARTY_EQUIVALENTS = ["PagerDuty", "Slack", "Opsgenie"]
@@ -30,7 +31,7 @@ PLUGINS_WITH_FIRST_PARTY_EQUIVALENTS = ["PagerDuty", "Slack", "Opsgenie"]
 def build_incident_attachment(
     incident: Incident,
     new_status: IncidentStatus,
-    metric_value: int | None = None,
+    metric_value: float | None = None,
     notification_uuid: str | None = None,
 ) -> dict[str, str]:
     from sentry.api.serializers.rest_framework.base import (
@@ -111,8 +112,8 @@ class NotifyEventServiceForm(forms.Form):
 
         super().__init__(*args, **kwargs)
 
-        self.fields["service"].choices = service_choices
-        self.fields["service"].widget.choices = self.fields["service"].choices
+        set_field_choices(self.fields["service"], service_choices)
+        set_widget_choices(self.fields["service"].widget, service_choices)
 
 
 class NotifyEventServiceAction(EventAction):
@@ -142,7 +143,7 @@ class NotifyEventServiceAction(EventAction):
     ) -> Generator[CallbackFuture, None, None]:
         service = self.get_option("service")
 
-        extra = {"event_id": event.event_id}
+        extra: dict[str, object] = {"event_id": event.event_id}
         if not service:
             self.logger.info("rules.fail.is_configured", extra=extra)
             return
@@ -151,9 +152,8 @@ class NotifyEventServiceAction(EventAction):
         app = app_service.get_sentry_app_by_slug(slug=service)
 
         if app:
-            kwargs = {"sentry_app": app}
             metrics.incr("notifications.sent", instance=app.slug, skip_internal=False)
-            yield self.future(notify_sentry_app, **kwargs)
+            yield self.future(notify_sentry_app, sentry_app=app)
 
         try:
             plugin = plugins.get(service)

+ 10 - 1
src/sentry/utils/forms.py

@@ -1,6 +1,8 @@
 from collections.abc import Sequence
 
 from django import forms
+from django.forms import ChoiceField
+from django.forms.widgets import ChoiceWidget
 
 
 def field_to_config(name, field):
@@ -43,6 +45,13 @@ def form_to_config(form):
 
 def set_field_choices(field: forms.Field, choices: Sequence[tuple[object, object]]) -> None:
     """workaround for typeddjango/django-stubs#1514"""
-    if not isinstance(field, forms.ChoiceField):
+    if not isinstance(field, ChoiceField):
         raise TypeError(f"expected ChoiceField, got {field!r}")
     field.choices = choices
+
+
+def set_widget_choices(widget: forms.Widget, choices: Sequence[tuple[object, object]]) -> None:
+    """workaround for typeddjango/django-stubs#1514"""
+    if not isinstance(widget, ChoiceWidget):
+        raise TypeError(f"expected ChoiceWidget, got {widget!r}")
+    widget.choices = choices