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

pyta-uoft / pyta / 18984642825

31 Oct 2025 08:39PM UTC coverage: 93.664% (-0.6%) from 94.222%
18984642825

Pull #1251

github

web-flow
Merge 924a71221 into cc0379cd3
Pull Request #1251: Optimizing performance for 'test_examples.py'

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

21 existing lines in 7 files now uncovered.

3474 of 3709 relevant lines covered (93.66%)

17.54 hits per line

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

99.56
/python_ta/reporters/node_printers.py
1
"""Specify how errors should be rendered."""
2

3
import re
20✔
4
from enum import Enum
20✔
5

6
from astroid import nodes
20✔
7

8
NEW_BLANK_LINE_MESSAGE = "# INSERT NEW BLANK LINE HERE"
20✔
9

10

11
def render_message(msg, node, source_lines, config=None):
20✔
12
    """Render a message based on type."""
13
    renderer = CUSTOM_MESSAGES.get(msg.symbol, render_generic)
20✔
14
    yield from renderer(msg, node, source_lines, config)
20✔
15

16

17
def render_generic(msg, node=None, source_lines=None, config=None):
20✔
18
    """Default rendering for a message."""
19
    if node is not None:
20✔
20
        start_line, start_col = node.fromlineno, node.col_offset
20✔
21

22
        if isinstance(node, (nodes.FunctionDef, nodes.ClassDef)):
20✔
23
            end_line, end_col = start_line, None
20✔
24
        else:
25
            end_line, end_col = node.end_lineno, node.end_col_offset
20✔
26

27
        # Display up to 2 lines before node for context:
28
        yield from render_context(start_line - 2, start_line, source_lines)
20✔
29

30
        if start_line == end_line:
20✔
31
            yield (
20✔
32
                start_line,
33
                slice(start_col, end_col),
34
                LineType.ERROR,
35
                source_lines[start_line - 1],
36
            )
37
        else:
38
            yield (start_line, slice(start_col, None), LineType.ERROR, source_lines[start_line - 1])
20✔
39
            yield from (
20✔
40
                (line, slice(None, None), LineType.ERROR, source_lines[line - 1])
41
                for line in range(start_line + 1, end_line)
42
            )
43
            yield (end_line, slice(None, end_col), LineType.ERROR, source_lines[end_line - 1])
20✔
44

45
        # Display up to 2 lines after node for context:
46
        yield from render_context(end_line + 1, end_line + 3, source_lines)
20✔
47

48
    else:
49
        line = msg.line
20✔
50
        yield from render_context(line - 2, line, source_lines)
20✔
51
        yield (line, slice(None, None), LineType.ERROR, source_lines[line - 1])
20✔
52
        yield from render_context(line + 1, line + 3, source_lines)
20✔
53

54

55
def render_missing_docstring(_msg, node, source_lines=None, config=None):
20✔
56
    """Render a missing docstring message."""
57
    if isinstance(node, nodes.Module):
20✔
58
        yield (None, slice(None, None), LineType.DOCSTRING, '"""YOUR DOCSTRING HERE"""')
20✔
59
        yield from render_context(1, 3, source_lines)
20✔
60
    elif isinstance(node, nodes.ClassDef) or isinstance(node, nodes.FunctionDef):
20✔
61
        start = node.fromlineno
20✔
62
        end = node.body[0].fromlineno
20✔
63
        yield from render_context(start, end, source_lines)
20✔
64
        # Calculate indentation
65
        body = source_lines[end - 1]
20✔
66
        indentation = len(body) - len(body.lstrip())
20✔
67
        yield (
20✔
68
            None,
69
            slice(None, None),
70
            LineType.DOCSTRING,
71
            body[:indentation] + '"""YOUR DOCSTRING HERE"""',
72
        )
73
        yield from render_context(end, end + 2, source_lines)
20✔
74

75

76
def render_line_too_long(msg, node, source_lines=None, config=None):
20✔
77
    """Render a line too long message."""
78
    line = msg.line
20✔
79

80
    # Set start_index to configured max-line-length and end_index to length of line
81
    start_index, end_index = config.max_line_length, len(source_lines[line - 1])
20✔
82

