コンテンツにスキップ

Standard Library Types


description: Support for common types from the Python standard library.

Pydanticは、Python標準ライブラリから多くの一般的な型をサポートしています。より厳密な処理が必要な場合は、Strict Typesを参照してください。これには、許可される値を制限する必要がある場合(たとえば、正のintを要求する場合)も含まれます。

Booleans

標準のboolフィールドは、値が次のいずれでもない場合にValidationErrorを発生させます。

  • 有効なブール値(すなわちTrueまたはFalse)
  • 整数0または1
  • 小文字に変換されたときに、"0"、"off"、"f"、"false"、"n"、"no"、"1"、"on"、"t"、"true"、"y"、"yes"のいずれかになる"str"
  • strにデコードされたときに、前の規則に従った有効なbytes

Note

より厳密なブール論理(例えば、TrueFalseのみを許可するフィールド)が必要な場合は、StrictBoolを使用できます。

次に、これらの動作の一部を示すスクリプトを示します。

from pydantic import BaseModel, ValidationError


class BooleanModel(BaseModel):
    bool_value: bool


print(BooleanModel(bool_value=False))
#> bool_value=False
print(BooleanModel(bool_value='False'))
#> bool_value=False
print(BooleanModel(bool_value=1))
#> bool_value=True
try:
    BooleanModel(bool_value=[])
except ValidationError as e:
    print(str(e))
    """
    1 validation error for BooleanModel
    bool_value
      Input should be a valid boolean [type=bool_type, input_value=[], input_type=list]
    """

Datetime Types

Pydanticは次のdatetime型をサポートしています。

datetime.datetime

  • datetimeフィールドは以下の型の値を受け付けます:

    • datetime; 既存のdatetimeオブジェクト
    • intまたはfloat; 1970年1月1日からのUnix時間、つまり秒(>=-2e10および<=2e10の場合)またはミリ秒(<-2e10または>2e10の場合)と見なされます。
    • str; 以下のフォーマットが使用できます。
    • YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or[±]HH[:]MM]
    • datetime.dateインスタンスはlaxモードでは受け付けられますが、strictモードでは受け付けられません。
    • 文字列としてのintまたはfloat(Unix時間と仮定)
from datetime import datetime

from pydantic import BaseModel


class Event(BaseModel):
    dt: datetime = None


event = Event(dt='2032-04-23T10:20:30.400+02:30')

print(event.model_dump())
"""
{'dt': datetime.datetime(2032, 4, 23, 10, 20, 30, 400000, tzinfo=TzInfo(+02:30))}
"""

datetime.date

*dateフィールドは以下の型の値を受け付けます:

<!--
* `date`; an existing `date` object
* `int` or `float`; handled the same as described for `datetime` above
* `str`; the following formats are accepted:
    * `YYYY-MM-DD`
    * `int` or `float` as a string (assumed as Unix time)
-->
* `date`; 既存の`date`オブジェクト
* `int`または`float`; 上記の`datetime`と同じように扱われます。
* `str`; 以下のフォーマットが使用できます。
    * `YYYY-MM-DD`
    * 文字列としての`int`または`float`(Unix時間と仮定)
from datetime import date

from pydantic import BaseModel


class Birthday(BaseModel):
    d: date = None


my_birthday = Birthday(d=1679616000.0)

print(my_birthday.model_dump())
#> {'d': datetime.date(2023, 3, 24)}

datetime.time

  • timeフィールドは以下の型の値を受け付けます:

    * time; 既存のtimeオブジェクト * str; 以下のフォーマットが使用できます。 * HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]

from datetime import time

from pydantic import BaseModel


class Meeting(BaseModel):
    t: time = None


m = Meeting(t=time(4, 8, 16))

print(m.model_dump())
#> {'t': datetime.time(4, 8, 16)}

