본문 바로가기
파이썬/문법 및 오류 잡기

Mypy를 사용한 타입 힌팅

by David.Ho 2023. 1. 16.
728x90
반응형

Mypy는 파이썬에서 가장 일반적으로 사용하는 정적 타입 검사 도구입니다.

mypy를 설치하면 프로젝트의 모든 파일을 분석하여 타입 불일치를 검사해줍니다. 버그를 조기에 발견할 수 있기 때문에 유용하지만 가끔 잘못 탐지하는 경우도 있습니다.

pip를 사용해 설치할 수 있으며 프로젝트 셋업 파일에 종속성을 추가하는 것이 좋습니다.

1
$ pip install mypy
cs

 

가상환경에 mypy를 설치하고 mypy [파일명]을 입력하면 타입 검사 결과를 제공합니다. 여기서 보고된 대부분의 내용은 가능한 준수하는 것이 좋습니다. 왜냐하면 실제 상용화 시 문제가 재현될 수 있기 때문입니다. 잘못된 탐지를 하는 경우가 인쓴데, 문장 끝에 다음과 같이 주석을 추가하여 mypy가 무시하도록 할 수 있습니다.

Mypy 예제1 - Type Annotation error

Mypy에서 Type Annotation이 명시되어 있지 않은 경우 에러를 유발합니다.

다음은 파일명을 입력받아서 해당 파일에 있는 단어들을 카운트하는 파이썬 코드입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# mypy_test.py
# Display the frequencies of words in a file.
 
import sys
import re
 
 
if not sys.argv[1:]:
    raise RuntimeError('Usage: wordfreq FILE')
 
= {}
 
with open(sys.argv[1]) as f:
    for s in f:
        for word in re.sub('\W'' ', s).split():
            d[word] = d.get(word, 0+ 1
 
# Use list comprehension
= [(freq, word) for word, freq in d.items()]
 
for freq, word in sorted(l):
    print('%-6d %s' % (freq, word))
cs

 

위의 파일을 mypy로 실행하면 다음과 같이 경고합니다.

11번 줄의 dict 변수 d 에 대한 type annotation이 필요하다고 합니다.

Mypy의 검사에 통과하기 위해서 11번 줄을 다음과 같이 변경합니다.

1
= {}  # type: Dict[strint]
cs

 

dict의 key는 str이며, value는 int 타입이라는 힌트를 준 것입니다.  따라서 변경된 소스코드는 다음과 같습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# mypy_test.py
# Display the frequencies of words in a file.
 
import sys
import re
from typing import Dict
 
if not sys.argv[1:]:
    raise RuntimeError('Usage: wordfreq FILE')
 
= {}  # type: Dict[str, int]
 
with open(sys.argv[1]) as f:
    for s in f:
        for word in re.sub('\W'' ', s).split():
            d[word] = d.get(word, 0+ 1
 
# Use list comprehension
= [(freq, word) for word, freq in d.items()]
 
for freq, word in sorted(l):
    print('%-6d %s' % (freq, word))
cs

 

Mypy 예제2 - 오류 검사

mypy는 런타임 에러를 유발할 수 있는 오류도 검사합니다.

다음과 같이 두 정수를 입력 받아 두 정수의 곱을 하는 myMultiply() 함수가 있습니다.

1
2
3
4
def myMultiply(n1: int, n2: int-> int:
    return n1 * n2
 
print(myMultiply("1""2"))
cs

 

이 함수의 인자로 정수가 아닌 문자열을 전달하는 경우 문자열 끼리 곱셈은 불가능하기 때문에 런타임 오류가 발생합니다.

런타임 에러

이 파일을 Mypy로 실행하면 다음과 같이  잘못된 인자가 입력되었다는 것을 알려줍니다.

 

이처럼 Mypy를 사용하면 코드에 대한 정적 타입 체크를 해주고 인터프리터가 잡지 못하는 에러 또한 탐지할 수 있습니다. 

728x90
반응형

댓글