83
    yield from render_context(line - 2, line, source_lines)
20✔
84
    yield (line, slice(start_index, end_index), LineType.ERROR, source_lines[line - 1])
20✔
85
    yield from render_context(line + 1, line + 2, source_lines)
20✔
86

87

88
def render_trailing_newlines(msg, _node, source_lines=None, config=None):
20✔
89
    """Render a trailing newlines message."""
90
    start_line = len(source_lines)
10✔
91
    while start_line > 0 and source_lines[start_line - 1].strip() == "":
10✔
92
        start_line -= 1
10✔
93
    start_line += 1  # Offset to start from the first extraneous newline
10✔
94

95
    yield from render_context(start_line - 2, start_line + 1, source_lines)
10✔
96
    for line in range(start_line, len(source_lines)):
10✔
97
        yield ((line, slice(None, None), LineType.ERROR, source_lines[line] + "# DELETE THIS LINE"))
10✔
98
    # Render the last newline
99
    yield (len(source_lines) + 1, slice(None, None), LineType.ERROR, "# DELETE THIS LINE")
10✔
100

101

102
def render_trailing_whitespace(msg, _node, source_lines=None, config=None):
20✔
103
    """Render a trailing whitespace message."""
104
    line = msg.line
10✔
105
    start_index, end_index = len(source_lines[line - 1].rstrip()), len(source_lines[line - 1])
10✔
106
    yield from render_context(line - 1, line, source_lines)
10✔
107
    yield (line, slice(start_index, end_index), LineType.ERROR, source_lines[line - 1])
10✔
108
    yield from render_context(line + 1, line + 2, source_lines)
10✔
109

110

111
def render_context(start, stop, source_lines):
20✔
112
    """Helper for rendering context lines."""
113
    start, stop = max(start, 1), min(stop, len(source_lines))
20✔
114
    yield from (
20✔
115
        (line, slice(None, None), LineType.CONTEXT, source_lines[line - 1])
116
        for line in range(start, stop)
117
    )
118

119

120
def render_missing_return_type(_msg, node, source_lines=None, config=None):
20✔
121
    """Render a type annotation return message."""
122
    start_line, start_col = node.fromlineno, node.parent.col_offset
20✔
123
    end_line, end_col = node.end_lineno, node.end_col_offset
20✔
124

125
    # Display up to 2 lines before node for context:
126
    yield from render_context(start_line - 2, start_line, source_lines)
20✔
127
    yield from (
20✔
128
        (line, slice(None, end_col + 1), LineType.ERROR, source_lines[line - 1])
129
        for line in range(start_line, end_line + 1)
130
    )
131
    # Display up to 2 lines after node for context:
132
    yield from render_context(end_line + 1, end_line + 3, source_lines)
20✔
133

134

135
def render_too_many_arguments(msg, node, source_lines=None, config=None):
20✔
136
    """Render a too many arguments message."""
137
    # node is a FunctionDef node so replace it with its Arguments child
138
    yield from render_generic(msg, node.args, source_lines, config)
10✔
139

140

141
def render_missing_space_in_doctest(msg, _node, source_lines=None, config=None):
20✔
142
    """Render a missing space in doctest message"""
143
    line = msg.line
10✔
144

145
    # Display 2 lines before and after the erroneous line
146
    yield from render_context(line - 2, line, source_lines)
10✔
147
    yield (line, slice(None, None), LineType.ERROR, source_lines[line - 1])
10✔
148
    yield from render_context(line + 1, line + 3, source_lines)
10✔
149

150

151
def render_pep8_errors(msg, _node, source_lines=None, config=None):
20✔
152
    """Render a PEP8 error message."""
153
    # Extract the raw error message
154
    raw_msg = getattr(msg, "msg", "")
20✔
155

156
    # Search for the first appearance of the error code in the extracted error text
157
    matched_error = re.search(r"(E\d{3})", raw_msg)
20✔
158
    if matched_error:
20✔
159
        error_code = matched_error.group(1)
20✔
160
        # Render the appropriate error through the RENDERERS dict
161
        if error_code in RENDERERS:
20✔
162
            line = msg.line