datetime.timedelta

  • timedeltaフィールドは以下の型の値を受け付けます:

    • timedelta; 既存のtimedeltaオブジェクト
    • intまたはfloat; 秒と見なされます
    • str; 以下のフォーマットが使用できます。
      • [-][DD]D[,][HH:MM:]SS[.ffffff]
        • 例: '1d,01:02:03.000004' または '1D01:02:03.000004' または '01:02:03'
      • [±]P[DD]DT[HH]H[MM]M[SS]S (ISO 8601 タイムデルタフォーマット)
from datetime import timedelta

from pydantic import BaseModel


class Model(BaseModel):
    td: timedelta = None


m = Model(td='P3DT12H30M5S')

print(m.model_dump())
#> {'td': datetime.timedelta(days=3, seconds=45005)}

Number Types

Pydanticは、Python標準ライブラリから次の数値型をサポートしています。

int

  • Pydanticは型をintに強制するためにint(v)を使用します。

データ変換中の情報損失の詳細については、Data conversionを参照してください。

float

  • Pydanticはfloat(v)を使用して値を浮動小数点に変換します。

enum.IntEnum

  • バリデーション: Pydanticは、値が有効なIntEnumインスタンスであることを確認します。
  • enum.IntEnumのサブクラスのバリデーション: 値が整数列挙型の有効なメンバーであることをチェックします;

詳細については、Enums and Choicesを参照してください。

decimal.Decimal

  • 検証: Pydanticは値を文字列に変換してから、その文字列をDecimal(v)に渡します。
  • シリアライゼーション: PydanticはDecimal型を文字列としてシリアライズします。

必要に応じて、カスタム・シリアライザを使用してこの動作を上書きできます。次に例を示します。

from decimal import Decimal

from typing_extensions import Annotated

from pydantic import BaseModel, PlainSerializer


class Model(BaseModel):
    x: Decimal
    y: Annotated[
        Decimal,
        PlainSerializer(
            lambda x: float(x), return_type=float, when_used='json'
        ),
    ]


my_model = Model(x=Decimal('1.1'), y=Decimal('2.1'))

print(my_model.model_dump())  # (1)!
#> {'x': Decimal('1.1'), 'y': Decimal('2.1')}
print(my_model.model_dump(mode='json'))  # (2)!
#> {'x': '1.1', 'y': 2.1}
print(my_model.model_dump_json())  # (3)!
#> {"x":"1.1","y":2.1}
  1. model_dumpを使用すると、xyの両方がDecimal型のインスタンスのままになります
  2. model_dumpmode='json'で使用すると、xstringとしてシリアライズされ、yはカスタムシリアライザが適用されているためfloatとしてシリアライズされます。
  3. model_dump_jsonを使用すると、xstringとしてシリアライズされ、yはカスタムシリアライザが適用されているためfloatとしてシリアライズされます。

Enum

PydanticはPythonの標準のenumクラスを使って選択肢を定義します。

enum.Enumは、値が有効なEnumインスタンスであることをチェックします。 enum.Enumのサブクラスは、値が列挙型の有効なメンバーであることをチェックします。

from enum import Enum, IntEnum

from pydantic import BaseModel, ValidationError


class FruitEnum(str, Enum):
    pear = 'pear'
    banana = 'banana'


class ToolEnum(IntEnum):
    spanner = 1
    wrench = 2


class CookingModel(BaseModel):
    fruit: FruitEnum = FruitEnum.pear
    tool: ToolEnum = ToolEnum.spanner


print(CookingModel())
#> fruit=<FruitEnum.pear: 'pear'> tool=<ToolEnum.spanner: 1>
print(CookingModel(tool=2, fruit='banana'))
#> fruit=<FruitEnum.banana: 'banana'> tool=<ToolEnum.wrench: 2>
try:
    CookingModel(fruit='other')
except ValidationError as e:
    print(e)
    """
    1 validation error for CookingModel
    fruit
      Input should be 'pear' or 'banana' [type=enum, input_value='other', input_type=str]
    """

Lists and Tuples

list

