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

pybuilder / pybuilder / 19378751824

14 Nov 2025 09:59PM UTC coverage: 82.899% (-1.0%) from 83.907%
19378751824

push

github

web-flow
Upgrade coveralls to ~=4.0 (#930)

1388 of 1840 branches covered (75.43%)

Branch coverage included in aggregate %.

0 of 10 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

5510 of 6481 relevant lines covered (85.02%)

39.53 hits per line

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

15.15
/src/main/python/pybuilder/plugins/python/coveralls_plugin.py
1
#   -*- coding: utf-8 -*-
2
#
3
#   This file is part of PyBuilder
4
#
5
#   Copyright 2011-2020 PyBuilder Team
6
#
7
#   Licensed under the Apache License, Version 2.0 (the "License");
8
#   you may not use this file except in compliance with the License.
9
#   You may obtain a copy of the License at
10
#
11
#       http://www.apache.org/licenses/LICENSE-2.0
12
#
13
#   Unless required by applicable law or agreed to in writing, software
14
#   distributed under the License is distributed on an "AS IS" BASIS,
15
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
#   See the License for the specific language governing permissions and
17
#   limitations under the License.
18

19
import logging
24✔
20
import random
24✔
21
from os.path import normcase as nc
24✔
22
from time import sleep
24✔
23

24
from pybuilder.core import init, use_plugin, finalize
24✔
25
from pybuilder.errors import BuildFailedException
24✔
26
from pybuilder.execution import ExecutionManager
24✔
27
from pybuilder.plugins.python._coverage_util import patch_coverage
24✔
28

29
use_plugin("python.core")
24✔
30
use_plugin("analysis")
24✔
31
use_plugin("python.coverage")
24✔
32

33

34
@init(environments="ci")
24✔
35
def init_coveralls_properties(project):
24✔
NEW
36
    project.plugin_depends_on("coveralls", "~=4.0")
×
37

38
    project.set_property_if_unset("coveralls_dry_run", False)
×
39
    project.set_property_if_unset("coveralls_report", False)
×
40
    project.set_property_if_unset("coveralls_token_required", True)
×
41
    project.set_property_if_unset("coveralls_retry_delay_min", 3)
×
42
    project.set_property_if_unset("coveralls_retry_delay_max", 10)
×
43

44

45
@finalize(environments="ci")
24✔
46
def finalize_coveralls(project, logger, reactor):
24✔
47
    em = reactor.execution_manager  # type: ExecutionManager
×
48

49
    if not em.is_task_in_current_execution_plan("coverage"):
×
50
        return
×
51

52
    patch_coverage()
×
53

54
    from coveralls.api import Coveralls, CoverallReporter, CoverallsException
×
55
    from coverage import coverage, files
×
56

57
    class PybCoveralls(Coveralls):
×
58
        def get_coverage(self):
×
59
            coverage_config = project.get_property("__coverage_config")
×
60

61
            workman = coverage(**coverage_config)
×
62
            workman.load()
×
NEW
63
            workman.get_data()
×
64

NEW
65
            return CoverallReporter(workman).coverage
×
66

NEW
67
        def wear(self, dry_run=False):
×
NEW
68
            json_string = self.create_report()
×
NEW
69
            if dry_run:
×
NEW
70
                return json_string
×
NEW
71
            return self.submit_report(json_string)
×
72

73
    coveralls_logger = logging.getLogger("coveralls")
×
74
    coveralls_logger.addHandler(logger)
×
75

76
    try:
×
77
        dry_run = project.get_property("coveralls_dry_run")
×
78
        report = project.get_property("coveralls_report")
×
79
        token_required = project.get_property("coveralls_token_required") and not dry_run and not report
×
80

81
        old_relative_dir = files.RELATIVE_DIR
×
82
        files.RELATIVE_DIR = nc(project.expand_path(project.get_property("coverage_source_path")))
×
83
        try:
×
84
            pyb_coveralls = PybCoveralls(token_required=token_required)
×
85
            try:
×
86
                staging = False
×
87
                if report:
×
88
                    report_file = project.expand_path("$dir_reports", "%s.coveralls.json" % project.name)
×
89
                    pyb_coveralls.save_report(report_file)
×
90
                    logger.info("Written Coveralls report into %r", report_file)
×
91
                    staging = True
×
92

93
                if dry_run:
×
NEW
94
                    report = pyb_coveralls.wear(dry_run=True)
×
95
                    logger.info("Coveralls dry-run coverage test has been completed!")
×
NEW
96
                    logger.debug("Coveralls report %s", report)
×
UNCOV
97
                    staging = True
×
98

99
                if staging:
×
100
                    return
×
101

102
                while True:
103
                    try:
×
104
                        report_result = pyb_coveralls.wear()
×
105
                        break
×
106
                    except CoverallsException as e:
×
107
                        if (hasattr(e.__cause__, "response") and
×
108
                                hasattr(e.__cause__.response, "status_code")):
109
                            status_code = e.__cause__.response.status_code
×
110
                            if status_code in (408, 429, 502, 503, 504):
×
111
                                # Retry after a random delay
112
                                logger.warn("Coveralls failed while uploading results, will retry: %s", e.__cause__)
×
113
                                sleep(random.randint(int(project.get_property("coveralls_retry_delay_min")),
×
114
                                                     int(project.get_property("coveralls_retry_delay_max"))))
115
                            elif status_code == 422 and pyb_coveralls.config["service_name"] == "github-actions":
×
116
                                # https://github.com/TheKevJames/coveralls-python/issues/252
117
                                pyb_coveralls = PybCoveralls(token_required=token_required, service_name="github")
×
118
                            else:
119
                                raise
×
120
                        else:
121
                            raise
×
122

123
                logger.debug("Coveralls result: %r", report_result)
×
124
                logger.info("Coveralls coverage successfully submitted! %s @ %s",
×
125
                            report_result["message"],
126
                            report_result["url"])
127
            except CoverallsException as e:
×
128
                raise BuildFailedException("Failed to upload Coveralls coverage: %s", e)
×
129
        finally:
130
            files.RELATIVE_DIR = old_relative_dir
×
131
    finally:
132
        coveralls_logger.removeHandler(logger)
×
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

© 2026 Coveralls, Inc