20✔
163
            require_source_lines_renderers = {"E302", "E303", "E304", "E305"}
20✔
164
            if error_code in require_source_lines_renderers:
20✔
165
                yield from RENDERERS[error_code](msg, line, source_lines)
20✔
166
            else:
167
                col = msg.column
20✔
168
                yield from render_context(line - 3, line, source_lines)
20✔
169
                yield from RENDERERS[error_code](line, col, source_lines[line - 1])
20✔
170
                yield from render_context(line + 1, line + 3, source_lines)
20✔
171
            return
20✔
172

173
    # If none of the error codes were present, render the error using the generic error renderer
174
    yield from render_generic(msg, _node, source_lines)
20✔
175

176

177
def render_blank_line(line):
20✔
178
    """Render a blank line for a PEP8 error message."""
179
    yield (line + 1, slice(None, None), LineType.ERROR, " " * 28)
20✔
180

181

182
def render_pep8_errors_e101_and_e123_and_e116(line, col, source_line=None):
20✔
183
    """Render a PEP8 indentation contains mixed spaces and tabs message
184
    AND a PEP8 closing bracket does not match indentation of opening bracket's line message."""
185
    curr_idx = len(source_line) - len(source_line.lstrip())
20✔
186
    yield (line, slice(0, curr_idx), LineType.ERROR, source_line)
20✔
187

188

189
def render_pep8_errors_e115(line, col, source_line=None):
20✔
190
    """Render a PEP8 expected an indented block (comment) message."""
191
    yield (
10✔
192
        line,
193
        slice(0, len(source_line)),
194
        LineType.ERROR,
195
        source_line + "  # INDENT THIS LINE",
196
    )
197

198

199
def render_pep8_errors_e122_and_e127_and_e131(line, col, source_line=None):
20✔
200
    """
201
    Render a PEP8 continuation line missing indentation or outdented message, a line over-indented for visual indent
202
    message, and a continuation line unaligned for hanging indent message.
203
    """
204
    curr_line_start_index = len(source_line) - len(source_line.lstrip())
10✔
205
    end_index = curr_line_start_index if curr_line_start_index > 0 else len(source_line)
10✔
206
    yield (
10✔
207
        line,
208
        slice(0, end_index),
209
        LineType.ERROR,
210
        source_line,
211
    )
212

213

214
def render_pep8_errors_e124(line, col, source_line=None):
20✔
215
    """Render a PEP8 closing bracket does not match visual indentation message."""
216
    yield (line, slice(col, col + 1), LineType.ERROR, source_line)
10✔
217

218

219
def render_pep8_errors_e125_and_e129(line, col, source_line=None):
20✔
220
    """Render a PEP8 continuation line with same indent as next logical line message
221
    AND a PEP8 visually indented line with same indent as next logical line messsage"""
222
    curr_idx = len(source_line) - len(source_line.lstrip())
10✔
223
    yield (
10✔
224
        line,
225
        slice(curr_idx, len(source_line)),
226
        LineType.ERROR,
227
        source_line + " " * 2 + "# INDENT THIS LINE",
228
    )
229

230

231
def render_pep8_errors_e128(line, col, source_line):
20✔
232
    """Render a PEP8 continuation line under-indented for visual indent message."""
233
    yield (line, slice(0, col if col != 0 else None), LineType.ERROR, source_line)
10✔
234

235

236
def render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272(line, col, source_line=None):
20✔
237
    """Render a PEP8 whitespace after '(' message,
238
    a PEP8 whitespace before ')' message,
239
    a PEP8 whitespace before ‘,’, ‘;’, or ‘:’ message,
240
    a PEP8 whitespace before '(' message,
241
    a PEP8 multiple spaces before operator message,
242
    a PEP8 multiple spaces after keyword message,
243
    a PEP8 multiple spaces before keyword message
244
    and a PEP8 multiple spaces after operator message."""
245
    curr_idx = col + len(source_line[col:]) - len(source_line[col:].lstrip())
20✔
246

247
    yield (line, slice(col, curr_idx), LineType.ERROR, source_line)
20✔
248

249

250
def render_pep8_errors_e204(line, col, source_line=None):
20✔
251
    """Render a PEP8 whitespace after decorator '@' message"""
