Skip to content

Type checking directive used

Detects usage of type checking directives in comments, which suppress type checker warnings and may hide potential type errors.

Type checking directives like # type: ignore tell type checkers to skip validation of specific lines or sections of code. While sometimes necessary, they can mask real bugs that would otherwise be caught during static analysis.

What gets flagged

We detect directives from the major Python type checkers:

mypy / Standard (PEP 484)

Python
1
2
3
res = foo()  # type: ignore

res = foo()  # type: ignore[name-defined]
Unsoundness Checker Output
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
warning[type-checking-directive-used]: Type checking directive `type: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:1:14
  |
1 | res = foo()  # type: ignore
  |              ^^^^^^^^^^^^^^
2 |
3 | res = foo()  # type: ignore[name-defined]
  |
info: rule `type-checking-directive-used` was selected in the configuration file

warning[type-checking-directive-used]: Type checking directive `type: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:3:14
  |
1 | res = foo()  # type: ignore
2 |
3 | res = foo()  # type: ignore[name-defined]
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
info: rule `type-checking-directive-used` was selected in the configuration file

pyright

Python
1
2
3
res = foo()  # pyright: ignore

res = foo()  # pyright: ignore[reportUndefinedVariable]
Unsoundness Checker Output
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
warning[type-checking-directive-used]: Type checking directive `pyright: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:1:14
  |
1 | res = foo()  # pyright: ignore
  |              ^^^^^^^^^^^^^^^^^
2 |
3 | res = foo()  # pyright: ignore[reportUndefinedVariable]
  |
info: rule `type-checking-directive-used` was selected in the configuration file

warning[type-checking-directive-used]: Type checking directive `pyright: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:3:14
  |
1 | res = foo()  # pyright: ignore
2 |
3 | res = foo()  # pyright: ignore[reportUndefinedVariable]
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
info: rule `type-checking-directive-used` was selected in the configuration file

ty

Python
1
2
3
res = foo()  # ty: ignore

res = foo()  # ty: ignore[unresolved-reference]
Unsoundness Checker Output
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
warning[type-checking-directive-used]: Type checking directive `ty: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:1:14
  |
1 | res = foo()  # ty: ignore
  |              ^^^^^^^^^^^^
2 |
3 | res = foo()  # ty: ignore[unresolved-reference]
  |
info: rule `type-checking-directive-used` was selected in the configuration file

warning[type-checking-directive-used]: Type checking directive `ty: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:3:14
  |
1 | res = foo()  # ty: ignore
2 |
3 | res = foo()  # ty: ignore[unresolved-reference]
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
info: rule `type-checking-directive-used` was selected in the configuration file

pyrefly

Python
1
2
3
res = foo()  # pyrefly: ignore

res = foo()  # pyrefly: ignore[unknown-name]
Unsoundness Checker Output
Text Only
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
warning[type-checking-directive-used]: Type checking directive `pyrefly: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:1:14
  |
1 | res = foo()  # pyrefly: ignore
  |              ^^^^^^^^^^^^^^^^^
2 |
3 | res = foo()  # pyrefly: ignore[unknown-name]
  |
info: rule `type-checking-directive-used` was selected in the configuration file

warning[type-checking-directive-used]: Type checking directive `pyrefly: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:3:14
  |
1 | res = foo()  # pyrefly: ignore
2 |
3 | res = foo()  # pyrefly: ignore[unknown-name]
  |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
info: rule `type-checking-directive-used` was selected in the configuration file

Why this matters

Type checking directives bypass the safety guarantees that static type checking provides. For example:

Python
1
2
3
4
5
def calculate_total(items: list[int]) -> int:
    return sum(items)

# This will fail at runtime, but the directive hides the error
result = calculate_total("not a list")  # type: ignore
Unsoundness Checker Output
Text Only
1
2
3
4
5
6
7
8
warning[type-checking-directive-used]: Type checking directive `type: ignore` suppresses type checker warnings, which may hide potential type errors.
 --> main.py:5:41
  |
4 | # This will fail at runtime, but the directive hides the error
5 | result = calculate_total("not a list")  # type: ignore
  |                                         ^^^^^^^^^^^^^^
  |
info: rule `type-checking-directive-used` was selected in the configuration file

When directives might be necessary

There are legitimate cases where type checking directives are needed:

  • Working with dynamic third-party libraries that lack type stubs
  • Temporary workarounds during incremental type adoption

However, these should be rare and well-documented exceptions, not the norm.