Browse Source

chore(typing): Set 8 (#68507)

Armen Zambrano G 11 months ago
parent
commit
2dd164fd95
2 changed files with 64 additions and 32 deletions
  1. 1 0
      pyproject.toml
  2. 63 32
      src/sentry/api/helpers/source_map_helper.py

+ 1 - 0
pyproject.toml

@@ -589,6 +589,7 @@ disable_error_code = [
 [[tool.mypy.overrides]]
 module = [
     "sentry.api.endpoints.issues.*",
+    "sentry.api.helpers.source_map_helper",
     "sentry.buffer.base",
     "sentry.buffer.redis",
     "sentry.eventstore.reprocessing.redis",

+ 63 - 32
src/sentry/api/helpers/source_map_helper.py

@@ -1,4 +1,6 @@
-from urllib.parse import urlparse
+from collections.abc import Mapping
+from typing import Any
+from urllib.parse import ParseResult, ParseResultBytes, urlparse
 
 from django.utils.encoding import force_bytes, force_str
 from packaging.version import Version
@@ -6,7 +8,11 @@ from rest_framework.exceptions import NotFound, ParseError
 
 from sentry import eventstore
 from sentry.api.endpoints.project_release_files import ArtifactSource
+from sentry.eventstore.models import BaseEvent
+from sentry.interfaces.exception import Exception as ExceptionInterface
+from sentry.interfaces.stacktrace import Frame
 from sentry.models.distribution import Distribution
+from sentry.models.project import Project
 from sentry.models.release import Release
 from sentry.models.releasefile import ReleaseFile, read_artifact_index
 from sentry.models.sourcemapprocessingissue import SourceMapProcessingIssue
@@ -23,7 +29,25 @@ NO_DEBUG_ID_FRAMEWORKS = {
 }
 
 
-def source_map_debug(project, event_id, exception_idx, frame_idx):
+class SourceMapDebug:
+    def __init__(self, issue: str | None = None, data: Mapping[str, Any] | None = None) -> None:
+        self.issue = issue
+        self.data = data
+
+
+class SourceMapException(Exception):
+    def __init__(self, issue: str, data: Mapping[str, Any] | None = None) -> None:
+        super().__init__(issue, data)
+        self.issue = issue
+        self.data = data
+
+
+def source_map_debug(
+    project: Project,
+    event_id: int,
+    exception_idx: int,
+    frame_idx: int,
+) -> SourceMapDebug:
     event = eventstore.backend.get_event_by_id(project.id, event_id)
     if event is None:
         raise NotFound(detail="Event not found")
@@ -126,7 +150,9 @@ def source_map_debug(project, event_id, exception_idx, frame_idx):
     return SourceMapDebug()
 
 
-def _get_frame_filename_and_path(exception, frame_idx):
+def _get_frame_filename_and_path(
+    exception: ExceptionInterface, frame_idx: int
+) -> tuple[Frame, str, str]:
     frame_list = exception.stacktrace.frames
     try:
         frame = frame_list[frame_idx]
@@ -137,7 +163,14 @@ def _get_frame_filename_and_path(exception, frame_idx):
     return frame, filename, abs_path
 
 
-def _find_matches(release_artifacts, abs_path, unified_path, filename, release, event):
+def _find_matches(
+    release_artifacts: list[ReleaseFile],
+    abs_path: str | None,
+    unified_path: str,
+    filename: str,
+    release: Release,
+    event: BaseEvent,
+) -> tuple[list[ReleaseFile], list[ReleaseFile]]:
     full_matches = [
         artifact
         for artifact in release_artifacts
@@ -148,7 +181,7 @@ def _find_matches(release_artifacts, abs_path, unified_path, filename, release,
     return full_matches, partial_matches
 
 
-def _find_partial_matches(unified_path, artifacts):
+def _find_partial_matches(unified_path: str, artifacts: list[ReleaseFile]) -> list[ReleaseFile]:
     filename = unified_path.split("/")[-1]
     filename_matches = [
         artifact for artifact in artifacts if artifact.name.split("/")[-1] == filename
@@ -162,7 +195,7 @@ def _find_partial_matches(unified_path, artifacts):
     return []
 
 
-def _extract_release(event, project):
+def _extract_release(event: BaseEvent, project: Project) -> Release:
     release_version = event.get_tag("sentry:release")
 
     if not release_version:
@@ -170,7 +203,9 @@ def _extract_release(event, project):
     return Release.objects.get(organization=project.organization, version=release_version)
 
 
-def _verify_dist_matches(release, event, artifact, filename):
+def _verify_dist_matches(
+    release: Release, event: BaseEvent, artifact: ReleaseFile, filename: str
+) -> bool:
     try:
         if event.dist is None and artifact.dist_id is None:
             return True
@@ -188,7 +223,14 @@ def _verify_dist_matches(release, event, artifact, filename):
     return True
 
 
-def _find_matching_artifact(release_artifacts, urlparts, abs_path, filename, release, event):
+def _find_matching_artifact(
+    release_artifacts: list[ReleaseFile],
+    urlparts: ParseResult | ParseResultBytes,
+    abs_path: str | None,
+    filename: str,
+    release: Release,
+    event: BaseEvent,
+) -> ReleaseFile:
     unified_path = _unify_url(urlparts)
     full_matches, partial_matches = _find_matches(
         release_artifacts, abs_path, unified_path, filename, release, event
@@ -225,7 +267,7 @@ def _find_matching_artifact(release_artifacts, urlparts, abs_path, filename, rel
     return full_matches[0]
 
 
-def _discover_sourcemap_url(artifact, filename):
+def _discover_sourcemap_url(artifact: ReleaseFile, filename: str) -> str | None:
     file = artifact.file
     # Code adapted from sentry/lang/javascript/processor.py
     sourcemap_header = file.headers.get("Sourcemap", file.headers.get("X-SourceMap"))
@@ -240,11 +282,11 @@ def _discover_sourcemap_url(artifact, filename):
     return force_str(sourcemap) if sourcemap is not None else None
 
 
-def _unify_url(urlparts):
-    return "~" + urlparts.path
+def _unify_url(urlparts: ParseResult | ParseResultBytes) -> str:
+    return "~" + str(urlparts.path)
 
 
-def _get_releasefiles(release, organization_id):
+def _get_releasefiles(release: Release, organization_id: int) -> list[ReleaseFile]:
     data_sources = []
 
     file_list = ReleaseFile.public_objects.filter(release_id=release.id).exclude(artifact_count=0)
@@ -267,7 +309,7 @@ def _get_releasefiles(release, organization_id):
     return data_sources
 
 
-def _find_url_prefix(filepath, artifact_name):
+def _find_url_prefix(filepath_str: str, artifact_name_str: str) -> str | None:
     # Right now, we only support 3 cases for finding the url prefix:
     # 1. If the file name is a suffix of the artifact name, return the missing prefix
     # Example : "/static/app.js" and "~/dist/static/app/js"
@@ -275,13 +317,13 @@ def _find_url_prefix(filepath, artifact_name):
     # Example : "~/dist/static/header/app.js" and "~/dist/static/footer/app.js"
     # 3. If there is only 1 difference that needs to be added to make the file name and artifact name match
     # Example : "~/dist/app.js" and "~/dist/static/header/app.js"
-    idx = artifact_name.find(filepath)
+    idx = artifact_name_str.find(filepath_str)
     # If file name is suffix of artifact name, return the missing prefix
     if idx != -1:
-        return artifact_name[:idx]
+        return artifact_name_str[:idx]
 
-    filepath = filepath.split("/")
-    artifact_name = artifact_name.split("/")
+    filepath = filepath_str.split("/")
+    artifact_name = artifact_name_str.split("/")
     if len(filepath) == len(artifact_name):
         matches = [filepath[i] != artifact_name[i] for i in range(len(filepath))]
         if sum(matches) == 1:
@@ -290,22 +332,11 @@ def _find_url_prefix(filepath, artifact_name):
 
     if len(filepath) + 1 == len(artifact_name):
         # If not suffix, find the missing parts and return them
-        filepath = set(filepath)
-        artifact_name = set(artifact_name)
+        filepath_set = set(filepath)
+        artifact_name_set = set(artifact_name)
 
-        differences = list(filepath.symmetric_difference(artifact_name))
+        differences = list(filepath_set.symmetric_difference(artifact_name_set))
         if len(differences) == 1:
             return "/".join(differences + [""])
 
-
-class SourceMapException(Exception):
-    def __init__(self, issue, data=None):
-        super().__init__(issue, data)
-        self.issue = issue
-        self.data = data
-
-
-class SourceMapDebug:
-    def __init__(self, issue=None, data=None):
-        self.issue = issue
-        self.data = data
+    return None