252
    # calculates the length of the leading whitespaces by subtracting the length of everything after the first character after stripping all leading whitespaces from the total line length
253
    curr_idx = col + len(source_line[col:]) - len(source_line[col + 1 :].lstrip())
10✔
254

255
    yield (line, slice(col, curr_idx), LineType.ERROR, source_line)
10✔
256

257

258
def render_pep8_errors_e223_and_e274(line, col, source_line=None):
20✔
259
    """Render a PEP8 tab before operator message and a PEP8 tab before keyword message."""
260
    curr_idx = col + len(source_line[col:]) - len(source_line[col:].lstrip("\t"))
10✔
261

262
    yield (line, slice(col, curr_idx), LineType.ERROR, source_line)
10✔
263

264

265
def render_pep8_errors_e224_and_e273(line, col, source_line):
20✔
266
    """Render a PEP8 tab after operator message and a PEP8 tab after keyword message."""
267
    curr_idx = col + len(source_line[col:]) - len(source_line[col:].lstrip("\t"))
10✔
268

269
    yield (line, slice(col, curr_idx), LineType.ERROR, source_line)
10✔
270

271

272
def render_pep8_errors_e225(line, col, source_line):
20✔
273
    """Render a PEP8 missing whitespace around operator message"""
274
    curr_idx = col + 1
20✔
275

276
    two_char_operators = {
20✔
277
        "==",
278
        ">=",
279
        "<=",
280
        "!=",
281
        ":=",
282
        "&=",
283
        "->",
284
        "%=",
285
        "/=",
286
        "+=",
287
        "-=",
288
        "*=",
289
        "|=",
290
        "^=",
291
        "@=",
292
    }
293
    three_char_operators = {"//=", ">>=", "<<=", "**="}
20✔
294
    # highlight multiple characters for operators that are longer than one character
295
    if source_line[col : col + 2] in two_char_operators:
20✔
296
        curr_idx += 1
20✔
297
    elif source_line[col : col + 3] in three_char_operators:
10✔
298
        curr_idx += 2
10✔
299

300
    yield (line, slice(col, curr_idx), LineType.ERROR, source_line)
20✔
301

302

303
def render_pep8_errors_e226(line, col, source_line):
20✔
304
    """Render a PEP8 missing whitespace around arithmetic operator message"""
305
    end_idx = col + 1
20✔
306

307
    multi_char_operators = {"//"}
20✔
308
    # highlight multiple characters for arithmetic operators that are longer than one character
309
    if source_line[col : col + 2] in multi_char_operators:
20✔
310
        end_idx += 1
10✔
311

312
    yield (line, slice(col, end_idx), LineType.ERROR, source_line)
20✔
313

314

315
def render_pep8_errors_e227(line, col, source_line=None):
20✔
316
    """Render a PEP8 missing whitespace around bitwise or shift operator message."""
317
    # Check which operator to get the correct range of the line to highlight.
318
    # Default highlight is one character, but may be updated to two.
319
    # Note that only binary bitwise operators that are more than one character are included.
320
    operators = {">>", "<<"}
10✔
321
    end_idx = col + 1
10✔
322
    end_idx = end_idx + 1 if source_line[col : col + 2] in operators else end_idx
10✔
323

324
    yield (line, slice(col, end_idx), LineType.ERROR, source_line)
10✔
325

326

327
def render_pep8_errors_e228(line, col, source_line=None):
20✔
328
    """Render a PEP8 missing whitespace around modulo operator message."""
329
    yield (
10✔
330
        line,
331
        slice(col, col + 1),
332
        LineType.ERROR,
333
        source_line + "  # INSERT A SPACE BEFORE AND AFTER THE % OPERATOR",
334
    )
335

336

337
def render_pep8_errors_e231(line, col, source_line=None):
20✔
338
    curr_idx = col + 1
20✔
339

340
    yield (line, slice(col, curr_idx), LineType.ERROR, source_line)
20✔
341

342

343
def render_pep8_errors_e251(line, col, source_line=None):
20✔
344
    """Render a PEP8 unexpected spaces around keyword / parameter equals message."""
