목차

  • mypy에 대하여
  • mypy 사용법
  • mypy 활용 예제
  • 실전 프로젝트 활용

1. mypy에 대하여

mypy는 python에서 정적 타입 힌트를 검사해주는 타입 검사기이다. 코드를 실행하지 않고 타입 오류를 확인해주는 역할을 합니다.

2. mypy 사용법

2-0. 설치 방법

$ pip3 install mypy
 
# 제대로 설치 되었는지 확인
$ mypy --version
mypy 2.1.0 (compiled: yes)

2-1. 설정 파일 만들기

  • 프로젝트 루트 위치에 pyproject.toml을 두고 작성합니다.
[tool.mypy]
python_version = "3.14"
disallow_untyped_defs = true
no_implicit_optional = true
warn_unused_ignores = true

옵션

  • disallow_untyped_defs = true

    • 새로 만들어진 함수는 무조건 타입 힌트를 작성하도록 규칙 설정.
  • no_implicit_optional = true

    • None을 허용할 때 Optional을 명시하도록 규칙 설정.
  • strict_optional = true

    • None 관련 처리를 확인
  • warn_unused_ignores = true

    • 필요 없는 # type: ignore 주석을 알려줌.
  • warn_return_any = true

    • 함수가 Any 타입을 반환하는 경우를 경고함.
  • check_untyped_defs = true

    • 타입 힌트가 없는 함수 내부도 검사함.
  • ignore_missing_imports = true

    • 타입 정보를 찾을 수 없는 외부 라이브러리 import 오류를 무시함.
  • disallow_any_generics = true

    • list, dict처럼 타입 인자가 빠진 제네릭 사용을 막음.
  • strict = true

    • 여러 엄격한 검사 옵션을 한 번에 켬.
  • warn_redundant_casts = true

    • 불필요한 cast() 사용을 경고함.
  • pretty = true

    • 오류 메시지를 보기 좋게 출력하고, 코드 위치 표시를 함께 보여줌.
  • exclude = “tests/”

    • 검사에서 제외할 파일이나 디렉터리를 정규식으로 지정함.

2-3. 실행 방법

python3 -m mypy .
  • python3 -m mypy . : 전체 코드 검사
    • 성공하면 : Success : no issues found
    • 실패하면 : 어디 파일에 몇번째 줄에서 무슨 이유로 오류가 발생하는지 알려줌.

3. mypy 기능

3-1. 타입 검사

number: int = "1"
print(number)

만약 다음과 같은 코드가 있다고 가정하겠습니다.

실제 해당 코드를 실행한다면 다음과 같이 정상 실행되는 모습을 볼수 있습니다.

python error1.py
1

위 코드가 정상 작동하는 이유는 어노테이션은 언어 레벨에서는 코드 실행에 아무 영향이나 제약을 주지않기 때문입니다. 따라서 개발자가 위와 같은 문제를 해결하기 위해서 소외 타입 헌팅이라고 하는 주로 코드를 읽기 쉽게 하거나, 코드 편집기나 린트(linter)에서 활용합니다.

mypy를 이용해서 해당 python 코드를 실행할 한다면,

$ mypy error.py
test1.py:1: error: Incompatible types in assignment (expression has type "str", variable has type "int")
Found 1 error in 1 file (checked 1 source file)

와 같은 결과를 받을수 있으며, 이를 통해서 개발자를 언어 레벨에도 타입 오류를 쉽게 찾을수 있습니다.

3-2. 오류 예방

Mypy를 통해서 실제 런타임 오류를 미리 알아낼수 있습니다.

from typing import List
 
def repeat(message: str, times: int = 2) -> List[str]:
    return [message] * times
 
repeat("Hi", "3")

위 코드에는 repeat이라는 함수에 2번재 인자가 str이 아닌 int를 받는 것을 볼수 있습니다. 하지만 함수 호출에서 보내는 값은 “3”이라는 문자열을 보내고 있습니다.

$ mypy test2.py
test2.py:7: error: Argument 2 to "repeat" has incompatible type "str"; expected "int"
Found 1 error in 1 file (checked 1 source file)

mypy는 이러한 런타임 시점에서의 오류 또한 탐지하고 알려줍니다.

3-3. 검사 예외

python으로 개발 하는 과정에서 타입을 무시해야 하는 경우가 생길수 있다. 이 경우 # type: ignore이를 주석을 통해서 타입 검사에서 제외시키는 방법이 존재한다.

number: int = "1" # type: ignore
print(number)

파일 전체에서 타입 검사를 스킵하고 싶으면 # mypy: ignore-errors를 통해서 파일 전체를 타입 검사에서 제외 시키는 것이 가능하다.

# mypy: ignore-erros
number: int = "1"
number2: int = "2"
 
print(number1 + number2)

4. 실전 프로젝트 활용

RECCONIZATION-DETECTOR

recconization-detector는 한 IP에서 발생하는 트래픽을 모아서 해당 트래픽의 패턴이 reconnization을 수행하는지 아닌지를 나이브 베이즈 분류기를 활용해서 분류하는 프로젝트이다. 해당 프로젝트에서 나이브 베이즈 분류기를 이용해서 트래픽 분류를 위한 프로그램에 python 언어를 활용해서 만들었으며 이 과정에서 mypy를 활용하여 타입 오류 및 런타임 단계 오류를 빠르게 찾아내 수정하였습니다.

[tool.mypy]
python_version = "3.14"
disallow_untyped_defs = true
no_implicit_optional = true
strict_optional = true
warn_unused_ignores = true
warn_redundant_casts = true
warn_return_any = true
pretty = true