Mypy
Pydantic은 기본적으로 mypy 와 잘 작동합니다.
그러나 Pydantic에는 코드 유형 검사 기능을 향상시키는 여러 가지 중요한 Pydantic 관련 기능을 mypy에 추가하는 mypy 플러그인도 함께 제공됩니다.
예를 들어 다음 스크립트를 고려해보세요.
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel
class Model(BaseModel):
age: int
first_name = 'John'
last_name: Optional[str] = None
signup_ts: Optional[datetime] = None
list_of_ints: List[int]
m = Model(age=42, list_of_ints=[1, '2', b'3'])
print(m.middle_name) # not a model field!
Model() # will raise a validation error for age and list_of_ints
특별한 구성이 없으면 mypy는 누락된 모델 필드 주석을 포착하지 못하고 Pydantic이 올바르게 구문 분석하는 list_of_ints
인수에 대해 경고합니다.
test.py:15: error: List item 1 has incompatible type "str"; expected "int" [list-item]
test.py:15: error: List item 2 has incompatible type "bytes"; expected "int" [list-item]
test.py:16: error: "Model" has no attribute "middle_name" [attr-defined]
test.py:17: error: Missing named argument "age" for "Model" [call-arg]
test.py:17: error: Missing named argument "list_of_ints" for "Model" [call-arg]
그러나 플러그인을 활성화하면 올바른 오류가 발생합니다.
9: error: Untyped fields disallowed [pydantic-field]
16: error: "Model" has no attribute "middle_name" [attr-defined]
17: error: Missing named argument "age" for "Model" [call-arg]
17: error: Missing named argument "list_of_ints" for "Model" [call-arg]
pydantic mypy 플러그인을 사용하면 필드 이름이나 유형이 변경되면 mypy가 실수를 잡아낼 것이라는 점을 알고 모델을 두려움 없이 리팩토링할 수 있습니다.
다른 혜택도 있어요! 자세한 내용은 아래를 참조하세요.
플러그인 없이 mypy 사용하기¶
다음을 사용하여 mypy를 통해 코드를 실행할 수 있습니다.
mypy \
--ignore-missing-imports \
--follow-imports=skip \
--strict-optional \
pydantic_mypy_test.py
엄격한 선택사항¶
--strict-optional
사용하여 코드를 전달하려면 None
이 기본값인 모든 필드에 대해 Optional[]
또는 Optional[]
별칭을 사용해야 합니다. (이것은 mypy의 표준입니다.)
기타 Pydantic 인터페이스¶
Pydantic 데이터 클래스 와 validate_call
데코레이터 도 mypy와 잘 작동합니다.
Mypy 플러그인 기능¶
Model.__init__
에 대한 서명 생성¶
- 동적으로 결정된 별칭이 없는 필수 필드는 필수 키워드 인수로 포함됩니다.
Config.populate_by_name=True
인 경우 생성된 서명은 별칭이 아닌 필드 이름을 사용합니다.Config.extra='forbid'
이고 동적으로 결정된 별칭을 사용하지 않는 경우 생성된 서명은 예기치 않은 입력을 허용하지 않습니다.- 선택 사항:
init_forbid_extra
플러그인 설정이True
로 설정된 경우Config.extra
가'forbid'
아니더라도__init__
에 대한 예기치 않은 입력으로 인해 오류가 발생합니다. - 선택 사항:
init_typed
플러그인 설정이True
로 설정된 경우 생성된 서명은 모델 필드의 유형을 사용합니다(그렇지 않으면 구문 분석을 허용하기 위해Any
로 주석이 추가됩니다).
Model.model_construct
에 대한 형식화된 서명 생성¶
model_construct
메소드는 입력 데이터가 유효하고 구문 분석되어서는 안 되는 경우__init__
의 대안입니다. 이 방법은 런타임 유효성 검사를 수행하지 않기 때문에 오류를 감지하려면 정적 검사가 중요합니다.
존중 Config.frozen
¶
Config.frozen
이True
인 경우 모델 필드의 값을 변경하려고 하면 mypy 오류가 발생합니다. 참조. 가짜 불변성 .
dataclasses
에 대한 서명 생성¶
- 장식된 수업
@pydantic.dataclasses.dataclass
표준 Python 데이터 클래스와 동일하게 유형이 검사됩니다. - 그만큼
@pydantic.dataclasses.dataclass
데코레이터는Config
하위 클래스 와 동일한 의미를 갖는config
키워드 인수를 허용합니다.
Field
의 default
및 default_factory
유형을 존중합니다.¶
default
과default_factory
모두 있는 필드는 정적 검사 중에 오류가 발생합니다.default
및default_factory
값의 유형은 해당 필드 중 하나와 호환되어야 합니다.
유형이 지정되지 않은 필드 사용에 대해 경고¶
- 해당 유형에 주석을 달지 않고 모델에 공개 속성을 할당할 때마다 mypy 오류가 발생합니다.
- 목표가 ClassVar를 설정하는 것이라면 Typing.ClassVar를 사용하여 필드에 명시적으로 주석을 달아야 합니다.
선택적 기능:¶
필수 동적 별칭 사용 방지¶
warn_required_dynamic_aliases
플러그인 설정 이True
로 설정된 경우Config.populate_by_name=False
가 포함된 모델에서 동적으로 결정된 별칭 또는 별칭 생성기를 사용할 때마다 mypy 오류가 발생합니다.- 이러한 별칭이 있으면 mypy가
__init__
에 대한 검사 호출을 제대로 입력할 수 없기 때문에 이는 중요합니다. 이 경우 기본적으로 모든 인수를 선택 사항으로 처리합니다.
플러그인 활성화¶
플러그인을 활성화하려면 mypy 구성 파일 의 플러그인 목록에 pydantic.mypy
추가하기만 하면 됩니다( mypy.ini
, pyproject.toml
또는 setup.cfg
일 수 있음).
시작하려면 다음 내용이 포함된 mypy.ini
파일을 생성하기만 하면 됩니다.
[mypy]
plugins = pydantic.mypy
!!! note pydantic.v1
모델을 사용하는 경우 플러그인 목록에 pydantic.v1.mypy
추가해야 합니다.
플러그인은 mypy 버전 >=0.930
과 호환됩니다.
자세한 내용은 플러그인 구성 문서를 참조하세요.
플러그인 구성¶
플러그인 설정 값을 변경하려면 mypy 구성 파일에 [pydantic-mypy]
라는 섹션을 만들고 재정의하려는 설정에 대한 키-값 쌍을 추가하세요.
모든 플러그인 엄격 플래그가 활성화된 mypy.ini
파일(및 기타 mypy 엄격 플래그도 포함)은 다음과 같습니다.
[mypy]
plugins = pydantic.mypy
follow_imports = silent
warn_redundant_casts = True
warn_unused_ignores = True
disallow_any_generics = True
check_untyped_defs = True
no_implicit_reexport = True
# for strict mypy: (this is the tricky one :-))
disallow_untyped_defs = True
[pydantic-mypy]
init_forbid_extra = True
init_typed = True
warn_required_dynamic_aliases = True
mypy>=0.900
부터 mypy 구성은 mypy.ini
가 아닌 pyproject.toml
파일에 포함될 수도 있습니다. 위와 동일한 구성은 다음과 같습니다.
[tool.mypy]
plugins = [
"pydantic.mypy"
]
follow_imports = "silent"
warn_redundant_casts = true
warn_unused_ignores = true
disallow_any_generics = true
check_untyped_defs = true
no_implicit_reexport = true
# for strict mypy: (this is the tricky one :-))
disallow_untyped_defs = true
[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
warn_required_dynamic_aliases = true
--disallow-any-explicit
에 대한 참고 사항¶
--disallow-any-explicit
mypy 구성 설정(또는 Any
금지하는 기타 설정)을 사용하는 경우 BaseModel
확장 시 no-any-explicit
오류가 발생할 수 있습니다. 이는 기본적으로 Pydantic의 mypy
플러그인이 다음과 같은 서명이 있는 __init__
메소드를 추가하기 때문입니다. def __init__(self, field_1: Any, field_2: Any, **kwargs: Any):
!!! "왜 추가 서명이 필요한가요?"를 참고하세요. Pydantic mypy
플러그인은 다음과 같은 서명이 있는 __init__
메소드를 추가합니다. def __init__(self, field_1: Any, field_2: Any, **kwargs: Any):
필드 주석과 일치하지 않는 유형으로 모델을 초기화할 때 유형 오류를 방지하기 위해. 예를 들어 Model(date='2024-01-01')
이 Any
서명이 없으면 유형 오류를 발생시키지만 Pydantic은 '2024-01-01'
문자열을 datetime.date
유형으로 구문 분석하는 기능이 있습니다.
이 문제를 해결하려면 Pydantic mypy 플러그인에 대해 엄격 모드 설정을 활성화해야 합니다. 특히 [pydantic-mypy]
섹션에 다음 옵션을 추가하세요.
[tool.pydantic-mypy]
init_forbid_extra = true
init_typed = true
init_forbid_extra = True
사용하면 생성된 __init__
서명에서 **kwargs
제거됩니다. init_typed = True
사용하면 필드의 Any
유형이 실제 유형 힌트로 대체됩니다.
이 구성을 사용하면 Pydantic 모델에서 오류 없이 --disallow-any-explicit
사용할 수 있습니다. 그러나 이러한 보다 엄격한 검사는 일부 유효한 Pydantic 사용 사례(예: 날짜/시간 필드에 대한 문자열 전달)를 유형 오류로 표시할 수 있다는 점에 유의하세요.
本文总阅读量次