345
    equals_sign_idx = source_line[col:].find("=")
10✔
346
    code = source_line[col : col + equals_sign_idx if equals_sign_idx != -1 else None]
10✔
347
    end_idx = col + len(code) - len(code.lstrip())
10✔
348

349
    yield (line, slice(col, end_idx), LineType.ERROR, source_line)
10✔
350

351

352
def render_pep8_errors_e261(line, col, source_line=None):
20✔
353
    """Render a PEP8 at least two spaces before inline comment message."""
354
    yield (
10✔
355
        line,
356
        slice(col, len(source_line)),
357
        LineType.ERROR,
358
        source_line + "  # INSERT TWO SPACES BEFORE THE '#'",
359
    )
360

361

362
def render_pep8_errors_e262(line, col, source_line=None):
20✔
363
    """Render a PEP8 inline comment should start with '# ' message"""
364
    keyword_idx = len(source_line) - len(source_line[col:].lstrip("# \t"))
10✔
365

366
    yield (line, slice(col, keyword_idx), LineType.ERROR, source_line)
10✔
367

368

369
def render_pep8_errors_e265(line, col, source_line=None):
20✔
370
    """Render a PEP8 block comment should start with '# ' message."""
371
    yield (
10✔
372
        line,
373
        slice(0, len(source_line)),
374
        LineType.ERROR,
375
        source_line + "  # INSERT SPACE AFTER THE '#'",
376
    )
377

378

379
def render_pep8_errors_e266(line, col, source_line=None):
20✔
380
    """Render a PEP8 too many leading ‘#’ for block comment message."""
381
    curr_idx = col + len(source_line[col:]) - len(source_line[col:].lstrip("#"))
10✔
382

383
    yield (
10✔
384
        line,
385
        slice(col, curr_idx),
386
        LineType.ERROR,
387
        source_line + "  # THERE SHOULD ONLY BE ONE '#'",
388
    )
389

390

391
def render_pep8_errors_e275(line, col, source_line=None):
20✔
392
    """Render a PEP8 missing whitespace after keyword message."""
393
    # Get the range for highlighting the corresponding keyword.
394
    keyword = source_line[:col].split()[-1]
10✔
395
    keyword_idx = source_line.index(keyword)
10✔
396

397
    yield (
10✔
398
        line,
399
        slice(keyword_idx, col),
400
        LineType.ERROR,
401
        source_line + "  # INSERT SPACE AFTER KEYWORD",
402
    )
403

404

405
def render_pep8_errors_e301(line, col, source_line=None):
20✔
406
    """Render a PEP8 expected 1 blank line message."""
407
    indentation = len(source_line) - len(source_line.lstrip())
10✔
408
    yield (
10✔
409
        None,
410
        slice(None, None),
411
        LineType.ERROR,
412
        source_line[:indentation] + NEW_BLANK_LINE_MESSAGE,
413
    )
414

415

416
def render_pep8_errors_e302(msg, line, source_lines=None):
20✔
417
    """Render a PEP8 expected 2 blank lines message."""
418
    if "found 0" in msg.msg:
20✔
419
        yield from render_context(line - 3, line, source_lines)
10✔
420
        yield from (
10✔
421
            (
422
                None,
423
                slice(None, None),
424
                LineType.ERROR,
425
                NEW_BLANK_LINE_MESSAGE,
426
            )
427
            for _ in range(0, 2)
428
        )
429
    else:
430
        yield from render_context(line - 3, line - 1, source_lines)
20✔
431
        yield from render_blank_line(line)
20✔
432
        yield (None, slice(None, None), LineType.ERROR, NEW_BLANK_LINE_MESSAGE)
20✔
433
    yield from render_context(line, line + 3, source_lines)
20✔
434

435

436
def render_pep8_errors_e303_and_e304(msg, line, source_lines=None):
20✔
437
    """Render a PEP8 too many blank lines message
438
    and a PEP8 blank lines found after function decorator message
439
    """
440
    dline = line
10✔
441
    while source_lines[dline - 2].strip() == "":
10✔
442
        dline -= 1
10✔
443
    body = source_lines[line - 1]
10✔
444
    indentation = len(body) - len(body.lstrip())