listtuplesetfrozensetdeque、またはジェネレータとlistへのキャストを許可します。 汎用パラメータを指定すると、適切な検証がリストのすべての項目に適用されます。

typing.List

上記のlistと同じように扱われます。

from typing import List, Optional

from pydantic import BaseModel


class Model(BaseModel):
    simple_list: Optional[list] = None
    list_of_ints: Optional[List[int]] = None


print(Model(simple_list=['1', '2', '3']).simple_list)
#> ['1', '2', '3']
print(Model(list_of_ints=['1', '2', '3']).list_of_ints)
#> [1, 2, 3]

tuple

listtuplesetfrozensetdeque、またはジェネレータとtupleへのキャストを許可します。 汎用パラメータが提供される場合、適切な検証がタプルの各項目に適用されます。

typing.Tuple

上記のtupleと同じように扱われます。

from typing import Optional, Tuple

from pydantic import BaseModel


class Model(BaseModel):
    simple_tuple: Optional[tuple] = None
    tuple_of_different_types: Optional[Tuple[int, float, bool]] = None


print(Model(simple_tuple=[1, 2, 3, 4]).simple_tuple)
#> (1, 2, 3, 4)
print(Model(tuple_of_different_types=[3, 2, 1]).tuple_of_different_types)
#> (3, 2.0, True)

typing.NamedTuple

typing.NamedTupleのサブクラスはtupleに似ていますが、与えられたNamedTupleクラスのインスタンスを作成します。

collections.namedtupleのサブクラスは、typing.NamedTupleのサブクラスと似ていますが、フィールド型が指定されていないので、すべてのフィールドはAny型として扱われます。

from typing import NamedTuple

from pydantic import BaseModel, ValidationError


class Point(NamedTuple):
    x: int
    y: int


class Model(BaseModel):
    p: Point


