Pydantic prend en charge de nombreux types courants de la bibliothèque standard Python. Si vous avez besoin d'un traitement plus strict, consultez Strict Types , y compris si vous devez limiter les valeurs autorisées (par exemple pour exiger un int
positif).
Booléens¶
Un champ bool
standard générera une ValidationError
si la valeur n'est pas l'une des suivantes:
- Un booléen valide (c'est-à-dire
True
ouFalse
), - Les entiers
0
ou1
, - une
str
qui, une fois convertie en minuscules, est l'une des'0', 'off', 'f', 'false', 'n', 'no', '1', 'on', 't', 'true', 'y', 'yes'
- un
bytes
qui est valide selon la règle précédente lorsqu'il est décodé enstr
!!! note Si vous souhaitez une logique booléenne plus stricte (par exemple un champ qui autorise uniquement True
et False
), vous pouvez utiliser StrictBool
.
Voici un script illustrant certains de ces comportements:
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]
"""
Types date/heure¶
Pydantic prend en charge les types datetime suivants:
datetime.datetime
¶
-
Les champs
datetime
accepteront des valeurs de type:datetime
; un objetdatetime
existantint
oufloat
; supposé comme heure Unix, c'est-à-dire secondes (si >=-2e10
et <=2e10
) ou millisecondes (si <-2e10
ou >2e10
) depuis le 1er janvier 1970str
; les formats suivants sont acceptés :YYYY-MM-DD[T]HH:MM[:SS[.ffffff]][Z or [±]HH[:]MM]
YYYY-MM-DD
est accepté en mode laxiste, mais pas en mode strictint
oufloat
sous forme de chaîne (supposée à l'heure Unix)
datetime.date
les instances sont acceptées en mode laxiste, mais pas en mode strict
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
¶
-
les champs
date
accepteront des valeurs de type:date
; un objetdate
existantint
oufloat
; géré de la même manière que décrit pourdatetime
ci-dessusstr
; les formats suivants sont acceptés :YYYY-MM-DD
int
oufloat
sous forme de chaîne (supposée à l'heure 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())
>¶
datetime.time
¶
-
les champs
time
accepteront des valeurs de type:time
; un objettime
existantstr
; les formats suivants sont acceptés :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())
>¶
datetime.timedelta
¶
-
Les champs
timedelta
accepteront des valeurs de type:timedelta
; un objettimedelta
existantint
oufloat
; supposé être des secondesstr
; les formats suivants sont acceptés :[-][DD]D[,][HH:MM:]SS[.ffffff]
- Ex :
'1d,01:02:03.000004'
ou'1D01:02:03.000004'
ou'01:02:03'
- Ex :
[±]P[DD]DT[HH]H[MM]M[SS]S
(format ISO 8601 pour timedelta)
from datetime import timedelta
from pydantic import BaseModel
class Model(BaseModel): td: timedelta = None
m = Model(td='P3DT12H30M5S')
print(m.model_dump())
>¶
Types de nombres¶
Pydantic prend en charge les types numériques suivants de la bibliothèque standard Python:
int
¶
- Pydantic utilise
int(v)
pour contraindre les types à unint
; voir Conversion de données pour plus de détails sur la perte d'informations lors de la conversion de données.
float
¶
- Pydantic utilise
float(v)
pour contraindre les valeurs à flotter.
enum.IntEnum
¶
- Validation: Pydantic vérifie que la valeur est une instance
IntEnum
valide. - Validation pour la sous-classe d'
enum.IntEnum
: vérifie que la valeur est un membre valide de l'énumération entière; voir Énumérations et choix pour plus de détails.
decimal.Decimal
¶
- Validation: Pydantic tente de convertir la valeur en chaîne, puis transmet la chaîne à
Decimal(v)
. -
Sérialisation: Pydantic sérialise les types
Decimal
sous forme de chaînes. Vous pouvez utiliser un sérialiseur personnalisé pour remplacer ce comportement si vous le souhaitez. Par exemple: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)!
>¶
print(my_model.model_dump(mode='json')) # (2)!
>¶
print(my_model.model_dump_json()) # (3)!
>¶
-
En utilisant
model_dump
,x
ety
restent des instances du typeDecimal
- En utilisant
model_dump
avecmode='json'
,x
est sérialisé en tant questring
ety
est sérialisé en tant quefloat
en raison du sérialiseur personnalisé appliqué. - En utilisant
model_dump_json
,x
est sérialisé en tant questring
ety
est sérialisé en tant quefloat
en raison du sérialiseur personnalisé appliqué.
Enum
¶
Pydantic utilise les classes standard enum
de Python pour définir des choix.
enum.Enum
vérifie que la valeur est une instance Enum
valide. La sous-classe de enum.Enum
vérifie que la valeur est un membre valide de l'énumération.
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]
"""
Listes et tuples¶
list
¶
Autorise list
, tuple
, set
, frozenset
, deque
ou des générateurs et des conversions en list
. Lorsqu'un paramètre générique est fourni, la validation appropriée est appliquée à tous les éléments de la liste.
typing.List
¶
Géré de la même manière que list
ci-dessus.
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
¶
Autorise list
, tuple
, set
, frozenset
, deque
ou des générateurs et convertit en un tuple
. Lorsque des paramètres génériques sont fournis, la validation appropriée est appliquée aux éléments respectifs du tuple
typing.Tuple
¶
Géré de la même manière que tuple
ci-dessus.
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
¶
Les sous-classes de typing.NamedTuple
sont similaires à tuple
, mais créent des instances de la classe namedtuple
nommée.
Les sous-classes de collections.namedtuple
sont similaires à la sous-classe de typing.NamedTuple
, mais comme les types de champs ne sont pas spécifiés, tous les champs sont traités comme ayant le type 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]
"""
Déqué¶
deque
¶
Autorise list
, tuple
, set
, frozenset
, deque
ou des générateurs et des conversions en deque
. Lorsque des paramètres génériques sont fournis, la validation appropriée est appliquée aux éléments respectifs du deque
.
typing.Deque
¶
Géré de la même manière que deque
ci-dessus.
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])
Ensembles¶
set
¶
Autorise list
, tuple
, set
, frozenset
, deque
ou des générateurs et des conversions en un set
. Lorsqu'un paramètre générique est fourni, la validation appropriée est appliquée à tous les éléments de l'ensemble.
typing.Set
¶
Géré de la même manière que set
-dessus.
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
¶
Autorise list
, tuple
, set
, frozenset
, deque
ou des générateurs et des conversions vers un frozenset
. Lorsqu'un paramètre générique est fourni, la validation appropriée est appliquée à tous les éléments de l'ensemble figé.
typing.FrozenSet
¶
Géré de la même manière que frozenset
ci-dessus.
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]
Autres itérables¶
typing.Sequence
¶
Ceci est destiné à être utilisé lorsque la valeur fournie doit répondre aux exigences de la Sequence
ABC et qu'il est souhaitable de procéder à une validation rapide des valeurs dans le conteneur. Notez que lorsque la validation doit être effectuée sur les valeurs du conteneur, le type du conteneur peut ne pas être conservé puisque la validation peut finir par remplacer des valeurs. Nous garantissons que la valeur validée sera un typing.Sequence
valide, mais elle peut avoir un type différent de celui fourni (généralement, elle deviendra une list
).
typing.Iterable
¶
Ceci est destiné à être utilisé lorsque la valeur fournie peut être un itérable qui ne doit pas être consommé. Voir Générateurs infinis ci-dessous pour plus de détails sur l'analyse et la validation. Semblable à typing.Sequence
, nous garantissons que le résultat validé sera un typing.Iterable
valide, mais il peut avoir un type différent de celui fourni. En particulier, même si un type non générateur tel qu'une list
est fourni, la valeur post-validation d'un champ de type typing.Iterable
sera un générateur.
Voici un exemple simple utilisant 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)
Générateurs infinis¶
Si vous souhaitez valider un générateur, vous pouvez toujours utiliser Sequence
comme décrit ci-dessus. Dans ce cas, le générateur sera consommé et stocké sur le modèle sous forme de liste et ses valeurs seront validées par rapport au paramètre de type de la Sequence
(par exemple int
dans Sequence[int]
).
Cependant, si vous disposez d'un générateur que vous ne souhaitez pas utiliser avec impatience (par exemple un générateur infini ou un chargeur de données distant), vous pouvez utiliser un champ de type 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
!!! avertissement Lors de la validation initiale, les champs Iterable
effectuent uniquement une simple vérification que l'argument fourni est itérable. Pour éviter qu'il ne soit consommé, aucune validation des valeurs fournies n'est effectuée avec impatience.
Bien que les valeurs générées ne soient pas validées avec impatience, elles sont toujours validées lorsqu'elles sont générées et déclencheront une ValidationError
au moment du rendement, le cas échéant:
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]
"""
Types de mappage¶
dict
¶
dict(v)
est utilisé pour tenter de convertir un dictionnaire. voir typing.Dict
ci-dessous pour les contraintes de sous-type.
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]
"""
TypéDict¶
!!! note Il s'agit d'une nouvelle fonctionnalité de la bibliothèque standard Python à partir de Python 3.8. En raison des limitations de typing.TypedDict avant la version 3.12, le package typing-extensions est requis pour Python <3.12. Vous devrez importer TypedDict
depuis typing_extensions
au lieu de typing
et vous obtiendrez une erreur de temps de construction si vous ne le faites pas.
TypedDict
déclare un type de dictionnaire qui s'attend à ce que toutes ses instances aient un certain ensemble de clés, où chaque clé est associée à une valeur d'un type cohérent.
C'est la même chose que dict
mais Pydantic validera le dictionnaire puisque les clés sont annotées.
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]
"""
Vous pouvez définir __pydantic_config__
pour modifier le modèle hérité de TypedDict
. Voir la référence de l'API ConfigDict
pour plus de détails.
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]
"""
Appelable¶
Voir ci-dessous pour plus de détails sur l'analyse et la validation
Les champs peuvent également être de type 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>
!!! avertissement Les champs appelables effectuent uniquement une simple vérification que l'argument est appelable; aucune validation des arguments, de leurs types ou du type de retour n'est effectuée.
Types d'adresses IP¶
ipaddress.IPv4Address
: utilise le type lui-même pour la validation en transmettant la valeur àIPv4Address(v)
.ipaddress.IPv4Interface
: utilise le type lui-même pour la validation en transmettant la valeur àIPv4Address(v)
.ipaddress.IPv4Network
: utilise le type lui-même pour la validation en transmettant la valeur àIPv4Network(v)
.ipaddress.IPv6Address
: utilise le type lui-même pour la validation en transmettant la valeur àIPv6Address(v)
.ipaddress.IPv6Interface
: utilise le type lui-même pour la validation en transmettant la valeur àIPv6Interface(v)
.ipaddress.IPv6Network
: utilise le type lui-même pour la validation en transmettant la valeur àIPv6Network(v)
.
Voir Types de réseau pour d'autres types d'adresses IP personnalisées.
UUID¶
Pour UUID, Pydantic essaie d'utiliser le type lui-même pour la validation en transmettant la valeur à UUID(v)
. Il existe une solution de repli vers UUID(bytes=v)
pour bytes
et bytearray
.
Si vous souhaitez contraindre la version de l'UUID, vous pouvez vérifier les types suivants:
UUID1
: nécessite la version 1 de l'UUID.UUID3
: nécessite la version 3 de l'UUID.UUID4
: nécessite la version 4 de l'UUID.UUID5
: nécessite la version 5 de l'UUID.
Union¶
Pydantic prend en charge largement la validation des unions, à la fois typing.Union
et la syntaxe des tuyaux de Python 3.10 ( A | B
) sont prises en charge. Pour en savoir plus, consultez la section Unions
de la documentation sur les concepts.
Type
et TypeVar
¶
type
¶
Pydantic prend en charge l'utilisation de type[T]
pour spécifier qu'un champ ne peut accepter que des classes (et non des instances) qui sont des sous-classes de T
.
typing.Type
¶
Géré de la même manière que type
ci-dessus.
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]
"""
Vous pouvez également utiliser Type
pour spécifier que n'importe quelle classe est autorisée.
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
est pris en charge sans contrainte, avec contrainte ou avec une limite.
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
Aucun type¶
None
, type(None)
ou Literal[None]
sont tous équivalents selon la spécification de typage . Autorise uniquement la valeur None
.
Cordes¶
str
: Les chaînes sont acceptées telles quelles. bytes
et bytearray
sont convertis à l'aide de v.decode()
. Les Enum s inheriting from
str are converted using
v.value`. Tous les autres types provoquent une erreur.
Les chaînes ne sont pas des séquences
While instances of str
are technically valid instances of the Sequence[str]
protocol from a type-checker's point of
view, this is frequently not intended as is a common source of bugs.
As a result, Pydantic raises a ValidationError
if you attempt to pass a str
or bytes
instance into a field of type
Sequence[str]
or Sequence[bytes]
:
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] """
Octets¶
bytes
sont acceptés tels quels. bytearray
est converti en utilisant bytes(v)
. str
sont convertis en utilisant v.encode()
. int
, float
et Decimal
sont contraints à l'aide de str(v).encode()
. Voir ByteSize pour plus de détails.
typing.Literal
¶
Pydantic prend en charge l'utilisation de typing.Literal
comme moyen léger de spécifier qu'un champ ne peut accepter que des valeurs littérales spécifiques:
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]
"""
L'un des avantages de ce type de champ est qu'il peut être utilisé pour vérifier l'égalité avec une ou plusieurs valeurs spécifiques sans avoir besoin de déclarer des validateurs personnalisés:
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]
"""
Avec un classement approprié dans un Union
annoté, vous pouvez l'utiliser pour analyser les types de spécificité décroissante:
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
¶
Autorise n’importe quelle valeur, y compris None
.
typing.Annotated
¶
Permet d'encapsuler un autre type avec des métadonnées arbitraires, conformément au PEP-593 . L'indice Annotated
peut contenir un seul appel à la fonction Field
, mais sinon, les métadonnées supplémentaires sont ignorées et le type racine est utilisé.
typing.Pattern
¶
La valeur d'entrée sera transmise à re.compile(v)
pour créer un modèle d'expression régulière.
pathlib.Path
¶
Utilise simplement le type lui-même pour la validation en passant la valeur à Path(v)
.
本文总阅读量次