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などがあります。
型判定を厳密に行うことにより、暗黙的な型変換でのすり抜けを防ぐことができるので、必要なケースで使ってみてください。


コメント