Pydanticで、通常のint型を使用する場合に文字列の「1」などが代入されても処理が通ります。
全てのケースで厳密な型判定を使う必要はないとは思いますが、暗黙的に変換されることを知らない場合に原因調査に時間が掛かってしまうリスクがあります。
この記事では、数値型を扱う際に文字列は許可せずに厳密な型判定をする方法に関して解説します。
環境
- Python: 3.11.2
- Pydantic: 1.10.4
int型の場合、文字列が許可される
まずは、通常のint型を使用した場合です。
from pydantic import BaseModel, ValidationError
class IntModel(BaseModel):
normal_int: int
try:
print(IntModel(normal_int=1))
# normal_int=1
except ValidationError as e:
print(e)
try:
print(IntModel(normal_int="1"))
# normal_int=1
except ValidationError as e:
print(e)
結果を見ると、文字列の1を入れた場合もエラー無くnormal_int=1
が出力されています。
文字列が数値に暗黙的に変換され、文字列がすり抜けてしまうことが分かります。
Strict Typesを使う
Strict TypesのStrictInt
を使用すれば、厳密に数値であることを判定することが可能です。
from pydantic import BaseModel, ValidationError, StrictInt
class StrictIntModel(BaseModel):
strict_int: StrictInt
try:
print(StrictIntModel(strict_int=1))
# strict_int=1
except ValidationError as e:
print(e)
try:
print(StrictIntModel(strict_int="1"))
except ValidationError as e:
print(e)
"""
1 validation error for StrictIntModel
strict_int
value is not a valid integer (type=type_error.integer)
"""
先程のint型の場合とは異なり、文字列の1を入れた場合にValidationError
になっています。
文字列は数値型ではないとみなされて、暗黙的に変換されていません。
絶対に文字列を通したくない場合は、StrictInt
で解決できることが分かりますね。
まとめ
厳密に型判定をしたい場合、Strict Types
を使いましょう。Strict Types
には、StrictInt
の他にもStrictStr
, StrictBytes
, StrictFloat
, StrictBool
などがあります。
型判定を厳密に行うことにより、暗黙的な型変換でのすり抜けを防ぐことができるので、必要なケースで使ってみてください。
コメント