• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mozilla / fx-private-relay / d3128616-238d-446e-82c5-ab66cd38ceaf

09 May 2024 06:22PM CUT coverage: 84.07% (-0.6%) from 84.64%
d3128616-238d-446e-82c5-ab66cd38ceaf

push

circleci

web-flow
Merge pull request #4684 from mozilla/enable-flak8-bandit-checks-mpp-3802

fix MPP-3802: stop ignoring bandit security checks

3601 of 4734 branches covered (76.07%)

Branch coverage included in aggregate %.

74 of 158 new or added lines in 24 files covered. (46.84%)

5 existing lines in 5 files now uncovered.

14686 of 17018 relevant lines covered (86.3%)

10.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.84
/privaterelay/cleaners.py
1
"""Framework for tasks that identify data issues and (if possible) clean them up"""
2

3
from __future__ import annotations
1✔
4

5
from typing import Any
1✔
6

7
Counts = dict[str, dict[str, int]]
1✔
8
CleanupData = dict[str, Any]
1✔
9

10

11
class DataIssueTask:
1✔
12
    """Base class for data issue / cleaner tasks."""
13

14
    slug: str  # Short name, appropriate for command-line option
1✔
15
    title: str  # Short title for reports
1✔
16
    check_description: str  # A sentence describing what this cleaner is checking.
1✔
17
    can_clean: bool  # True if the issue can be automatically cleaned
1✔
18

19
    _counts: Counts | None
1✔
20
    _cleanup_data: CleanupData | None
1✔
21
    _cleaned: bool
1✔
22

23
    def __init__(self):
1✔
24
        self._counts = None
1✔
25
        self._cleanup_data = None
1✔
26
        self._cleaned = False
1✔
27

28
    @property
1✔
29
    def counts(self) -> Counts:
1✔
30
        """Get relevant counts for data issues and prepare to clean if possible."""
31
        if self._counts is None:
1✔
32
            if self._cleanup_data is not None:
1!
NEW
33
                raise ValueError(
×
34
                    "self.cleanup_data should be None when self._counts is None"
35
                )
36
            self._counts, self._cleanup_data = self._get_counts_and_data()
1✔
37
        return self._counts
1✔
38

39
    @property
1✔
40
    def cleanup_data(self) -> CleanupData:
1✔
41
        """Get data needed to clean data issues."""
42
        if not self.counts:
1!
NEW
43
            raise ValueError("self.counts must have a value when calling cleanup_data.")
×
44
        if not self._cleanup_data:
1!
NEW
45
            raise ValueError(
×
46
                "self._cleanup_data must have a value when calling cleanup_data."
47
            )
48
        return self._cleanup_data
1✔
49

50
    def issues(self) -> int:
1✔
51
        """Return the number of detected data issues."""
52
        return self.counts["summary"]["needs_cleaning"]
1✔
53

54
    def _get_counts_and_data(self) -> tuple[Counts, CleanupData]:
1✔
55
        """Return a dictionary of counts and cleanup data."""
56
        raise NotImplementedError("_get_counts_and_data() not implemented")
1✔
57

58
    def _clean(self) -> int:
1✔
59
        """
60
        Clean the detected items.
61

62
        Returns the number of cleaned items. Implementors can add detailed
63
        counts to self._counts as needed.
64
        """
65
        raise NotImplementedError("_clean() not implemented")
1✔
66

67
    def clean(self) -> int:
1✔
68
        """Clean the detected items, and update counts["summary"]"""
69
        summary = self.counts["summary"]
1✔
70
        if not self._cleaned:
1✔
71
            summary["cleaned"] = self._clean()
1✔
72
            self._cleaned = True
1✔
73
        return summary["cleaned"]
1✔
74

75
    def markdown_report(self) -> str:
1✔
76
        """Return Markdown-formatted report of issues found and (maybe) fixed."""
77
        raise NotImplementedError("markdown_report() not implemented")
1✔
78

79
    @staticmethod
1✔
80
    def _as_percent(part: int, whole: int) -> str:
1✔
81
        """Return value followed by percent of whole, like '5 ( 30.0%)'"""
82
        if not whole > 0:
1!
NEW
83
            raise ValueError("whole must be greater than 0 when calling _as_percent")
×
84
        len_whole = len(str(whole))
1✔
85
        return f"{part:{len_whole}d} ({part / whole:6.1%})"
1✔
86

87

88
class CleanerTask(DataIssueTask):
1✔
89
    """Base class for tasks that can clean up detected issues."""
90

91
    can_clean = True
1✔
92

93

94
class DetectorTask(DataIssueTask):
1✔
95
    """Base class for tasks that cannot clean up detected issues."""
96

97
    can_clean = False
1✔
98

99
    def _clean(self) -> int:
1✔
100
        """DetectorTask can't clean any detected issues."""
101
        return 0
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc