Python WebAcademy Blog

Pydantic 2.14がリリース。Python 3.15に対応し、未入力を表すMISSINGが正式機能になったニュースを初心者向けに解説

|

データの検証ライブラリPydanticの2.14.0が、2026年10月8日に公開されました。Python 3.9のサポートを終え、3.15のfrozendictやlazy importに対応したほか、値が送られてこなかったことを表すMISSINGが正式な機能になりました。NoneとMISSINGの違いを実際に動かした結果とともに、上げる前に確かめたい点を整理します。

2026年10月8日、Pythonのデータ検証ライブラリPydanticの2.14.0が公開されました。FastAPIの裏側でも使われている、とても利用者の多いライブラリです。

今回の目玉は、正式版の公開を目前に控えたPython 3.15への対応です。あわせて、値が送られてこなかったことを表すMISSINGという仕組みが、実験的な機能から正式な機能になりました。

NoneとMISSINGはどう違うのか、と疑問に思った方もいるでしょう。今回は、その違いを実際に動かしながら見ていきます。

まずは何が変わったのかを整理しよう

最初に、今回取り上げる変更を表にまとめます。内容は、Pydanticの公式リポジトリにある変更履歴にもとづいています。

変更 中身
Pythonの対応範囲 3.9のサポートを終了し、3.15に対応
Python 3.15の新機能 frozendict、TypeForm、lazy importに対応
MISSING 実験的な機能から正式な機能へ
新しい制約 fractionとtimedeltaにmultiple_ofを指定できる
細かな修正 検証やJSON Schemaの生成まわりの不具合を多数修正

PyPIの記録によると、2.14.0が必要とするPythonは3.10以上です。3.9で動かしている場合、pip installしても2.14は入らず、2.13系のままになります。

Pydanticそのものがまだよくわからない方は、先にこちらを読んでおくと話がつながります。【関連記事】Pydantic v2とは?

Python 3.15の新機能に対応した

変更履歴によると、2.14.0b2の段階でPython 3.15の新しい機能への対応が入りました。その内容が、今回の正式版にそのまま含まれています。

frozendictを型として使える

Python 3.15では、書き換えられない辞書frozendictが組み込みの型として加わります。Pydantic 2.14では、このfrozendictをモデルのフィールドの型として使えるようになりました。

frozendictそのものについては、3.15の新機能をまとめた記事で紹介しています。【関連記事】Python 3.15の新機能を先取り解説!

TypeFormとlazy importにも対応

TypeFormは、型そのものを値として受け渡すときに、型チェッカーが正しく理解できるようにする仕組みです。Pydanticでは、TypeAdapterなどで型を渡す場面の型チェックが、より正確になります。

もう1つが、3.15の目玉機能であるlazy importへの対応です。モジュールを実際に使う瞬間まで読み込みを遅らせる仕組みで、プログラムの起動を速くする効果が期待されています。

Python 3.15の正式版は、10月9日の公開が予定されています。主要なライブラリがこうして先に対応してくれると、新しいPythonへ安心して移れるようになります。

3.15の公開日程が変わった経緯は、先日の記事で取り上げました。【関連記事】Python 3.15の正式版は10月9日に延期

未入力を表すMISSINGが正式な機能に

今回のニュースで、学習者にとっていちばん面白いのがMISSINGです。Pydanticのドキュメントによると、MISSINGは2.12で実験的な機能として加わり、2.14で実験的という扱いが外れました。

これからは、from pydantic import MISSINGと書くだけで使えます。では、MISSINGは何のためにあるのでしょうか。

NoneとMISSINGは何が違うのか

Pythonでは、値がないことを表すのにNoneがよく使われます。けれども、Noneには2つの意味が混ざってしまうことがあります。

たとえば、プロフィールを更新するWeb APIを考えてみてください。自己紹介を空にしたいという指示と、自己紹介には触れないという指示は、まったく別のものですよね。

両方をNoneで表すと、プログラムからはこの2つを区別できません。MISSINGは、そもそも値が送られてこなかったことを表すための専用の目印です。

Noneの基本については、こちらで詳しく解説しています。【関連記事】PythonのNoneとは?

MISSINGを実際に動かしてみる

では、プロフィール更新の例を実際にコードにしてみましょう。ニックネームと自己紹介の2つのフィールドを持つモデルで、どちらも既定値をMISSINGにしておきます。

from pydantic import MISSING, BaseModel


class ProfileUpdate(BaseModel):
    nickname: str | None | MISSING = MISSING
    bio: str | None | MISSING = MISSING


# ニックネームだけ変えたい
a = ProfileUpdate(nickname="taro")
# 自己紹介を空(None)にしたい
b = ProfileUpdate(bio=None)

print(a.model_dump())
print(b.model_dump())
print(a.bio is MISSING, b.bio is MISSING)

新しい仮想環境にPydantic 2.14.0を入れ、手元のPython 3.11で実行した結果です。

{'nickname': 'taro'}
{'bio': None}
True False

1行目では、送られてこなかったbioが、model_dump()の結果から自動的に消えています。2行目では、明示的にNoneを指定したbioは、ちゃんとNoneとして残りました。