try:
    Model(p=('1.3', '2'))
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    p.0
      Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='1.3', input_type=str]
    """

Deque

deque

listtuplesetfrozensetdeque、またはジェネレータとdequeへのキャストを許可します。 一般的なパラメータが与えられると、適切な検証がdequeの各項目に適用されます。

typing.Deque

Handled the same as deque above.

from typing import Deque, Optional

from pydantic import BaseModel


class Model(BaseModel):
    deque: Optional[Deque[int]] = None


print(Model(deque=[1, 2, 3]).deque)
#> deque([1, 2, 3])

Sets

set

listtuplesetfrozensetdeque、またはジェネレータとsetへのキャストを許可します。 汎用パラメータを指定すると、セットのすべてのアイテムに適切な検証が適用されます。

typing.Set

上記のsetと同じように扱われます。

from typing import Optional, Set

from pydantic import BaseModel


class Model(BaseModel):
    simple_set: Optional[set] = None
    set_of_ints: Optional[Set[int]] = None


print(Model(simple_set={'1', '2', '3'}).simple_set)
#> {'1', '2', '3'}
print(Model(simple_set=['1', '2', '3']).simple_set)
#> {'1', '2', '3'}
print(Model(set_of_ints=['1', '2', '3']).set_of_ints)
#> {1, 2, 3}

frozenset

listtuplesetfrozensetdeque、またはジェネレータとfrozensetへのキャストを許可します。 汎用パラメータを指定すると、フリーズされたセットのすべてのアイテムに適切な検証が適用されます。

typing.FrozenSet

上記のfrozensetと同じように扱われます。

from typing import FrozenSet, Optional

from pydantic import BaseModel


class Model(BaseModel):
    simple_frozenset: Optional[frozenset] = None
    frozenset_of_ints: Optional[FrozenSet[int]] = None


m1 = Model(simple_frozenset=['1', '2', '3'])
print(type(m1.simple_frozenset))
#> <class 'frozenset'>
print(sorted(m1.simple_frozenset))
#> ['1', '2', '3']

m2 = Model(frozenset_of_ints=['1', '2', '3'])
print(type(m2.frozenset_of_ints))
#> <class 'frozenset'>
print(sorted(m2.frozenset_of_ints))
#> [1, 2, 3]

Other Iterables

typing.Sequence

これは、提供された値がSequenceABCの要件を満たす必要があり、コンテナ内の値を積極的に検証することが望ましい場合に使用することを意図しています。

コンテナの値に対して検証を実行する必要がある場合、検証によって値が置き換えられる可能性があるため、コンテナのタイプが保持されない可能性があることに注意してください。

検証された値が有効なtyping.Sequenceであることを保証しますが、提供されたものとは異なる型を持つ可能性があります(一般的にはlistになります)。

typing.Iterable

これは、提供された値が消費されるべきではないiterableである場合に使用することを意図しています。 解析と検証の詳細については、以下のInfinite Generatorsを参照してください。

typing.Sequenceと同様に、検証された結果が有効なtyping.Iterableであることを保証しますが、提供されたものとは異なる型を持つ可能性があります。特に、listのような非ジェネレータ型が提供された場合でも、typing.Iterable型のフィールドの検証後の値はジェネレータになります。

以下は、typing.Sequenceを使用した簡単な例です。

from typing import Sequence

from pydantic import BaseModel


class Model(BaseModel):
    sequence_of_ints: Sequence[int] = None


print(Model(sequence_of_ints=[1, 2, 3, 4]).sequence_of_ints)
#> [1, 2, 3, 4]
print(Model(sequence_of_ints=(1, 2, 3, 4)).sequence_of_ints)
#> (1, 2, 3, 4)

Infinite Generators

検証したいジェネレータがある場合は、上記のようにSequenceを使うことができます。 この場合、ジェネレータが消費されてリストとしてモデルに保存され、その値がSequenceの型パラメータ(例えばintinSequence[int])に対して検証されます。

しかし、あまり使われたくないジェネレータ(無限ジェネレータやリモートデータローダなど)がある場合は、Iterable型のフィールドを使うことができます。

from typing import Iterable

from pydantic import BaseModel


class Model(BaseModel):
    infinite: Iterable[int]


def infinite_ints():
    i = 0
    while True:
        yield i
        i += 1


m = Model(infinite=infinite_ints())
print(m)
"""
infinite=ValidatorIterator(index=0, schema=Some(Int(IntValidator { strict: false })))
"""

for i in m.infinite:
    print(i)
    #> 0
    #> 1
    #> 2
    #> 3
    #> 4
    #> 5
    #> 6
    #> 7
    #> 8
    #> 9
    #> 10
    if i == 10:
        break

Warning

最初の検証では、Iterableフィールドは与えられた引数がiterableであるかどうかの単純なチェックのみを行います。 それが消費されないようにするために、得られた値の検証は熱心に行われない。

生成された値はすぐには検証されませんが、生成時には検証され、適切な場合には生成時にValidationErrorが発生します。

from typing import Iterable

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    int_iterator: Iterable[int]


def my_iterator():
    yield 13
    yield '27'
    yield 'a'


m = Model(int_iterator=my_iterator())
print(next(m.int_iterator))
#> 13
print(next(m.int_iterator))
#> 27
try:
    next(m.int_iterator)
except ValidationError as e:
    print(e)
    """
    1 validation error for ValidatorIterator
    2
      Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='a', input_type=str]
    """

Mapping Types

dict

dict(v)は辞書を変換するために使用されます。サブタイプの制約については以下のtyping.Dictを参照してください。

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    x: dict


m = Model(x={'foo': 1})
print(m.model_dump())
#> {'x': {'foo': 1}}

try:
    Model(x='test')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    x
      Input should be a valid dictionary [type=dict_type, input_value='test', input_type=str]
    """

typing.Dict

from typing import Dict

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    x: Dict[str, int]


m = Model(x={'foo': 1})
print(m.model_dump())
#> {'x': {'foo': 1}}

try:
    Model(x={'foo': '1'})
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    x
      Input should be a valid dictionary [type=dict_type, input_value='test', input_type=str]
    """

TypedDict

Note

3.12より前のtyping.TypedDictの制限により、Python<3.12にはtyping-extensionsパッケージが必要です。typingの代わりにtyping_extensionsからTypedDictをインポートする必要があり、インポートしないとビルド時エラーが発生します。

TypedDictは、すべてのインスタンスが特定のキーのセットを持つことを期待する辞書型を宣言します。各キーは一貫した型の値に関連付けられています。

dictと同じですが、キーには注釈が付けられているので、Pydanticは辞書を検証します。

from typing_extensions import TypedDict

from pydantic import TypeAdapter, ValidationError


class User(TypedDict):
    name: str
    id: int


ta = TypeAdapter(User)

print(ta.validate_python({'name': 'foo', 'id': 1}))
#> {'name': 'foo', 'id': 1}

try:
    ta.validate_python({'name': 'foo'})
except ValidationError as e:
    print(e)
    """
    1 validation error for typed-dict
    id
      Field required [type=missing, input_value={'name': 'foo'}, input_type=dict]
    """

__pydantic_config__を定義して、TypedDictから継承されたモデルを変更することができます。 詳細については、ConfigDictAPI referenceを参照してください。

from typing import Optional

from typing_extensions import TypedDict

from pydantic import ConfigDict, TypeAdapter, ValidationError


# `total=False` means keys are non-required
class UserIdentity(TypedDict, total=False):
    name: Optional[str]
    surname: str


class User(TypedDict):
    __pydantic_config__ = ConfigDict(extra='forbid')

    identity: UserIdentity
    age: int


ta = TypeAdapter(User)

print(
    ta.validate_python(
        {'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}
    )
)
#> {'identity': {'name': 'Smith', 'surname': 'John'}, 'age': 37}

print(
    ta.validate_python(
        {'identity': {'name': None, 'surname': 'John'}, 'age': 37}
    )
)
#> {'identity': {'name': None, 'surname': 'John'}, 'age': 37}

print(ta.validate_python({'identity': {}, 'age': 37}))
#> {'identity': {}, 'age': 37}


try:
    ta.validate_python(
        {'identity': {'name': ['Smith'], 'surname': 'John'}, 'age': 24}
    )
except ValidationError as e:
    print(e)
    """
    1 validation error for typed-dict
    identity.name
      Input should be a valid string [type=string_type, input_value=['Smith'], input_type=list]
    """

try:
    ta.validate_python(
        {
            'identity': {'name': 'Smith', 'surname': 'John'},
            'age': '37',
            'email': 'john.smith@me.com',
        }
    )
except ValidationError as e:
    print(e)
    """
    1 validation error for typed-dict
    email
      Extra inputs are not permitted [type=extra_forbidden, input_value='john.smith@me.com', input_type=str]
    """

Callable

解析と検証の詳細については、以下を参照してください。

フィールドはCallable型にすることもできます。

from typing import Callable

from pydantic import BaseModel


class Foo(BaseModel):
    callback: Callable[[int], int]


m = Foo(callback=lambda x: x)
print(m)
#> callback=<function <lambda> at 0x0123456789ab>

Warning

呼び出し可能フィールドは、引数が呼び出し可能であることの単純なチェックのみを実行します。引数、その型、または戻り値の型の検証は実行されません。

IP Address Types

その他のカスタムIPアドレスタイプについては、Network Typesを参照してください。

UUID

UUIDの場合、PydanticはUUID(v)に値を渡すことで、型自体を検証に使用しようとします。 bytesbytearrayにはUUID(bytes=v)へのフォールバックがあります。

UUIDバージョンを制限する場合は、次のタイプをチェックします。

  • UUID1: UUIDバージョン1が必要です。
  • UUID3: UUIDバージョン3が必要です。
  • UUID4: UUIDバージョン4が必要です。
  • UUID5: UUIDバージョン5が必要です。

Union

Pydanticはユニオン検証を幅広くサポートしており、typing.UnionとPython 3.10のパイプ構文(A B)の両方がサポートされています。 詳細はconcepts docsのUnionsセクションを読んでください。

Type and TypeVar

type

Pydanticでは、type[T]を使用して、フィールドがTのサブクラスであるクラス(インスタンスではない)のみを受け入れるように指定できます。

typing.Type

上記のtypeと同様に扱われます。

from typing import Type

from pydantic import BaseModel, ValidationError


class Foo:
    pass


class Bar(Foo):
    pass


class Other:
    pass


class SimpleModel(BaseModel):
    just_subclasses: Type[Foo]


SimpleModel(just_subclasses=Foo)
SimpleModel(just_subclasses=Bar)
try:
    SimpleModel(just_subclasses=Other)
except ValidationError as e:
    print(e)
    """
    1 validation error for SimpleModel
    just_subclasses
      Input should be a subclass of Foo [type=is_subclass_of, input_value=<class '__main__.Other'>, input_type=type]
    """

Typeを使用して、任意のクラスを許可するように指定することもできます。

from typing import Type

from pydantic import BaseModel, ValidationError


class Foo:
    pass


class LenientSimpleModel(BaseModel):
    any_class_goes: Type


LenientSimpleModel(any_class_goes=int)
LenientSimpleModel(any_class_goes=Foo)
try:
    LenientSimpleModel(any_class_goes=Foo())
except ValidationError as e:
    print(e)
    """
    1 validation error for LenientSimpleModel
    any_class_goes
      Input should be a type [type=is_type, input_value=<__main__.Foo object at 0x0123456789ab>, input_type=Foo]
    """

typing.TypeVar

TypeVarは、アンバインド、バインド、または境界付きのいずれかでサポートされています。

from typing import TypeVar

from pydantic import BaseModel

Foobar = TypeVar('Foobar')
BoundFloat = TypeVar('BoundFloat', bound=float)
IntStr = TypeVar('IntStr', int, str)


class Model(BaseModel):
    a: Foobar  # equivalent of ": Any"
    b: BoundFloat  # equivalent of ": float"
    c: IntStr  # equivalent of ": Union[int, str]"


print(Model(a=[1], b=4.2, c='x'))
#> a=[1] b=4.2 c='x'

# a may be None
print(Model(a=None, b=1, c=1))
#> a=None b=1.0 c=1

None Types

Nonetype(None)、またはLiteral[None]はすべて、the typing specificationに従って等価です。

None値のみを許可します。

Strings

str:文字列はそのまま受け入れられます。bytesbytearrayv.decode()を使って変換されます。 strから継承した列挙型はv.valueを使用して変換されます。他のすべての型はエラーを引き起こします。

Strings aren't Sequences

型チェッカーの観点から見ると、strのインスタンスは技術的にはSequence[str]プロトコルの有効なインスタンスですが、これはバグの一般的な原因として意図されていないことがよくあります。

その結果、strまたはbytesインスタンスをSequence[str]型またはSequence[bytes]型のフィールドに渡そうとすると、PydanticはValidationErrorを発生させます。

from typing import Optional, Sequence

from pydantic import BaseModel, ValidationError


class Model(BaseModel):
    sequence_of_strs: Optional[Sequence[str]] = None
    sequence_of_bytes: Optional[Sequence[bytes]] = None


print(Model(sequence_of_strs=['a', 'bc']).sequence_of_strs)
#> ['a', 'bc']
print(Model(sequence_of_strs=('a', 'bc')).sequence_of_strs)
#> ('a', 'bc')
print(Model(sequence_of_bytes=[b'a', b'bc']).sequence_of_bytes)
#> [b'a', b'bc']
print(Model(sequence_of_bytes=(b'a', b'bc')).sequence_of_bytes)
#> (b'a', b'bc')


try:
    Model(sequence_of_strs='abc')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    sequence_of_strs
      'str' instances are not allowed as a Sequence value [type=sequence_str, input_value='abc', input_type=str]
    """
