Browse Source

ref: fix typing in IPlugin2 (#51427)

<!-- Describe your PR here. -->
anthony sottile 1 year ago
parent
commit
dc67683a9b

+ 0 - 8
pyproject.toml

@@ -828,8 +828,6 @@ module = [
     "sentry.plugins.base.bindings",
     "sentry.plugins.base.notifier",
     "sentry.plugins.base.urls",
-    "sentry.plugins.base.v1",
-    "sentry.plugins.base.v2",
     "sentry.plugins.bases.data_forwarding",
     "sentry.plugins.bases.issue",
     "sentry.plugins.bases.issue2",
@@ -845,7 +843,6 @@ module = [
     "sentry.plugins.sentry_urls.models",
     "sentry.plugins.sentry_useragents.models",
     "sentry.plugins.sentry_webhooks.plugin",
-    "sentry.plugins.utils",
     "sentry.plugins.validators.url",
     "sentry.profiles.task",
     "sentry.profiles.utils",
@@ -855,7 +852,6 @@ module = [
     "sentry.quotas.redis",
     "sentry.ratelimits.utils",
     "sentry.receivers.core",
-    "sentry.receivers.features",
     "sentry.receivers.onboarding",
     "sentry.receivers.outbox",
     "sentry.receivers.outbox.control",
@@ -1181,7 +1177,6 @@ module = [
     "sentry_plugins.heroku.plugin",
     "sentry_plugins.jira.client",
     "sentry_plugins.jira.plugin",
-    "sentry_plugins.opsgenie.plugin",
     "sentry_plugins.pivotal.plugin",
     "sentry_plugins.pushover.plugin",
     "sentry_plugins.redmine.forms",
@@ -1542,10 +1537,8 @@ module = [
     "tests.sentry.options.test_store",
     "tests.sentry.ownership.test_grammar",
     "tests.sentry.pipeline.test_pipeline",
-    "tests.sentry.plugins.bases.test_issue",
     "tests.sentry.plugins.bases.test_issue2",
     "tests.sentry.plugins.bases.test_notify",
-    "tests.sentry.plugins.test_config",
     "tests.sentry.processing.realtime_metrics.test_redis",
     "tests.sentry.profiles.consumers.test_process",
     "tests.sentry.profiles.test_task",
@@ -1554,7 +1547,6 @@ module = [
     "tests.sentry.ratelimits.test_redis",
     "tests.sentry.ratelimits.utils.test_get_rate_limit_value",
     "tests.sentry.ratelimits.utils.test_get_ratelimit_key",
-    "tests.sentry.receivers.test_featureadoption",
     "tests.sentry.receivers.test_onboarding",
     "tests.sentry.receivers.test_releases",
     "tests.sentry.relay.test_config",

+ 1 - 1
src/sentry/api/endpoints/group_details.py

@@ -28,7 +28,7 @@ from sentry.models import Activity, Group, GroupSeen, GroupSubscriptionManager,
 from sentry.models.groupinbox import get_inbox_details
 from sentry.models.groupowner import get_owner_details
 from sentry.plugins.base import plugins
-from sentry.plugins.bases import IssueTrackingPlugin2
+from sentry.plugins.bases.issue2 import IssueTrackingPlugin2
 from sentry.services.hybrid_cloud.user.service import user_service
 from sentry.types.ratelimit import RateLimit, RateLimitCategory
 from sentry.utils import metrics

+ 3 - 3
src/sentry/plugins/base/v1.py

@@ -26,7 +26,7 @@ if TYPE_CHECKING:
 
 class PluginMount(type):
     def __new__(cls, name, bases, attrs):
-        new_cls = type.__new__(cls, name, bases, attrs)
+        new_cls: type[IPlugin] = type.__new__(cls, name, bases, attrs)  # type: ignore[assignment]
         if IPlugin in bases:
             return new_cls
         if not hasattr(new_cls, "title"):
@@ -65,7 +65,7 @@ class IPlugin(local, PluggableViewMixin, PluginConfigMixin, PluginStatusMixin):
     version: str | None = None
     author: str | None = None
     author_url: str | None = None
-    resource_links: list[tuple[str, str]] = ()
+    resource_links: list[tuple[str, str]] = []
     feature_descriptions: Sequence[Any] = []
 
     # Configuration specifics
@@ -276,7 +276,7 @@ class IPlugin(local, PluggableViewMixin, PluginConfigMixin, PluginStatusMixin):
 
     # The following methods are specific to web requests
 
-    def get_title(self) -> str:
+    def get_title(self) -> str | _StrPromise:
         """
         Returns the general title for this plugin.
 

+ 23 - 16
src/sentry/plugins/base/v2.py

@@ -1,7 +1,8 @@
-__all__ = ("Plugin2",)
+from __future__ import annotations
 
 import logging
 from threading import local
+from typing import TYPE_CHECKING, Any, Sequence
 
 from django.http import HttpResponseRedirect
 
@@ -12,15 +13,18 @@ from sentry.plugins.config import PluginConfigMixin
 from sentry.plugins.status import PluginStatusMixin
 from sentry.utils.hashlib import md5_text
 
+if TYPE_CHECKING:
+    from django.utils.functional import _StrPromise
+
 
 class PluginMount(type):
     def __new__(cls, name, bases, attrs):
-        new_cls = type.__new__(cls, name, bases, attrs)
+        new_cls: type[IPlugin2] = type.__new__(cls, name, bases, attrs)  # type: ignore[assignment]
         if IPlugin2 in bases:
             return new_cls
-        if new_cls.title is None:
+        if not hasattr(new_cls, "title"):
             new_cls.title = new_cls.__name__
-        if not new_cls.slug:
+        if not hasattr(new_cls, "slug"):
             new_cls.slug = new_cls.title.replace(" ", "-").lower()
         if not hasattr(new_cls, "logger"):
             new_cls.logger = logging.getLogger(f"sentry.plugins.{new_cls.slug}")
@@ -46,20 +50,20 @@ class IPlugin2(local, PluginConfigMixin, PluginStatusMixin):
     """
 
     # Generic plugin information
-    title = None
-    slug = None
-    description = None
-    version = None
-    author = None
-    author_url = None
-    resource_links = ()
-    feature_descriptions = []
+    title: str | _StrPromise
+    slug: str
+    description: str | None = None
+    version: str | None = None
+    author: str | None = None
+    author_url: str | None = None
+    resource_links: list[tuple[str, str]] = []
+    feature_descriptions: Sequence[Any] = []
 
     # Configuration specifics
-    conf_key = None
-    conf_title = None
+    conf_key: str | None = None
+    conf_title: str | _StrPromise | None = None
 
-    project_conf_form = None
+    project_conf_form: Any = None
     project_conf_template = "sentry/plugins/project_configuration.html"
 
     # Global enabled state
@@ -70,7 +74,7 @@ class IPlugin2(local, PluginConfigMixin, PluginStatusMixin):
     project_default_enabled = False
 
     # used by queries to determine if the plugin is configured
-    required_field = None
+    required_field: str | None = None
 
     def _get_option_key(self, key):
         return f"{self.get_conf_key()}:{key}"
@@ -455,3 +459,6 @@ class Plugin2(IPlugin2, metaclass=PluginMount):
     """
 
     __version__ = 2
+
+
+__all__ = ("Plugin2",)

+ 3 - 1
src/sentry/plugins/bases/issue.py

@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 from django import forms
 from django.conf import settings
 from django.utils.html import format_html
@@ -26,7 +28,7 @@ class IssueTrackingPlugin(Plugin):
     create_issue_template = "sentry/plugins/bases/issue/create_issue.html"
     not_configured_template = "sentry/plugins/bases/issue/not_configured.html"
     needs_auth_template = "sentry/plugins/bases/issue/needs_auth.html"
-    auth_provider = None
+    auth_provider: str | None = None
     can_unlink_issues = False
     can_link_existing_issues = False
 

+ 4 - 2
src/sentry/plugins/bases/issue2.py

@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 from django.conf import settings
 from django.conf.urls import url
 from django.urls import reverse
@@ -35,13 +37,13 @@ class IssueGroupActionEndpoint(PluginGroupEndpoint):
 
 
 class IssueTrackingPlugin2(Plugin):
-    auth_provider = None
+    auth_provider: str | None = None
 
     allowed_actions = ("create", "link", "unlink")
 
     # we default this to None to support legacy integrations, but newer style
     # should explicitly call out what is stored
-    issue_fields = None
+    issue_fields: frozenset[str] | None = None
     # issue_fields = frozenset(['id', 'title', 'url'])
 
     def configure(self, project, request):

+ 6 - 2
src/sentry/plugins/providers/base.py

@@ -1,3 +1,7 @@
+from __future__ import annotations
+
+import logging
+
 from django.urls import reverse
 from rest_framework.response import Response
 
@@ -8,8 +12,8 @@ from social_auth.models import UserSocialAuth
 
 
 class ProviderMixin:
-    auth_provider = None
-    logger = None
+    auth_provider: str | None = None
+    logger: logging.Logger | None = None
 
     def link_auth(self, user, organization, data):
         try:

+ 1 - 1
src/sentry/plugins/utils.py

@@ -1,5 +1,5 @@
 from sentry.integrations import FeatureDescription, IntegrationFeatures
-from sentry.plugins.bases import IssueTrackingPlugin2
+from sentry.plugins.bases.issue2 import IssueTrackingPlugin2
 
 
 class TestIssuePlugin2(IssueTrackingPlugin2):

+ 2 - 1
src/sentry/receivers/features.py

@@ -5,7 +5,8 @@ from django.db.models.signals import post_save
 from sentry import analytics
 from sentry.adoption import manager
 from sentry.models import FeatureAdoption, GroupTombstone, Organization
-from sentry.plugins.bases import IssueTrackingPlugin, IssueTrackingPlugin2
+from sentry.plugins.bases.issue import IssueTrackingPlugin
+from sentry.plugins.bases.issue2 import IssueTrackingPlugin2
 from sentry.plugins.bases.notify import NotificationPlugin
 from sentry.receivers.rules import DEFAULT_RULE_DATA, DEFAULT_RULE_LABEL
 from sentry.signals import (

+ 2 - 1
src/sentry/receivers/onboarding.py

@@ -15,7 +15,8 @@ from sentry.models import (
     Project,
 )
 from sentry.onboarding_tasks import try_mark_onboarding_complete
-from sentry.plugins.bases import IssueTrackingPlugin, IssueTrackingPlugin2
+from sentry.plugins.bases.issue import IssueTrackingPlugin
+from sentry.plugins.bases.issue2 import IssueTrackingPlugin2
 from sentry.services.hybrid_cloud.organization import RpcOrganization
 from sentry.services.hybrid_cloud.user import RpcUser
 from sentry.signals import (

Some files were not shown because too many files changed in this diff