Browse Source

ref: require type ignore comments to include the error code (#67638)

automated with:

```python
import re

REG = re.compile(r'^([^:]+):([^:]+):.*consider "([^"]+)"')
REG2 = re.compile('type: ?ignore')

with open('mypy-output') as f:
    for line in f:
        match = REG.match(line)
        assert match is not None

        with open(match[1]) as srcf:
            lines = list(srcf)

        lineno = int(match[2]) - 1
        lines[lineno] = REG2.sub(match[3], lines[lineno])

        with open(match[1], 'w') as srcf_w:
            srcf_w.write(''.join(lines))
```

<!-- Describe your PR here. -->
anthony sottile 11 months ago
parent
commit
7a44b756da

+ 1 - 0
.pre-commit-config.yaml

@@ -94,6 +94,7 @@ repos:
     rev: v1.10.0
     hooks:
       - id: python-use-type-annotations
+      - id: python-check-blanket-type-ignore
 
   - repo: https://github.com/python-jsonschema/check-jsonschema
     rev: 0.24.1

+ 1 - 1
devenv/sync.py

@@ -5,7 +5,7 @@ import os
 import subprocess
 
 from devenv import constants
-from devenv.lib import venv  # type: ignore
+from devenv.lib import venv  # type: ignore[attr-defined]
 from devenv.lib import colima, config, limactl, proc, volta
 
 

+ 1 - 0
pyproject.toml

@@ -64,6 +64,7 @@ warn_unreachable = true
 warn_unused_configs = true
 warn_unused_ignores = true
 warn_redundant_casts = true
+enable_error_code = ["ignore-without-code"]
 
 [tool.django-stubs]
 django_settings_module = "sentry.conf.server_mypy"

+ 1 - 1
src/sentry/analytics/events/rule_snooze.py

@@ -15,7 +15,7 @@ class RuleSnoozeAction(analytics.Event):
 
 class RuleSnoozed(RuleSnoozeAction):
     type = "rule.snoozed"
-    attributes = RuleSnoozeAction.attributes + (analytics.Attribute("until", required=False),)  # type: ignore
+    attributes = RuleSnoozeAction.attributes + (analytics.Attribute("until", required=False),)  # type: ignore[assignment]
 
 
 class RuleUnSnoozed(RuleSnoozeAction):

+ 10 - 10
src/sentry/api/bases/organization.py

@@ -57,7 +57,7 @@ class OrganizationPermission(SentryPermission):
         if not organization.flags.require_2fa:
             return False
 
-        if request.user.has_2fa():  # type: ignore
+        if request.user.has_2fa():  # type: ignore[union-attr]
             return False
 
         if is_active_superuser(request):
@@ -268,7 +268,7 @@ class ControlSiloOrganizationEndpoint(Endpoint):
         kwargs["organization"] = organization_context.organization
 
         # Used for API access logs
-        request._request.organization = organization_context.organization  # type: ignore
+        request._request.organization = organization_context.organization  # type: ignore[attr-defined]
 
         return (args, kwargs)
 
@@ -536,7 +536,7 @@ class OrganizationEndpoint(Endpoint):
 
         bind_organization_context(organization)
 
-        request._request.organization = organization  # type: ignore
+        request._request.organization = organization  # type: ignore[attr-defined]
 
         # Track the 'active' organization when the request came from
         # a cookie based agent (react app)
@@ -566,18 +566,18 @@ class OrganizationReleasesBaseEndpoint(OrganizationEndpoint):
         """
         has_valid_api_key = False
         if is_api_key_auth(request.auth):
-            if request.auth.organization_id != organization.id:  # type: ignore
+            if request.auth.organization_id != organization.id:  # type: ignore[union-attr]
                 return []
-            has_valid_api_key = request.auth.has_scope(  # type: ignore
+            has_valid_api_key = request.auth.has_scope(  # type: ignore[union-attr]
                 "project:releases"
-            ) or request.auth.has_scope(  # type: ignore
+            ) or request.auth.has_scope(  # type: ignore[union-attr]
                 "project:write"
             )
 
         if is_org_auth_token_auth(request.auth):
-            if request.auth.organization_id != organization.id:  # type: ignore
+            if request.auth.organization_id != organization.id:  # type: ignore[union-attr]
                 return []
-            has_valid_api_key = request.auth.has_scope("org:ci")  # type: ignore
+            has_valid_api_key = request.auth.has_scope("org:ci")  # type: ignore[union-attr]
 
         if not (
             has_valid_api_key or (getattr(request, "user", None) and request.user.is_authenticated)
@@ -614,9 +614,9 @@ class OrganizationReleasesBaseEndpoint(OrganizationEndpoint):
         if getattr(request, "user", None) and request.user.id:
             actor_id = "user:%s" % request.user.id
         if getattr(request, "auth", None) and getattr(request.auth, "id", None):
-            actor_id = "apikey:%s" % request.auth.id  # type: ignore
+            actor_id = "apikey:%s" % request.auth.id  # type: ignore[union-attr]
         elif getattr(request, "auth", None) and getattr(request.auth, "entity_id", None):
-            actor_id = "apikey:%s" % request.auth.entity_id  # type: ignore
+            actor_id = "apikey:%s" % request.auth.entity_id  # type: ignore[union-attr]
         if actor_id is not None:
             requested_project_ids = project_ids
             if requested_project_ids is None:

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

@@ -53,7 +53,7 @@ class OrganizationDeriveCodeMappingsEndpoint(OrganizationEndpoint):
             )
 
         # This method is specific to the GithubIntegration
-        trees = installation.get_trees_for_org()  # type: ignore
+        trees = installation.get_trees_for_org()  # type: ignore[attr-defined]
         trees_helper = CodeMappingTreesHelper(trees)
         possible_code_mappings: list[dict[str, str]] = []
         resp_status: int = status.HTTP_204_NO_CONTENT

+ 2 - 2
src/sentry/api/endpoints/organization_events_trends_v2.py

@@ -136,7 +136,7 @@ class OrganizationEventsNewTrendsStatsEndpoint(OrganizationEventsV2EndpointBase)
             # keep only projects that top events belong to to reduce query cardinality
             used_project_ids = list({event["project"] for event in data})
 
-            request.GET.projectSlugs = used_project_ids  # type: ignore
+            request.GET.projectSlugs = used_project_ids  # type: ignore[attr-defined]
 
             # Get new params with pruned projects
             pruned_params = self.get_snuba_params(request, organization)
@@ -164,7 +164,7 @@ class OrganizationEventsNewTrendsStatsEndpoint(OrganizationEventsV2EndpointBase)
                     "project_id": item["project_id"],
                 }
 
-            for row in result.get("data", []):  # type: ignore
+            for row in result.get("data", []):  # type: ignore[union-attr]
                 result_key = create_result_key(row, translated_groupby, {})
                 if result_key in results:
                     results[result_key]["data"].append(row)

+ 2 - 2
src/sentry/api/endpoints/release_deploys.py

@@ -128,9 +128,9 @@ class ReleaseDeploysEndpoint(OrganizationReleasesBaseEndpoint):
             if getattr(request, "user", None) and request.user.id:
                 auth = f"user.id: {request.user.id}"
             elif getattr(request, "auth", None) and getattr(request.auth, "id", None):
-                auth = f"auth.id: {request.auth.id}"  # type: ignore
+                auth = f"auth.id: {request.auth.id}"  # type: ignore[union-attr]
             elif getattr(request, "auth", None) and getattr(request.auth, "entity_id", None):
-                auth = f"auth.entity_id: {request.auth.entity_id}"  # type: ignore
+                auth = f"auth.entity_id: {request.auth.entity_id}"  # type: ignore[union-attr]
             if auth is not None:
                 logging_info.update({"auth": auth})
                 logger.info(

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

@@ -112,7 +112,7 @@ class SeerRpcServiceEndpoint(Endpoint):
             raise RpcResolutionException(f"Unknown method {method_name}")
         # As seer is a single service, we just directly expose the methods instead of services.
         method = seer_method_registry[method_name]
-        return method(**arguments)  # type: ignore
+        return method(**arguments)  # type: ignore[operator]
 
     def post(self, request: Request, method_name: str) -> Response:
         if not self._is_authorized(request):

+ 2 - 2
src/sentry/api/endpoints/source_map_debug_blue_thunder_edition.py

@@ -342,8 +342,8 @@ class ReleaseLookupData:
             "found", "wrong-dist", "unsuccessful"
         ] = "unsuccessful"
 
-        if self.source_map_reference is not None and self.found_source_file_name is not None:  # type: ignore
-            if self.source_map_reference.startswith("data:"):  # type: ignore
+        if self.source_map_reference is not None and self.found_source_file_name is not None:  # type: ignore[unreachable]
+            if self.source_map_reference.startswith("data:"):  # type: ignore[unreachable]
                 self.source_map_reference = "Inline Sourcemap"
                 self.source_map_lookup_result = "found"
             else:

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