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

basilisp-lang / basilisp / 12281612501

11 Dec 2024 05:24PM CUT coverage: 98.677% (-0.06%) from 98.738%
12281612501

Pull #1172

github

web-flow
Merge a45766c9a into 2dffcc004
Pull Request #1172: Derive module (test) names from `ns` declarations

1026 of 1035 branches covered (99.13%)

Branch coverage included in aggregate %.

15 of 15 new or added lines in 2 files covered. (100.0%)

5 existing lines in 1 file now uncovered.

8820 of 8943 relevant lines covered (98.62%)

0.99 hits per line

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

95.56
/src/basilisp/lang/source.py
1
import itertools
1✔
2
import linecache
1✔
3
import os
1✔
4
from collections.abc import Iterable
1✔
5
from typing import Optional
1✔
6

7
try:
1✔
8
    import pygments.formatters
1✔
9
    import pygments.lexers
1✔
10
    import pygments.styles
1✔
11
except ImportError:  # pragma: no cover
12

13
    def _format_source(
14
        s: str, disable_color: Optional[bool] = None  # pylint: disable=unused-argument
15
    ) -> str:
16
        return f"{s}{os.linesep}"
17

18
else:
19

20
    def _get_formatter_name(
21
        disable_color: Optional[bool] = None,
22
    ) -> Optional[str]:  # pragma: no cover
23
        """Get the Pygments formatter name for formatting the source code by
24
        inspecting various environment variables set by terminals.
25

26
        If If `disable_color` is explicitly True or `BASILISP_NO_COLOR` is set
27
        to a truthy value, use no formatting."""
28
        if (disable_color is True) or os.environ.get(
29
            "BASILISP_NO_COLOR", "false"
30
        ).lower() in {"1", "true"}:
31
            return None
32
        elif os.environ.get("COLORTERM", "") in {"truecolor", "24bit"}:
33
            return "terminal16m"
34
        elif "256" in os.environ.get("TERM", ""):
35
            return "terminal256"
36
        else:
37
            return "terminal"
38

39
    def _format_source(
40
        s: str, disable_color: Optional[bool] = None
41
    ) -> str:  # pragma: no cover
42
        """Format source code for terminal output.
43

44
        If `disable_color` is True, no formatting will be applied to the source code."""
45
        if (formatter_name := _get_formatter_name(disable_color)) is None:
46
            return f"{s}{os.linesep}"
47
        return pygments.highlight(
48
            s,
49
            lexer=pygments.lexers.get_lexer_by_name("clojure"),
50
            formatter=pygments.formatters.get_formatter_by_name(
51
                formatter_name, style=pygments.styles.get_style_by_name("emacs")
52
            ),
53
        )
54

55

56
def format_source_context(  # pylint: disable=too-many-arguments,too-many-locals
1✔
57
    filename: str,
58
    line: int,
59
    end_line: Optional[int] = None,
60
    num_context_lines: int = 5,
61
    show_cause_marker: bool = True,
62
    disable_color: Optional[bool] = None,
63
) -> list[str]:
64
    """Format source code context with line numbers and identifiers for the affected
65
    line(s).
66

67
    If `disable_color` is True, no color formatting will be applied to the source code.
68
    """
69
    assert num_context_lines >= 0
1✔
70

71
    lines = []
1✔
72

73
    if not filename.startswith("<") and not filename.endswith(">"):
1✔
74
        cause_range: Optional[range]
75
        if not show_cause_marker:
1✔
76
            cause_range = None
×
77
        elif end_line is not None and end_line != line:
1✔
78
            cause_range = range(line, end_line + 1)
1✔
79
        else:
80
            cause_range = range(line, line + 1)
1✔
81

82
        linecache.checkcache(filename=filename)
1✔
83
        if source_lines := linecache.getlines(filename):
1✔
84
            selected_lines: Iterable[str]
85
            if end_line is None and line > len(source_lines):
1✔
86
                end = len(source_lines) + 1
1✔
87
                start = max(end - num_context_lines, 0)
1✔
88
                selected_lines = itertools.chain(
1✔
89
                    source_lines[start:end], itertools.repeat("\n")
90
                )
91
            else:
92
                start = max(0, line - num_context_lines)
1✔
93
                end = min((end_line or line) + num_context_lines, len(source_lines))
1✔
94
                selected_lines = source_lines[start:end]
1✔
95

96
            num_justify = max(len(str(start)), len(str(end))) + 1
1✔
97
            for n, source_line in zip(range(start, end), selected_lines):
1✔
98
                if cause_range is None:
1✔
99
                    line_marker = " "
×
100
                elif n + 1 in cause_range:
1✔
101
                    line_marker = " > "
1✔
102
                else:
103
                    line_marker = "   "
1✔
104

105
                line_num = str(n + 1).rjust(num_justify)
1✔
106
                lines.append(
1✔
107
                    f"{line_num}{line_marker}| {_format_source(source_line.rstrip(), disable_color=disable_color)}"
108
                )
109

110
    return lines
1✔
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