파이썬 타입 체크 - Mypy
Jun 6, 2020 · 4 min read



파이썬 버전 3.5에 추가된 타입 어노테이션(type annotation) 덕분에 파이썬에서도 Mypy와 같은 도구를 통해서 타입 체크가 가능해졌습니다.

파이썬의 타입 어노테이션에 대한 자세한 설명은 관련 포스트를 참고바라겠습니다.

타입 어노테이션 / 타입 체크

파이썬과 같이 동적(dynamic) 프로그래밍 언어에서 정적(static) 타입 체크가 왠 말이냐고 생각하시는 분들이 있으실 것 같습니다.
파이썬의 동적 타입 처리는 유연함은 일회성 스크립트나 소규모의 애플리케이션을 빠르게 개발할 때는 큰 장점으로 작용합니다.
하지만 애플리케이션이 규모가 커지게 되면 이러한 파이썬의 다이나믹함이 치명적인 버그로 이어질 확률이 높아지게 되며 애플리케이션 안정성에 위험 요소가 되기도 합니다.

타입 어노테이션(type annotation)은 파이썬 코드에 타입을 명시하기 위한 표준을 정립하기 위해서 파이썬 3.5에 추가되어 있습니다.
이 표준에 따라 변수나 함수에 타입이 명시된 파이썬 코드는 정적 타입 검사기(static type checker)를 통해 코드를 실행하지 않고도 타입 에러를 찾아낼 수 있습니다.

Mypy 설치 및 실행

Mypy는 파이썬에서 가장 많이 사용되고 있는 정적 타입 검사 도구입니다.
타입 어노테이션이 추가된 파이썬 코드를 상대로 Mypy를 돌리면 타입 에러를 찾아내줍니다.

Mypy는 pip으로 손쉽게 설치할 수 있습니다.

$ pip install mypy

Mypy를 터미널에서 실행할 때는 파일이나 디렉토리명을 인자로 넘기면 됩니다.

$ mypy our_file.py our_directory

타입 검사

실습을 위해 test.py 파일을 생성하고 다음과 같이 매우 간단한 파이썬 코드를 작성해보겠습니다.
no 변수의 타입을 int로 명시하기 위해서 타입 어노테이션을 추가하였습니다.

no: int = "1"
print(no)

이 코드를 파이썬 인터프리터로 실행해보면 다음과 같이 문제없이 잘 돌아갑니다. 😰

python test.py
1

왜냐하면 타입 어노테이션은 언어 레벨에서는 코드 실행에 아무 영향이나 제약을 주지않기 때문입니다.
이렇게 타입 어노테이션을 사용하는 것을 소외 타입 힌팅(type hinting)이라고 하는데 주로 코드를 읽기 쉽게 하거나, 코드 편집기(IDE)나 린터(linter)에서 활용됩니다.

이 코드를 다시 Mypy로 돌려보면 변수의 타입과 변수에 저장된 값의 타입이 다르다고 타입 에러가 발생합니다.

$ mypy test.py
test.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)

이렇게 Mypy를 사용하면 파이썬 인터프리터가 잡지 못하는 타입 버그를 쉽게 찾아낼 수 있습니다. 🐛

오류 검사

Mypy를 사용하면 위와 같이 타입 자체의 버그분만 아니라 실제로 런타임에 발생할 수 있는 오류를 미리 알아낼 수도 있습니다.

예를 들어, test.py 파일에 다음과 같이 파이썬 함수를 작성해보겠습니다.
함수의 인자 타입과 반환 타입을 명시하기 위해서 타입 어노테이션으로 해주었습니다.

def repeat(message: str, times: int = 2) -> list:
    return [message] * times


repeat("Hi", "3")

이 코드를 파이썬 인터프리터로 실행해보면 repeat() 함수의 두 번째 인자로 숫자가 아닌 문자 타입의 인자가 넘어가기 때문에 오류가 발생하게 됩니다. 😞

$ python test.py
Traceback (most recent call last):
  File "test.py", line 5, in <module>
    repeat("Hi", "3")
  File "test.py", line 2, in repeat
    return [message] * times
TypeError: can't multiply sequence by non-int of type 'str'

이 코드를 Mypy로 돌려보면 이미 이 코드에서 이러한 오류가 발생할 것이라는 것을 알려줍니다.

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

이렇게 Mypy를 사용하면 많은 오류를 애플리케이션을 실행 전에 찾아내고 예방할 수 있습니다. 👍

Mypy 설정

Mypy 설정은 실행 시 커맨드에 옵션을 넘길 수도 있고, 설정 파일을 이용할 수도 있습니다.
Mypy를 프로젝트에 통합해서 사용하는 경우, 매번 커맨드에 옵션을 넘기는 것 보다는 설정 파일을 이용하는 편이 편리할 것입니다.

설정 파일은 프로젝트 최상위 디렉토리의 mypy.ini 또는 .mypy.ini, setup.cfg를 사용하도록 되어 있습니다.
예를 들어, apptests 디렉토리의 모든 파일을 타입 체크하되 일부 디렉토리를 제외하고 싶다면 다음과 같이 설정할 수 있습니다.

[mypy]
files = app,tests
show_error_context = True
show_column_numbers = True
show_error_codes = True
pretty = True

[mypy-app.*.migrations.*]
ignore_errors = True

이와 같이 모듈 레벨에서 상세 설정이 가능하기 때문에 기존에 타입 에러가 있는 프로젝트에서 Mypy를 사용하는데 지장이 없습니다.

마치면서

이상으로 파이썬 코드에 대한 정적 타입 체크를 해주고 런타임 오류를 미리 찾아내주는 유용한 도구인 Mypy에 대해서 알아보았습니다.

Mypy는 타입 어노테이션을 사용하지 않는 프로젝트에서도 점진적으로 사용할 수 있도록 타입 어노테이션이 추가되지 않은 코드는 무시하도록 되어 있습니다.
따라서 신규 프로젝트 뿐만 아니라 기존 프로젝트에서도 특히 프로젝트 규모가 크다면 코드 품질과 애플리케이션 안정성을 위해서 Mypy 사용을 추천드리고 싶습니다.






Engineering Blog  by Dale Seo