10✔
445
    yield from render_context(dline - 3, dline, source_lines)
10✔
446
    yield from (
10✔
447
        (curr_line, slice(None, None), LineType.ERROR, " " * (indentation + 28))
448
        for curr_line in range(dline, line)
449
    )
450
    yield from render_context(line, line + 3, source_lines)
10✔
451

452

453
def render_pep8_errors_e305(msg, line, source_lines=None):
20✔
454
    """Render a PEP8 expected 2 blank lines after class or function definition message."""
455
    if "found 0" in msg.msg:
20✔
456
        yield from render_context(line - 3, line, source_lines)
10✔
457
        yield from (
10✔
458
            (
459
                None,
460
                slice(None, None),
461
                LineType.ERROR,
462
                NEW_BLANK_LINE_MESSAGE,
463
            )
464
            for _ in range(0, 2)
465
        )
466
    else:
467
        yield from render_context(line - 3, line - 1, source_lines)
20✔
468
        yield from render_blank_line(line)
20✔
469
        yield (None, slice(None, None), LineType.ERROR, NEW_BLANK_LINE_MESSAGE)
20✔
470
    yield from render_context(line, line + 3, source_lines)
20✔
471

472

473
def render_pep8_errors_e306(line, col, source_line=None):
20✔
474
    """Render a PEP8 expected 1 blank line before a nested definition message."""
475
    indentation = len(source_line) - len(source_line.lstrip())
10✔
476
    yield (
10✔
477
        None,
478
        slice(None, None),
479
        LineType.ERROR,
480
        source_line[:indentation] + NEW_BLANK_LINE_MESSAGE,
481
    )
482

483

484
def render_pep8_errors_e502(line, col, source_line=None):
20✔
485
    """Render a PEP8 the backslash is redundant between brackets."""
486
    yield (line, slice(col, col + 1), LineType.ERROR, source_line)
10✔
487

488

489
def render_missing_return_statement(msg, node, source_lines=None, config=None):
20✔
490
    """
491
    Render a missing return statements message
492
    """
493
    yield from render_context(msg.line, msg.end_line + 1, source_lines)
20✔
494

495
    # calculate indentation for the insertion point
496
    body = source_lines[msg.end_line - 1]
20✔
497
    indentation = len(source_lines[msg.line - 1]) - len(source_lines[msg.line - 1].lstrip())
20✔
498

499
    # determine whether reaching the end of function
500
    first_statement_line = node.end_lineno if len(node.body) == 0 else node.body[0].lineno
20✔
501
    function_indentation = len(source_lines[first_statement_line - 1]) - len(
20✔
502
        source_lines[first_statement_line - 1].lstrip()
503
    )
504

505
    if msg.end_line == node.end_lineno and indentation == function_indentation:
20✔
506
        insertion_text = body[:indentation] + "# INSERT RETURN STATEMENT HERE"
20✔
507
    else:
UNCOV
508
        insertion_text = body[:indentation] + "# INSERT RETURN STATEMENT HERE (OR BELOW)"
×
509

510
    # insert the message
511
    yield (
20✔
512
        None,
513
        slice(indentation, None),
514
        LineType.ERROR,
515
        insertion_text,
516
    )
517

518
    yield from render_context(msg.end_line + 1, msg.end_line + 3, source_lines)
20✔
519

520

521
def render_static_type_checker_errors(msg, _node=None, source_lines=None, config=None):
20✔
522
    """Render a message for incompatible argument types."""
523
    start_line = msg.line
20✔
524
    start_col = msg.column
20✔
525
    end_line = msg.end_line
20✔
526
    end_col = msg.end_column
20✔
527
    yield from render_context(start_line - 2, start_line, source_lines)
20✔
528

529
    if start_line == end_line:
20✔
530
        yield (
20✔
531
            start_line,
532
            slice(start_col - 1, end_col),
533
            LineType.ERROR,
534
            source_lines[start_line - 1],
535
        )
536
    else:
537
        yield (start_line, slice(start_col - 1, None), LineType.ERROR, source_lines[start_line - 1])
