new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Pydantic · all subjects

validation

23 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Pydantic default data coercion behavior

By default, Pydantic is tolerant to common incorrect types and coerces data to the right type. For example, a numeric string passed to an int field will be parsed as an int.

Strict mode prevents type coercion

Pydantic has a strict mode where types are not coerced and a validation error is raised unless the input data exactly matches the expected schema.

Strict mode and JSON validation example

Example showing strict mode behavior and JSON validation: from datetime import datetime from pydantic import BaseModel, ValidationError class Meeting(BaseModel): when: datetime where: bytes m = Meeting.model_validate({'when': '2020-01-01T12:00', 'where': 'home'}) print(m) #> when=datetime.datetime(2020, 1, 1, 12, 0) where=b'home' try: m = Meeting.model_validate( {'when': '2020-01-01T12:00', 'where': 'home'}, strict=True ) except ValidationError as e: print(e) """ 2 validation errors for Meeting when Input should be a valid datetime [type=datetime_type, input_value='2020-01-01T12:00', input_type=str] where Input should be a valid bytes [type=bytes_type, input_value='home', input_type=str] """ m_json = Meeting.model_validate_json( '{"when": "2020-01-01T12:00", "where": "home"}' ) print(m_json) #> when=datetime.datetime(2020, 1, 1, 12, 0) where=b'home'

validate_call decorator purpose

The validate_call() decorator allows the arguments passed to a function to be parsed and validated using the function's annotations before the function is called. Under the hood it uses the same approach of model creation and initialisation.

validate_call parameter type inference

Parameter types are inferred from type annotations on the function, or as Any if not annotated. All types listed in Pydantic's types documentation can be validated, including Pydantic models and custom types. By default, types are coerced by the decorator before they are passed to the actual function.

validate_call return value validation

By default, the return value of the function is not validated. To validate the return value, the validate_return argument of the decorator must be set to True.

validate_call function signature support

The validate_call() decorator works with all possible parameter configurations: positional or keyword parameters with or without defaults, keyword-only parameters (after *,), positional-only parameters (before /, ), variable positional parameters (*args), and variable keyword parameters (**kwargs).

validate_call with Field function

The Field() function can be used with validate_call to provide extra information about the field and validations. When using Field with constraints but no default or default_factory, the Annotated pattern is recommended so type checkers infer the parameter as required. Otherwise, Field() can be used as a default value.

validate_call raw_function attribute

The original function which was decorated can be accessed by using the raw_function attribute. This is useful when in some scenarios you trust your input arguments and want to call the function in the most efficient way without validation.

validate_call with async functions

The validate_call() decorator can also be used on async functions, validating arguments before the async function executes.

validate_call type checker compatibility

The validate_call() decorator preserves the decorated function's signature, making it compatible with type checkers such as mypy and pyright. However, the raw_function attribute and other added attributes won't be recognized by type checkers and require suppression with a # type: ignore comment.

validate_call custom configuration

The config parameter of the validate_call decorator can be used to specify a custom configuration using ConfigDict, similar to Pydantic models.

validate_call performance considerations

While the inspection of the decorated function is only performed once, there will be a performance impact when making calls to the function compared to using the original function. validate_call() is not an equivalent or alternative to function definitions in strongly typed languages.

validate_call example with basic usage

from pydantic import ValidationError, validate_call @validate_call def repeat(s: str, count: int, *, separator: bytes = b'') -> bytes: b = s.encode() return separator.join(b for _ in range(count)) a = repeat('hello', 3) print(a) #> b'hellohellohello' b = repeat('x', '4', separator=b' ') print(b) #> b'x x x x' try: c = repeat('hello', 'wrong') except ValidationError as exc: print(exc) """ 1 validation error for repeat 1 Input should be a valid integer, unable to parse string as an integer [type=int_parsing, input_value='wrong', input_type=str] """

validate_call example with type coercion

from datetime import date from pydantic import validate_call @validate_call def greater_than(d1: date, d2: date, *, include_equal=False) -> date: if include_equal: return d1 >= d2 else: return d1 > d2 d1 = '2000-01-01' # string, will be converted to date object d2 = date(2001, 1, 1) greater_than(d1, d2, include_equal=True)

validate_call example with Field constraints

from typing import Annotated from pydantic import Field, ValidationError, validate_call @validate_call def how_many(num: Annotated[int, Field(gt=10)]): return num try: how_many(1) except ValidationError as e: print(e) """ 1 validation error for how_many 0 Input should be greater than 10 [type=greater_than, input_value=1, input_type=int] """

validate_call example with Field alias

from typing import Annotated from pydantic import Field, validate_call @validate_call def how_many(num: Annotated[int, Field(gt=10, alias='number')]): return num how_many(number=42)

validate_call example accessing raw_function

from pydantic import validate_call @validate_call def repeat(s: str, count: int, *, separator: bytes = b'') -> bytes: b = s.encode() return separator.join(b for _ in range(count)) a = repeat('hello', 3) print(a) #> b'hellohellohello' b = repeat.raw_function('good bye', 2, separator=b', ') print(b) #> b'good bye, good bye'

validate_call example with async function

import asyncio from pydantic import PositiveInt, ValidationError, validate_call @validate_call async def get_user_email(user_id: PositiveInt): email = await conn.execute('select email from users where id=$1', user_id) if email is None: raise RuntimeError('user not found') else: return email async def main(): email = await get_user_email(123) print(email) try: await get_user_email(-4) except ValidationError as exc: print(exc.errors()) asyncio.run(main())

validate_call example with custom configuration

from pydantic import ConfigDict, ValidationError, validate_call class Foobar: def __init__(self, v: str): self.v = v def __add__(self, other: 'Foobar') -> str: return f'{self} + {other}' def __str__(self) -> str: return f'Foobar({self.v})' @validate_call(config=ConfigDict(arbitrary_types_allowed=True)) def add_foobars(a: Foobar, b: Foobar): return a + b c = add_foobars(Foobar('a'), Foobar('b')) print(c) #> Foobar(a) + Foobar(b)

validate_call example with all parameter types

from pydantic import validate_call @validate_call def armageddon( a: int, /, b: int, *c: int, d: int, e: int = None, **f: int, ) -> str: return f'a={a} b={b} c={c} d={d} e={e} f={f}' print(armageddon(1, 2, d=3)) #> a=1 b=2 c=() d=3 e=None f={} print(armageddon(1, 2, 3, 4, 5, 6, d=8, e=9, f=10, spam=11)) #> a=1 b=2 c=(3, 4, 5, 6) d=8 e=9 f={'f': 10, 'spam': 11}

validate_call with Unpack for typed keyword parameters

The Unpack type from typing_extensions can be used to annotate variable keyword parameters of a function decorated with validate_call. This works with TypedDict to provide typed keyword arguments.

validate_call example with Unpack TypedDict

from typing_extensions import TypedDict, Unpack from pydantic import validate_call class Point(TypedDict): x: int y: int @validate_call def add_coords(**kwargs: Unpack[Point]) -> int: return kwargs['x'] + kwargs['y'] add_coords(x=1, y=2)

Give your agent this brain