try:
    Model(sequence_of_bytes=b'abc')
except ValidationError as e:
    print(e)
    """
    1 validation error for Model
    sequence_of_bytes
      'bytes' instances are not allowed as a Sequence value [type=sequence_str, input_value=b'abc', input_type=bytes]
    """

Bytes

bytesはそのまま受け入れられます。bytearraybytes(v)を使って変換されます。strv.encode()を使って変換されます。intfloatDecimalstr(v).encode()を使って強制されます。詳細はByteSizeを参照してください。

typing.Literal

Pydanticは、フィールドが特定のリテラル値のみを受け入れることを指定する軽量な方法として、typing.Literalの使用をサポートしています。

from typing import Literal

from pydantic import BaseModel, ValidationError


class Pie(BaseModel):
    flavor: Literal['apple', 'pumpkin']


Pie(flavor='apple')
Pie(flavor='pumpkin')
try:
    Pie(flavor='cherry')
except ValidationError as e:
    print(str(e))
    """
    1 validation error for Pie
    flavor
      Input should be 'apple' or 'pumpkin' [type=literal_error, input_value='cherry', input_type=str]
    """

このフィールド型の利点の1つは、カスタムバリデータを宣言しなくても、1つ以上の特定の値との等価性をチェックできることです。

from typing import ClassVar, List, Literal, Union

