Skip to content
Search

Mypy

lastmod 2025-05-29created 2019-04-1129 edits

Mypy is an experimental optional static type checker for Python that aims to combine the benefits of dynamic (or "duck") typing and static typing. Mypy combines the expressive power and convenience of Python with a powerful type system and compile-time type checking. Mypy type checks standard Python programs; run them using any Python VM with basically no runtime overhead.

Categories

Ignoring errors

Add the module name to the mypy.ini config file

Inline ignoring

Inline configuration comments take precedence over all other configuration mechanisms.

Whole-file comments

Add a # mypy: ignore-errors comment at the top of the file.

How to comment individual options:

# mypy: disallow-any-generics
# mypy: always-true=FOO

Multiple flags can be separated by commas or placed on separate lines. To include a comma as part of an option's value, put the value in quotes.

# mypy: disallow-untyped-defs, always-false="FOO,BAR"

As in the config file, options that take a boolean value can be inverted by adding no- to the name or (where applicable) by swapping the prefix disallow (or allow).

# mypy: allow-untyped-defs, no-strict-optional

If you used # type: ignore[call-overload] as an inline ignore, you can write # mypy: disable-error-code="call-overload" at the top of the file instead.

To use multiple ignores: use something like # mypy: disable-error-code="call-overload, operator, attr-defined".

Specific-line comments

Add # type: ignore to the end of the line.

To ignore only a specific warning:

# type: ignore[override]

Specific folder/package comments

In the mypy.ini file:

# mypy configuration

[mypy]
ignore_missing_imports = True
show_error_context = True
show_column_numbers = True
show_error_codes = True
pretty = True

# '/' 으로 시작하지 않는다.
exclude = (\.git|\.venv|scot/assets)

[mypy-reccd.proto.*]
ignore_errors = True

protobuf compatibility

Install mypy-protobuf. See that page for details.

Invariance vs covariance

Code written like this:

def f_bad(x: List[A]) -> A:
    return x[0]
f_bad(new_lst) # Fails

should be changed to this:

def f_good(x: Sequence[A]) -> A:
    return x[0]
f_good(new_lst) # OK

Troubleshooting

Library stubs not installed

recc/core/http_client.py:3:1: error: Library stubs not installed for "requests"
(or incompatible with Python 3.8)  [import]
    import requests
    ^
recc/core/http_client.py:3:1: note: Hint: "python3 -m pip install types-requests"
recc/log/logging.py:112:1: error: Library stubs not installed for "yaml" (or
incompatible with Python 3.8)  [import]
            import yaml
    ^
recc/driver/json.py:45:1: error: Library stubs not installed for "orjson" (or
incompatible with Python 3.8)  [import]
            import orjson
    ^
recc/driver/json.py:45:1: note: Hint: "python3 -m pip install types-orjson"
recc/config/yamlparse.py:3:1: error: Library stubs not installed for "yaml" (or
incompatible with Python 3.8)  [import]
    import yaml
    ^
recc/config/yamlparse.py:3:1: note: Hint: "python3 -m pip install types-PyYAML"
recc/config/yamlparse.py:3:1: note: (or run "mypy --install-types" to install all missing stub packages)
recc/config/yamlparse.py:3:1: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
recc/util/lib_versions.py:3:1: error: Library stubs not installed for
"google.protobuf" (or incompatible with Python 3.8)  [import]
    from google.protobuf import __version__ as protobuf_version_text
    ^
recc/util/lib_versions.py:3:1: note: Hint: "python3 -m pip install types-protobuf"
recc/util/lib_versions.py:6:1: error: Library stubs not installed for "orjson"
(or incompatible with Python 3.8)  [import]
    from orjson import __version__ as orjson_version_text
    ^
Found 6 errors in 5 files (checked 296 source files)

Either install them all at once like this,

mypy --install-types

or install them one by one:

python3 -m pip install types-requests
python3 -m pip install types-orjson
python3 -m pip install types-PyYAML
python3 -m pip install types-protobuf

"List" is invariant

recc/core/context.py:242:20: error: Argument "allows" to "CorePluginManager" has incompatible type "List[str]"; expected
"Optional[List[Union[str, Pattern[Any]]]]"  [arg-type]
                allows=self._config.core_plugin_allow,
                       ^
recc/core/context.py:242:20: note: "List" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
recc/core/context.py:242:20: note: Consider using "Sequence" instead, which is covariant

See #Invariance vs covariance.

By default the bodies of untyped functions are not checked

tester/obj/test_numpy.py:40:13: note: By default the bodies of untyped functions are not checked, consider using --check-untyped-defs  [annotation-unchecked]

Types defined Nested inside a function (e.g. class definitions) are not analyzed. Move them outside.

note: "Dict" is invariant

cvp/flow/runner.py: note: In member "_execute_node" of class "FlowRunner":
cvp/flow/runner.py:280:30: error: Argument "shared_variables" to "create_record" of "FlowRunner" has incompatible type "dict[str, FlowVariable[Any]]";
expected "dict[str, ValueProxy[Any]] | None"  [arg-type]
                shared_variables=graph.variables.as_dict(),
                                 ^~~~~~~~~~~~~~~~~~~~~~~~~
cvp/flow/runner.py:280:30: note: "Dict" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
cvp/flow/runner.py:280:30: note: Consider using "Mapping" instead, which is covariant in the value type

Dict is an invariant type, so it has to be converted directly. Mapping is a covariant type, so change Dict to Mapping.

See also

Favorite site

author Zer0 sitemap