Skip to content

Mypy

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

예외처리

mypy.ini 설정 파일에 모듈명 추가

인라인 예외 처리

인라인 구성 주석은 다른 모든 구성 메커니즘보다 우선합니다.

파일 전체 주석

파일 상단에 # mypy: ignore-errors 주석 추가.

개별 옵션 주석 처리 방법:

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

여러 플래그는 쉼표로 구분하거나 별도의 줄에 배치할 수 있습니다. 옵션 값의 일부로 쉼표를 포함하려면 값을 따옴표 안에 넣으십시오.

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

구성 파일에서와 마찬가지로 부울 값을 사용하는 옵션은 이름에 no-를 추가하거나 (해당되는 경우) 접두사를 disallow(또는 allow)로 교체하여 반전할 수 있습니다.

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

만약 인라인 예외로 # type: ignore[call-overload]를 썼다면 파일 상단에 # mypy: disable-error-code="call-overload"를 싸면 된다.

여러 예외를 사용하고 싶다면: # mypy: disable-error-code="call-overload, operator, attr-defined" 같이 사용.

특정 라인 주석

해당 라인 끝에 # type: ignore 추가.

특정 경고만 예외처리하고 싶을 경우:

# type: ignore[override]

특정 폴더/패키지 주석

mypy.ini파일에:

# 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 호환성

mypy-protobuf를 설치하면 된다. 자세한 내용은 해당 항목 참조.

Invariance vs covariance

다음과 같이 되어있는 코드는:

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

다음과 같이 바꿔야 한다:

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)

다음과 같이 한번에 설치하거나,

mypy --install-types

따로 따로 설치한다:

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

#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]

함수 안에 Nested 로 정의된 타입(e.g. 클래스 정의부)은 분석대상이 안된다. 외부로 빼자.

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 는 불변 타입이라 직접 변환해야 한다. 따라서 Mapping 을 사용하면 공변 타입을 사용하므로 Dict 를 Mapping 으로 수정하자.

See also

Favorite site