0
# Error System
1
2
Error codes, error handling classes, and error reporting functionality for comprehensive type checking diagnostics. Mypy's error system provides detailed, categorized error messages with precise location information.
3
4
## Capabilities
5
6
### Error Code System
7
8
Structured error codes that categorize different types of type checking errors.
9
10
```python { .api }
11
class ErrorCode:
12
"""
13
Represents specific error types with descriptions and categories.
14
15
Each error code has a unique name, human-readable description,
16
and belongs to a category for organizing related errors.
17
18
Attributes:
19
- code: str - Unique error code identifier
20
- description: str - Human-readable description
21
- category: str - Error category for grouping
22
"""
23
```
24
25
### Core Error Codes
26
27
Essential error codes for common type checking issues.
28
29
```python { .api }
30
# Attribute and name errors
31
ATTR_DEFINED: ErrorCode
32
"""Accessing undefined attributes on objects."""
33
34
NAME_DEFINED: ErrorCode
35
"""Using undefined names or variables."""
36
37
# Function call errors
38
CALL_ARG: ErrorCode
39
"""Function call argument errors (wrong number, missing, etc.)."""
40
41
ARG_TYPE: ErrorCode
42
"""Argument type mismatches in function calls."""
43
44
# Return value errors
45
RETURN: ErrorCode
46
"""Return statement errors."""
47
48
RETURN_VALUE: ErrorCode
49
"""Return value type mismatches."""
50
51
# Assignment errors
52
ASSIGNMENT: ErrorCode
53
"""Assignment type compatibility errors."""
54
55
# Method and inheritance errors
56
OVERRIDE: ErrorCode
57
"""Method override signature mismatches."""
58
59
# Generic type errors
60
TYPE_ARG: ErrorCode
61
"""Generic type argument errors."""
62
63
TYPE_VAR: ErrorCode
64
"""Type variable constraint violations."""
65
66
# Union type errors
67
UNION_ATTR: ErrorCode
68
"""Attribute access on union types where not all members have the attribute."""
69
70
# Container operation errors
71
INDEX: ErrorCode
72
"""Indexing operation errors (wrong key type, etc.)."""
73
74
OPERATOR: ErrorCode
75
"""Operator usage errors (unsupported operations)."""
76
77
# Container operation errors
78
LIST_ITEM: ErrorCode
79
"""List item type errors."""
80
81
DICT_ITEM: ErrorCode
82
"""Dictionary item type errors."""
83
84
TYPEDDICT_ITEM: ErrorCode
85
"""TypedDict item access errors."""
86
87
TYPEDDICT_UNKNOWN_KEY: ErrorCode
88
"""Unknown key access in TypedDict."""
89
90
# Import and module errors
91
IMPORT: ErrorCode
92
"""Import-related errors."""
93
94
IMPORT_NOT_FOUND: ErrorCode
95
"""Module not found errors."""
96
97
IMPORT_UNTYPED: ErrorCode
98
"""Importing from untyped modules."""
99
100
# Definition and redefinition errors
101
NO_REDEF: ErrorCode
102
"""Name redefinition errors."""
103
104
VAR_ANNOTATED: ErrorCode
105
"""Variable annotation errors."""
106
107
FUNC_RETURNS_VALUE: ErrorCode
108
"""Function return value errors."""
109
110
# Abstract class and method errors
111
ABSTRACT: ErrorCode
112
"""Abstract class instantiation errors."""
113
114
TYPE_ABSTRACT: ErrorCode
115
"""Abstract type usage errors."""
116
117
# String and literal errors
118
STRING_FORMATTING: ErrorCode
119
"""String formatting type errors."""
120
121
LITERAL_REQ: ErrorCode
122
"""Literal value requirement errors."""
123
124
STR_BYTES_PY3: ErrorCode
125
"""String/bytes compatibility errors in Python 3."""
126
127
# Async/await errors
128
UNUSED_COROUTINE: ErrorCode
129
"""Unused coroutine warnings."""
130
131
TOP_LEVEL_AWAIT: ErrorCode
132
"""Top-level await usage errors."""
133
134
AWAIT_NOT_ASYNC: ErrorCode
135
"""Await used outside async context."""
136
137
# Type checking strictness errors
138
NO_UNTYPED_CALL: ErrorCode
139
"""Calling untyped functions."""
140
141
NO_ANY_UNIMPORTED: ErrorCode
142
"""Any from unimported modules."""
143
144
NO_ANY_RETURN: ErrorCode
145
"""Functions returning Any."""
146
147
# Code quality and style errors
148
REDUNDANT_CAST: ErrorCode
149
"""Redundant type cast warnings."""
150
151
REDUNDANT_EXPR: ErrorCode
152
"""Redundant expression warnings."""
153
154
COMPARISON_OVERLAP: ErrorCode
155
"""Overlapping comparison warnings."""
156
157
UNUSED_IGNORE: ErrorCode
158
"""Unused type: ignore comments."""
159
160
UNUSED_AWAITABLE: ErrorCode
161
"""Unused awaitable expressions."""
162
163
# Advanced features
164
ASSERT_TYPE: ErrorCode
165
"""Assert type failures."""
166
167
SAFE_SUPER: ErrorCode
168
"""Super call safety checks."""
169
170
EXHAUSTIVE_MATCH: ErrorCode
171
"""Non-exhaustive match statements."""
172
173
EXPLICIT_OVERRIDE_REQUIRED: ErrorCode
174
"""Missing explicit override decorators."""
175
176
# Type annotation errors
177
ANNOTATION_UNCHECKED: ErrorCode
178
"""Issues with type annotations that can't be checked."""
179
180
VALID_TYPE: ErrorCode
181
"""Invalid type expressions in annotations."""
182
183
VALID_NEWTYPE: ErrorCode
184
"""NewType definition errors."""
185
186
HAS_TYPE: ErrorCode
187
"""Type existence checks."""
188
189
# Exit and control flow
190
EXIT_RETURN: ErrorCode
191
"""Exit function return type errors."""
192
193
# Miscellaneous errors
194
MISC: ErrorCode
195
"""Miscellaneous type checking errors."""
196
197
SYNTAX: ErrorCode
198
"""Python syntax errors."""
199
200
NO_RETURN: ErrorCode
201
"""Functions that should return but don't."""
202
203
UNREACHABLE: ErrorCode
204
"""Unreachable code detection."""
205
206
# Internal and debugging
207
FILE: ErrorCode
208
"""Internal marker for whole file ignoring."""
209
210
EXPLICIT_ANY: ErrorCode
211
"""Explicit Any usage warnings."""
212
213
UNIMPORTED_REVEAL: ErrorCode
214
"""reveal_type/reveal_locals usage warnings."""
215
```
216
217
### Error Handling Classes
218
219
Core classes for collecting, formatting, and reporting type checking errors.
220
221
```python { .api }
222
class Errors:
223
"""
224
Collects and formats error messages during type checking.
225
226
Central error reporting system that accumulates errors from
227
various phases of analysis and formats them for output.
228
229
Methods:
230
- report(line: int, column: int, message: str, code: ErrorCode | None)
231
- num_messages() -> int
232
- is_errors() -> bool
233
- format_messages() -> list[str]
234
"""
235
236
class CompileError(Exception):
237
"""
238
Exception raised when type checking fails with critical errors.
239
240
Used for errors that prevent continuation of analysis,
241
such as syntax errors or critical import failures.
242
243
Attributes:
244
- messages: list[str] - Error messages
245
- use_stdout: bool - Whether to print to stdout
246
"""
247
248
class ErrorInfo:
249
"""
250
Contains information about individual errors.
251
252
Structured error data with precise location information
253
and categorization for tools and IDEs.
254
255
Attributes:
256
- file: str - Source file path
257
- line: int - Line number (1-based)
258
- column: int - Column number (1-based)
259
- message: str - Error message text
260
- severity: str - Error severity level
261
- error_code: ErrorCode | None - Associated error code
262
"""
263
```
264
265
## Error Code Categories
266
267
### Type Compatibility Errors
268
269
```python
270
# Examples of common type compatibility errors
271
272
# ASSIGNMENT - Variable assignment type mismatch
273
x: int = "hello" # Error: Incompatible types (expression has type "str", variable has type "int")
274
275
# ARG_TYPE - Function argument type mismatch
276
def greet(name: str) -> str:
277
return f"Hello, {name}!"
278
279
greet(42) # Error: Argument 1 has incompatible type "int"; expected "str"
280
281
# RETURN_VALUE - Return value type mismatch
282
def get_number() -> int:
283
return "not a number" # Error: Incompatible return value type (got "str", expected "int")
284
```
285
286
### Attribute and Name Errors
287
288
```python
289
# NAME_DEFINED - Undefined variable
290
print(undefined_variable) # Error: Name 'undefined_variable' is not defined
291
292
# ATTR_DEFINED - Undefined attribute
293
class Person:
294
def __init__(self, name: str):
295
self.name = name
296
297
person = Person("Alice")
298
print(person.age) # Error: "Person" has no attribute "age"
299
300
# UNION_ATTR - Union attribute access
301
from typing import Union
302
303
def process(value: Union[str, int]) -> str:
304
return value.upper() # Error: Item "int" of "Union[str, int]" has no attribute "upper"
305
```
306
307
### Function Call Errors
308
309
```python
310
# CALL_ARG - Wrong number of arguments
311
def add(x: int, y: int) -> int:
312
return x + y
313
314
add(1) # Error: Missing positional argument "y" in call to "add"
315
add(1, 2, 3) # Error: Too many positional arguments for "add"
316
317
# ARG_TYPE - Argument type mismatch
318
add("1", "2") # Error: Argument 1 has incompatible type "str"; expected "int"
319
```
320
321
### Generic Type Errors
322
323
```python
324
from typing import List, TypeVar
325
326
# TYPE_ARG - Generic type argument errors
327
numbers: List = [1, 2, 3] # Error: Missing type parameters for generic type "List"
328
329
# TYPE_VAR - Type variable constraint violations
330
T = TypeVar('T', int, str) # T can only be int or str
331
332
def process(value: T) -> T:
333
return value
334
335
process(3.14) # Error: Value of type variable "T" cannot be "float"
336
```
337
338
## Error Reporting and Formatting
339
340
### Error Message Structure
341
342
```python
343
def parse_error_message(message: str) -> dict:
344
"""Parse mypy error message into components."""
345
# Format: filename:line:column: level: message [error-code]
346
import re
347
348
pattern = r'([^:]+):(\d+):(\d+): (error|warning|note): (.+?)(?:\s+\[([^\]]+)\])?$'
349
match = re.match(pattern, message)
350
351
if match:
352
filename, line, column, level, text, error_code = match.groups()
353
return {
354
'file': filename,
355
'line': int(line),
356
'column': int(column),
357
'level': level,
358
'message': text,
359
'error_code': error_code
360
}
361
362
return {'raw_message': message}
363
364
# Example error message parsing
365
error_msg = "myfile.py:10:5: error: Incompatible types [assignment]"
366
parsed = parse_error_message(error_msg)
367
# {'file': 'myfile.py', 'line': 10, 'column': 5, 'level': 'error',
368
# 'message': 'Incompatible types', 'error_code': 'assignment'}
369
```
370
371
### Custom Error Handling
372
373
```python
374
from mypy.errors import Errors
375
from mypy.errorcodes import ErrorCode
376
377
class CustomErrorReporter:
378
"""Custom error reporter for specialized error handling."""
379
380
def __init__(self):
381
self.errors = Errors()
382
self.error_counts = {}
383
384
def report_error(self, line: int, column: int, message: str,
385
code: ErrorCode | None = None):
386
"""Report an error with custom processing."""
387
self.errors.report(line, column, message, code)
388
389
# Track error frequency
390
if code:
391
self.error_counts[code.code] = self.error_counts.get(code.code, 0) + 1
392
393
def get_error_summary(self) -> dict:
394
"""Get summary of error types and counts."""
395
return {
396
'total_errors': self.errors.num_messages(),
397
'error_breakdown': self.error_counts.copy(),
398
'has_errors': self.errors.is_errors()
399
}
400
401
def format_errors_json(self) -> str:
402
"""Format errors as JSON for tool integration."""
403
import json
404
405
errors = []
406
for msg in self.errors.format_messages():
407
parsed = parse_error_message(msg)
408
errors.append(parsed)
409
410
return json.dumps({
411
'errors': errors,
412
'summary': self.get_error_summary()
413
}, indent=2)
414
415
# Usage
416
reporter = CustomErrorReporter()
417
reporter.report_error(10, 5, "Type mismatch", ARG_TYPE)
418
419
summary = reporter.get_error_summary()
420
json_output = reporter.format_errors_json()
421
```
422
423
### Error Filtering and Processing
424
425
```python
426
from mypy.errorcodes import ErrorCode
427
428
class ErrorFilter:
429
"""Filter and categorize mypy errors."""
430
431
def __init__(self):
432
self.ignored_codes = set()
433
self.severity_levels = {
434
'critical': {SYNTAX, IMPORT},
435
'high': {ARG_TYPE, RETURN_VALUE, ASSIGNMENT},
436
'medium': {ATTR_DEFINED, NAME_DEFINED},
437
'low': {MISC, ANNOTATION_UNCHECKED}
438
}
439
440
def ignore_error_code(self, code: ErrorCode):
441
"""Ignore specific error code."""
442
self.ignored_codes.add(code)
443
444
def should_report(self, code: ErrorCode | None) -> bool:
445
"""Check if error should be reported."""
446
return code not in self.ignored_codes
447
448
def get_severity(self, code: ErrorCode | None) -> str:
449
"""Get severity level for error code."""
450
if not code:
451
return 'unknown'
452
453
for level, codes in self.severity_levels.items():
454
if code in codes:
455
return level
456
457
return 'medium' # Default severity
458
459
def filter_errors(self, error_messages: list[str]) -> list[dict]:
460
"""Filter and categorize error messages."""
461
filtered = []
462
463
for msg in error_messages:
464
parsed = parse_error_message(msg)
465
466
if 'error_code' in parsed:
467
code_name = parsed['error_code']
468
# Find ErrorCode object by name
469
code = next((c for c in globals().values()
470
if isinstance(c, ErrorCode) and c.code == code_name), None)
471
472
if self.should_report(code):
473
parsed['severity'] = self.get_severity(code)
474
filtered.append(parsed)
475
476
return filtered
477
478
# Usage
479
error_filter = ErrorFilter()
480
error_filter.ignore_error_code(MISC) # Ignore miscellaneous errors
481
482
errors = [
483
"myfile.py:10:5: error: Incompatible types [assignment]",
484
"myfile.py:15:2: error: Missing import [misc]"
485
]
486
487
filtered = error_filter.filter_errors(errors)
488
# Only assignment error will be included, misc error filtered out
489
```
490
491
## Integration with Development Tools
492
493
### IDE Integration
494
495
```python
496
class IDEErrorReporter:
497
"""Error reporter optimized for IDE integration."""
498
499
def __init__(self):
500
self.diagnostics = []
501
502
def process_mypy_output(self, output: str) -> list[dict]:
503
"""Convert mypy output to IDE diagnostic format."""
504
diagnostics = []
505
506
for line in output.strip().split('\n'):
507
if not line:
508
continue
509
510
parsed = parse_error_message(line)
511
if 'file' in parsed:
512
diagnostic = {
513
'range': {
514
'start': {
515
'line': parsed['line'] - 1, # 0-based for LSP
516
'character': parsed['column'] - 1
517
},
518
'end': {
519
'line': parsed['line'] - 1,
520
'character': parsed['column'] + 10 # Approximate end
521
}
522
},
523
'severity': 1 if parsed['level'] == 'error' else 2, # LSP severity
524
'message': parsed['message'],
525
'source': 'mypy',
526
'code': parsed.get('error_code', 'unknown')
527
}
528
diagnostics.append(diagnostic)
529
530
return diagnostics
531
532
# Usage in LSP server
533
ide_reporter = IDEErrorReporter()
534
diagnostics = ide_reporter.process_mypy_output(mypy_output)
535
# Send diagnostics to IDE client
536
```
537
538
### CI/CD Integration
539
540
```python
541
import subprocess
542
import json
543
544
class CIErrorReporter:
545
"""Error reporter for CI/CD pipelines."""
546
547
def run_mypy_with_json_output(self, files: list[str]) -> dict:
548
"""Run mypy and return structured error data."""
549
try:
550
result = subprocess.run(
551
['mypy', '--show-error-codes'] + files,
552
capture_output=True,
553
text=True
554
)
555
556
errors = []
557
if result.stderr:
558
for line in result.stderr.strip().split('\n'):
559
parsed = parse_error_message(line)
560
if 'file' in parsed:
561
errors.append(parsed)
562
563
return {
564
'success': result.returncode == 0,
565
'exit_code': result.returncode,
566
'errors': errors,
567
'error_count': len(errors),
568
'stdout': result.stdout,
569
'stderr': result.stderr
570
}
571
572
except FileNotFoundError:
573
return {
574
'success': False,
575
'error': 'mypy not found - please install mypy'
576
}
577
578
def generate_junit_xml(self, results: dict, output_file: str):
579
"""Generate JUnit XML report for CI systems."""
580
import xml.etree.ElementTree as ET
581
582
testsuite = ET.Element('testsuite', {
583
'name': 'mypy',
584
'tests': str(len(results.get('errors', []))),
585
'failures': str(len([e for e in results.get('errors', [])
586
if e.get('level') == 'error'])),
587
'errors': '0'
588
})
589
590
for error in results.get('errors', []):
591
testcase = ET.SubElement(testsuite, 'testcase', {
592
'name': f"{error['file']}:{error['line']}",
593
'classname': 'mypy'
594
})
595
596
if error.get('level') == 'error':
597
failure = ET.SubElement(testcase, 'failure', {
598
'message': error['message'],
599
'type': error.get('error_code', 'unknown')
600
})
601
failure.text = f"Line {error['line']}: {error['message']}"
602
603
tree = ET.ElementTree(testsuite)
604
tree.write(output_file, encoding='utf-8', xml_declaration=True)
605
606
# Usage in CI pipeline
607
ci_reporter = CIErrorReporter()
608
results = ci_reporter.run_mypy_with_json_output(['src/'])
609
610
if not results['success']:
611
print(f"Type checking failed with {results['error_count']} errors")
612
ci_reporter.generate_junit_xml(results, 'mypy-results.xml')
613
exit(1)
614
```
615
616
## Error Code Reference
617
618
### Complete Error Code List
619
620
```python
621
# Core type errors
622
ASSIGNMENT = ErrorCode("assignment", "Assignment type mismatch", "types")
623
ARG_TYPE = ErrorCode("arg-type", "Argument type mismatch", "types")
624
RETURN_VALUE = ErrorCode("return-value", "Return value type mismatch", "types")
625
626
# Attribute and name errors
627
ATTR_DEFINED = ErrorCode("attr-defined", "Accessing undefined attributes", "names")
628
NAME_DEFINED = ErrorCode("name-defined", "Using undefined names", "names")
629
630
# Function call errors
631
CALL_ARG = ErrorCode("call-arg", "Function call argument errors", "calls")
632
TYPE_ARG = ErrorCode("type-arg", "Generic type argument errors", "generics")
633
634
# Advanced type system errors
635
UNION_ATTR = ErrorCode("union-attr", "Union attribute access errors", "unions")
636
OVERRIDE = ErrorCode("override", "Method override errors", "inheritance")
637
INDEX = ErrorCode("index", "Indexing operation errors", "operators")
638
OPERATOR = ErrorCode("operator", "Operator usage errors", "operators")
639
640
# Import and module errors
641
IMPORT = ErrorCode("import", "Import-related errors", "imports")
642
IMPORT_UNTYPED = ErrorCode("import-untyped", "Untyped module imports", "imports")
643
644
# Annotation and syntax errors
645
VALID_TYPE = ErrorCode("valid-type", "Invalid type expressions", "annotations")
646
ANNOTATION_UNCHECKED = ErrorCode("annotation-unchecked", "Unchecked annotations", "annotations")
647
SYNTAX = ErrorCode("syntax", "Python syntax errors", "syntax")
648
649
# Control flow errors
650
RETURN = ErrorCode("return", "Return statement errors", "control-flow")
651
NO_RETURN = ErrorCode("no-return", "Missing return statements", "control-flow")
652
UNREACHABLE = ErrorCode("unreachable", "Unreachable code", "control-flow")
653
654
# Miscellaneous
655
MISC = ErrorCode("misc", "Miscellaneous errors", "general")
656
```