from pydantic import BaseModel, ValidationError


class Cake(BaseModel):
    kind: Literal['cake']
    required_utensils: ClassVar[List[str]] = ['fork', 'knife']


class IceCream(BaseModel):
    kind: Literal['icecream']
    required_utensils: ClassVar[List[str]] = ['spoon']


class Meal(BaseModel):
    dessert: Union[Cake, IceCream]


print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__)
#> Cake
print(type(Meal(dessert={'kind': 'icecream'}).dessert).__name__)
#> IceCream
try:
    Meal(dessert={'kind': 'pie'})
except ValidationError as e:
    print(str(e))
    """
    2 validation errors for Meal
    dessert.Cake.kind
      Input should be 'cake' [type=literal_error, input_value='pie', input_type=str]
    dessert.IceCream.kind
      Input should be 'icecream' [type=literal_error, input_value='pie', input_type=str]
    """

注釈付きのUnionで適切な順序付けを行うと、これを使用して減少する特異性の型を解析できます。

from typing import Literal, Optional, Union

from pydantic import BaseModel


class Dessert(BaseModel):
    kind: str


class Pie(Dessert):
    kind: Literal['pie']
    flavor: Optional[str]


class ApplePie(Pie):
    flavor: Literal['apple']


class PumpkinPie(Pie):
    flavor: Literal['pumpkin']


class Meal(BaseModel):
    dessert: Union[ApplePie, PumpkinPie, Pie, Dessert]


print(type(Meal(dessert={'kind': 'pie', 'flavor': 'apple'}).dessert).__name__)
#> ApplePie
print(type(Meal(dessert={'kind': 'pie', 'flavor': 'pumpkin'}).dessert).__name__)
#> PumpkinPie
print(type(Meal(dessert={'kind': 'pie'}).dessert).__name__)
#> Dessert
print(type(Meal(dessert={'kind': 'cake'}).dessert).__name__)
#> Dessert

typing.Any

Allows any value, including None.

typing.Annotated

PEP-593に従って、別の型を任意のメタデータでラップすることを許可します。Annotatedヒントには、Field関数への単一の呼び出しを含めることができますが、それ以外の場合は追加のメタデータは無視され、ルート型が使用されます。

typing.Pattern

正規表現パターンを作成するために、入力値がre.compile(v)に渡されます。

pathlib.Path

値をPath(v)に渡すことで、型自体を検証に使用します。