10✔
538
        yield from (
10✔
539
            (line, slice(None, None), LineType.ERROR, source_lines)
540
            for line in range(start_line + 1, end_line)
541
        )
542
        yield (end_line, slice(None, end_col), LineType.ERROR, source_lines[end_line - 1])
10✔
543
    yield from render_context(end_line + 1, end_line + 3, source_lines)
20✔
544

545

546
CUSTOM_MESSAGES = {
20✔
547
    "missing-module-docstring": render_missing_docstring,
548
    "missing-class-docstring": render_missing_docstring,
549
    "missing-function-docstring": render_missing_docstring,
550
    "line-too-long": render_line_too_long,
551
    "trailing-newlines": render_trailing_newlines,
552
    "trailing-whitespace": render_trailing_whitespace,
553
    "missing-return-type": render_missing_return_type,
554
    "too-many-arguments": render_too_many_arguments,
555
    "missing-space-in-doctest": render_missing_space_in_doctest,
556
    "pep8-errors": render_pep8_errors,
557
    "missing-return-statement": render_missing_return_statement,
558
    "incompatible-argument-type": render_static_type_checker_errors,
559
    "incompatible-assignment": render_static_type_checker_errors,
560
    "list-item-type-mismatch": render_static_type_checker_errors,
561
    "unsupported-operand-types": render_static_type_checker_errors,
562
    "union-attr-error": render_static_type_checker_errors,
563
    "dict-item-type-mismatch": render_static_type_checker_errors,
564
}
565

566
RENDERERS = {
20✔
567
    "E101": render_pep8_errors_e101_and_e123_and_e116,
568
    "E123": render_pep8_errors_e101_and_e123_and_e116,
569
    "E115": render_pep8_errors_e115,
570
    "E116": render_pep8_errors_e101_and_e123_and_e116,
571
    "E122": render_pep8_errors_e122_and_e127_and_e131,
572
    "E127": render_pep8_errors_e122_and_e127_and_e131,
573
    "E131": render_pep8_errors_e122_and_e127_and_e131,
574
    "E124": render_pep8_errors_e124,
575
    "E125": render_pep8_errors_e125_and_e129,
576
    "E129": render_pep8_errors_e125_and_e129,
577
    "E128": render_pep8_errors_e128,
578
    "E201": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
579
    "E202": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
580
    "E203": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
581
    "E204": render_pep8_errors_e204,
582
    "E211": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
583
    "E221": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
584
    "E222": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
585
    "E223": render_pep8_errors_e223_and_e274,
586
    "E224": render_pep8_errors_e224_and_e273,
587
    "E225": render_pep8_errors_e225,
588
    "E231": render_pep8_errors_e231,
589
    "E273": render_pep8_errors_e224_and_e273,
590
    "E274": render_pep8_errors_e223_and_e274,
591
    "E226": render_pep8_errors_e226,
592
    "E227": render_pep8_errors_e227,
593
    "E228": render_pep8_errors_e228,
594
    "E251": render_pep8_errors_e251,
595
    "E261": render_pep8_errors_e261,
596
    "E262": render_pep8_errors_e262,
597
    "E265": render_pep8_errors_e265,
598
    "E266": render_pep8_errors_e266,
599
    "E271": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
600
    "E272": render_pep8_errors_e201_e202_e203_e211_e221_e222_e271_e272,
601
    "E275": render_pep8_errors_e275,
602
    "E301": render_pep8_errors_e301,
603
    "E302": render_pep8_errors_e302,
604
    "E303": render_pep8_errors_e303_and_e304,
605
    "E304": render_pep8_errors_e303_and_e304,
606
    "E305": render_pep8_errors_e305,
607
    "E306": render_pep8_errors_e306,
608
    "E502": render_pep8_errors_e502,
609
}
610

611

612
class LineType(Enum):
20✔
613
    """An enumeration for _add_line method line types."""
614

615
    ERROR = 1  # line with error
20✔
616
    CONTEXT = 2  # non-error/other line added for context
20✔
617
    OTHER = 3  # line included in source but not error
20✔
618
    ELLIPSIS = 5  # code replaced with ellipsis
20✔
619
    DOCSTRING = 6  # docstring needed warning
20✔
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