Skip to content

Commit

Permalink
Improve typing of LanguageProcessors
Browse files Browse the repository at this point in the history
This adds a lot of missing type annotations.

It also adds tracing to all the processors, and avoids a duplicated call to `remove_non_ascii`.
  • Loading branch information
Swatinem committed Aug 30, 2024
1 parent 26de857 commit b5b01e4
Show file tree
Hide file tree
Showing 32 changed files with 330 additions and 361 deletions.
29 changes: 0 additions & 29 deletions services/report/languages/__init__.py
Original file line number Diff line number Diff line change
@@ -1,29 +0,0 @@
# ruff: noqa: F401
from services.report.languages.bullseye import BullseyeProcessor
from services.report.languages.clover import CloverProcessor
from services.report.languages.cobertura import CoberturaProcessor
from services.report.languages.coveralls import CoverallsProcessor
from services.report.languages.csharp import CSharpProcessor
from services.report.languages.dlst import DLSTProcessor
from services.report.languages.elm import ElmProcessor
from services.report.languages.flowcover import FlowcoverProcessor
from services.report.languages.gap import GapProcessor
from services.report.languages.gcov import GcovProcessor
from services.report.languages.go import GoProcessor
from services.report.languages.jacoco import JacocoProcessor
from services.report.languages.jetbrainsxml import JetBrainsXMLProcessor
from services.report.languages.lcov import LcovProcessor
from services.report.languages.lua import LuaProcessor
from services.report.languages.mono import MonoProcessor
from services.report.languages.node import NodeProcessor
from services.report.languages.pycoverage import PyCoverageProcessor
from services.report.languages.rlang import RlangProcessor
from services.report.languages.salesforce import SalesforceProcessor
from services.report.languages.scala import ScalaProcessor
from services.report.languages.scoverage import SCoverageProcessor
from services.report.languages.simplecov import SimplecovProcessor
from services.report.languages.v1 import VOneProcessor
from services.report.languages.vb import VbProcessor
from services.report.languages.vb2 import VbTwoProcessor
from services.report.languages.xcode import XCodeProcessor
from services.report.languages.xcodeplist import XCodePlistProcessor
13 changes: 1 addition & 12 deletions services/report/languages/base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import typing
from typing import Any

from shared.reports.resources import Report
Expand All @@ -7,10 +6,6 @@


class BaseLanguageProcessor(object):
@property
def name(self):
return self.get_processor_name()

def __init__(self, *args, **kwargs) -> None:
pass