ドキュメントによると、MISSINGが入ったフィールドは、シリアライズのときに自動で出力から外されます。シリアライズとは、モデルを辞書やJSONに変換することです。

値を判定するときはisを使う

3行目のように、MISSINGかどうかを調べるときはisで比べます。ドキュメントの例でも、conf.timeout if conf.timeout is not MISSING else defaults['timeout']のように、isで判定してから既定値を補う書き方が紹介されています。

ちなみにドキュメントには、MISSINGは実行時にはPython 3.15で加わるsentinelのしくみで実装されている、と書かれています。sentinelは、こうした特別な目印の値を作るための新しい組み込みの仕組みです。

私は10年ほどエンジニアとして開発に関わってきましたが、更新APIで送られてこなかった項目をNoneと同じに扱ってしまい、ユーザーの入力済みのデータを空で上書きした事故を見たことがあります。こうした区別を、ライブラリが標準の機能として用意してくれるのは心強いですね。

これまでのexclude_unsetとの違い

実は、送られてこなかった項目を出力から外すだけなら、これまでもmodel_dump()のexclude_unset=Trueで実現できました。ドキュメントでも、MISSINGはexclude_unsetの代わりに使える、と紹介されています。

では、何が違うのでしょうか。従来の書き方とMISSINGを使った書き方を、並べて動かしてみます。

from pydantic import MISSING, BaseModel


class OldStyle(BaseModel):
    bio: str | None = None


class NewStyle(BaseModel):
    bio: str | None | MISSING = MISSING


print(OldStyle().model_dump())
print(OldStyle().model_dump(exclude_unset=True))
print(NewStyle().model_dump())
print(NewStyle.model_json_schema()["properties"]["bio"])

実行結果は次のとおりです。

{'bio': None}
{}
{}
{'anyOf': [{'type': 'string'}, {'type': 'null'}], 'title': 'Bio'}

従来の書き方では、exclude_unset=Trueを付け忘れると、送られてこなかったbioがNoneとして出力されてしまいます。MISSINGを使えば、付け忘れの心配がなく、モデルの定義だけで意図が伝わるのが大きな違いです。

違いを表にまとめておきます。

比べる点 exclude_unset MISSING
指定する場所 model_dump()を呼ぶたび モデルの定義に1回だけ
付け忘れたとき Noneとして出力される 心配なし
値を見て判定 別の方法で調べる必要がある isで直接判定できる
JSON Schema 通常どおり MISSINGは現れない

最後の行のとおり、MISSINGはJSON Schemaには現れません。API仕様書を自動生成している場合も、利用者側から見た型は文字列かnullのままで変わらないので安心です。

そのほかの変更点

ほかにも、2.14では細かな改善がたくさん入っています。変更履歴から、初心者にも関係しそうなものをいくつか紹介します。

変更 意味
fractionとtimedeltaにmultiple_ofを追加 ある値の倍数かどうかを検証できる
create_model()に__namespace__を追加 動的に作るモデルの名前空間を指定できる
NameEmailで改行を拒否 名前付きのメールアドレスに改行が入るのを防ぐ
model_configを書き換えない 設定がほかのモデルへ思わぬ形で伝わるのを防ぐ

変更履歴には、バージョン管理の方針上は互換性を壊さない扱いの、小さな変更もいくつか含まれていると書かれています。上げる前に一度目を通しておくよう、案内されています。

特に、検証やJSON Schemaの生成まわりでは多くの修正が入りました。これまでの動きに頼ったテストがある場合は、2.14で一通り流しておくと安心です。

上げる前にやっておきたいこと

最後に、2.13から2.14へ上げるときの確認ポイントを整理します。大きな互換性の問題は少ない更新ですが、次の点は押さえておきましょう。

順番 確認すること
1 動かしているPythonが3.10以上か
2 変更履歴の小さな変更に、自分のコードが当てはまらないか
3 実験的なMISSINGを使っていたなら、import文を書き換える
4 テストを2.14で一通り流して、結果が変わらないか

FastAPIでAPIを作っている方は、Pydanticの更新がそのままAPIの入力チェックに影響します。FastAPIとPydanticの関係は、こちらで紹介しています。【関連記事】PythonのFastAPIとは?

以前、入力チェックのライブラリを上げたら、エラーメッセージの文面がわずかに変わり、それを画面に出していたテストがまとめて落ちたことがあります。エラーメッセージの文面には頼りすぎないようにしておくと、こうした更新に強くなります。

まとめ

Pydantic 2.14.0が2026年10月8日に公開されました。Python 3.9のサポートを終え、3.15のfrozendictやlazy importに対応し、MISSINGが正式な機能になりました。

NoneとMISSINGを使い分けると、値を空にしたいのか、そもそも送られてこなかったのかを、はっきり区別できます。更新用のAPIを作るときに、ぜひ思い出してみてください。

ここまでお読みいただきありがとうございました。

参考情報

次のアクション

記事で学んだ内容を実際に動かしてみよう

Python WebAcademyでは、ブラウザ上でコードを書きながら基礎から実践まで体系的に学べます。

Python WebAcademyの学習画面

あわせて読む

関連記事

ブログ一覧へ

Python学習ロードマップ

まずはこの3講座から

記事で気になったテーマを、順番に手を動かしながら学べます。

ロードマップを見る