Expand All @@ -37,9 +32,7 @@ def matches_content(self, content: Any, first_line: str, name: str) -> bool:
"""
pass

def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
) -> Report:
def process(self, name: str, content: Any, report_builder: ReportBuilder) -> Report:
"""Processes a report uploaded by the user, returning a `Report`
This is the base function which we need to implement
Expand All @@ -61,7 +54,3 @@ def process(
ReportExpiredException: If the report is considered expired
"""
pass

@classmethod
def get_processor_name(cls) -> str:
return cls.__name__
10 changes: 5 additions & 5 deletions services/report/languages/bullseye.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typing
from xml.etree.ElementTree import Element

import sentry_sdk
from shared.reports.resources import Report
from timestring import Date

Expand All @@ -18,17 +18,17 @@ class BullseyeProcessor(BaseLanguageProcessor):
def matches_content(self, content: Element, first_line: str, name: str) -> bool:
return "BullseyeCoverage" in content.tag

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: Element, report_builder: ReportBuilder
) -> Report:
return from_xml(content, report_builder.create_report_builder_session(name))


def from_xml(xml, report_builder_session: ReportBuilderSession):
path_fixer, ignored_lines, sessionid, yaml = (
def from_xml(xml: Element, report_builder_session: ReportBuilderSession):
path_fixer, ignored_lines, yaml = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
report_builder_session.sessionid,
report_builder_session.current_yaml,
)
if read_yaml_field(yaml, ("codecov", "max_report_age"), "12h ago"):
Expand Down
15 changes: 8 additions & 7 deletions services/report/languages/clover.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import typing
from xml.etree.ElementTree import Element

import sentry_sdk
from shared.reports.resources import Report
from timestring import Date

Expand All @@ -14,11 +15,12 @@


class CloverProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
return bool(content.tag == "coverage" and content.attrib.get("generated"))
def matches_content(self, content: Element, first_line: str, name: str) -> bool:
return content.tag == "coverage" and "generated" in content.attrib

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: Element, report_builder: ReportBuilder
) -> Report:
report_builder_session = report_builder.create_report_builder_session(name)
return from_xml(content, report_builder_session)
Expand All @@ -38,11 +40,10 @@ def get_end_of_file(filename, xmlfile):
pass


def from_xml(xml, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, sessionid, yaml = (
def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, yaml = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
report_builder_session.sessionid,
report_builder_session.current_yaml,
)

Expand Down
17 changes: 8 additions & 9 deletions services/report/languages/cobertura.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
import re
import typing
from typing import List
from xml.etree.ElementTree import Element

import sentry_sdk
from shared.reports.resources import Report
from timestring import Date, TimestringInvalid

Expand All @@ -19,13 +20,12 @@


class CoberturaProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
if bool(list(content.iter("coverage"))):
return True
return bool(list(content.iter("scoverage")))
def matches_content(self, content: Element, first_line: str, name: str) -> bool:
return next(content.iter("coverage")) or next(content.iter("scoverage"))

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: Element, report_builder: ReportBuilder
) -> Report:
report_builder_session = report_builder.create_report_builder_session(name)
return from_xml(content, report_builder_session)
Expand All @@ -43,11 +43,10 @@ def get_sources_to_attempt(xml) -> List[str]:
return [s for s in sources if isinstance(s, str) and s.startswith("/")]


def from_xml(xml, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, sessionid, repo_yaml = (
def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, repo_yaml = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
report_builder_session.sessionid,
report_builder_session.current_yaml,
)

Expand Down
20 changes: 7 additions & 13 deletions services/report/languages/coveralls.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import typing

import sentry_sdk
from shared.reports.resources import Report

from services.report.languages.base import BaseLanguageProcessor
Expand All @@ -11,26 +10,21 @@


class CoverallsProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
return detect(content)
def matches_content(self, content: dict, first_line: str, name: str) -> bool:
return "source_files" in content

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: dict, report_builder: ReportBuilder
) -> Report:
return from_json(content, report_builder.create_report_builder_session(name))


def detect(report):
return "source_files" in report


def from_json(report, report_builder_session: ReportBuilderSession) -> Report:
def from_json(report: dict, report_builder_session: ReportBuilderSession) -> Report:
# https://github.com/codecov/support/issues/253
path_fixer, ignored_lines, sessionid, repo_yaml = (
path_fixer, ignored_lines = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
report_builder_session.sessionid,
report_builder_session.current_yaml,
)
for _file in report["source_files"]:
filename = path_fixer(_file["name"])
Expand Down
19 changes: 9 additions & 10 deletions services/report/languages/csharp.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import typing
from collections import defaultdict
from itertools import repeat
from xml.etree.ElementTree import Element

import sentry_sdk
from shared.reports.resources import Report

from services.report.languages.base import BaseLanguageProcessor
Expand All @@ -13,11 +14,12 @@


class CSharpProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
return bool(content.tag == "CoverageSession")
def matches_content(self, content: Element, first_line: str, name: str) -> bool:
return content.tag == "CoverageSession"

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: Element, report_builder: ReportBuilder
) -> Report:
report_builder_session = report_builder.create_report_builder_session(name)
return from_xml(content, report_builder_session)
Expand All @@ -38,7 +40,7 @@ def _build_branches(branch_gen):
return branches


def from_xml(xml, report_builder_session: ReportBuilderSession) -> Report:
def from_xml(xml: Element, report_builder_session: ReportBuilderSession) -> Report:
"""
https://github.com/OpenCover/opencover/issues/293#issuecomment-94598145
@sl - start line
Expand All @@ -50,13 +52,10 @@ def from_xml(xml, report_builder_session: ReportBuilderSession) -> Report:
@vc - statement executed
<SequencePoint vc="2" uspid="3" ordinal="0" offset="0" sl="35" sc="8" el="35" ec="9" bec="0" bev="0" fileid="1" />
"""
ignored_lines, sessionid = (
report_builder_session.ignored_lines,
report_builder_session.sessionid,
)
ignored_lines = report_builder_session.ignored_lines

# dict of {"fileid": "path"}
file_by_id = {}
file_by_id_get = file_by_id.get
file_by_name = {None: None}
for f in xml.iter("File"):
filename = report_builder_session.path_fixer(
Expand Down
11 changes: 6 additions & 5 deletions services/report/languages/dlst.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import typing
from io import BytesIO

import sentry_sdk
from shared.reports.resources import Report
from shared.reports.types import ReportLine

Expand All @@ -12,16 +12,17 @@


class DLSTProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
return bool(content[-7:] == b"covered")
def matches_content(self, content: bytes, first_line: str, name: str) -> bool:
return content[-7:] == b"covered"

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: bytes, report_builder: ReportBuilder
) -> Report:
return from_string(content, report_builder.create_report_builder_session(name))


def from_string(string, report_builder_session: ReportBuilderSession) -> Report:
def from_string(string: bytes, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, sessionid, filename = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
Expand Down
15 changes: 7 additions & 8 deletions services/report/languages/elm.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import typing

import sentry_sdk
from shared.reports.resources import Report

from services.report.languages.base import BaseLanguageProcessor
Expand All @@ -11,21 +10,21 @@


class ElmProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
return isinstance(content, dict) and bool(content.get("coverageData"))
def matches_content(self, content: dict, first_line: str, name: str) -> bool:
return isinstance(content, dict) and "coverageData" in content

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: dict, report_builder: ReportBuilder
) -> Report:
report_builder_session = report_builder.create_report_builder_session(name)
return from_json(content, report_builder_session)


def from_json(json, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, sessionid = (
def from_json(json: dict, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
report_builder_session.sessionid,
)
for name, data in json["coverageData"].items():
fn = path_fixer(json["moduleMap"][name])
Expand Down
15 changes: 7 additions & 8 deletions services/report/languages/flowcover.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import typing

import sentry_sdk
from shared.reports.resources import Report

from services.report.languages.base import BaseLanguageProcessor
Expand All @@ -11,23 +10,23 @@


class FlowcoverProcessor(BaseLanguageProcessor):
def matches_content(self, content, first_line, name):
return isinstance(content, dict) and bool(content.get("flowStatus"))
def matches_content(self, content: dict, first_line: str, name: str) -> bool:
return isinstance(content, dict) and "flowStatus" in content

@sentry_sdk.trace
def process(
self, name: str, content: typing.Any, report_builder: ReportBuilder
self, name: str, content: dict, report_builder: ReportBuilder
) -> Report:
report_builder_session = report_builder.create_report_builder_session(
filepath=name
)
return from_json(content, report_builder_session)


def from_json(json, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines, sessionid = (
def from_json(json: dict, report_builder_session: ReportBuilderSession) -> Report:
path_fixer, ignored_lines = (
report_builder_session.path_fixer,
report_builder_session.ignored_lines,
report_builder_session.sessionid,
)

for fn, data in json["files"].items():
Expand Down
Loading

0 comments on commit b5b01e4

Please sign in to comment.