Configuring Validation Strictness
Configuring validation strictness allows you to control whether pydantic-core coerces input types (lax mode) or requires exact type matches (strict mode). You can apply these settings globally, at the field level, or at runtime.
Global Strictness Configuration
You can set a global strictness policy by passing a CoreConfig object to the SchemaValidator. When strict is set to True, types like integers will no longer be coerced from strings or floats.
from pydantic_core import SchemaValidator, CoreConfig, core_schema as cs
# Global strict mode enabled
config = CoreConfig(strict=True)
v = SchemaValidator(cs.int_schema(), config=config)
# This will raise a ValidationError because '123' is a string
try:
v.validate_python('123')
except Exception as e:
print(e)
Field-Level Overrides
Individual schemas like IntSchema, BoolSchema, and FloatSchema support a strict parameter that overrides the global configuration. This is useful when you want specific fields to be strict while the rest of the model remains lax, or vice versa.
from pydantic_core import SchemaValidator, CoreConfig, core_schema as cs
# Global config is strict, but the field overrides it to be lax
v = SchemaValidator(
cs.int_schema(strict=False),
config=CoreConfig(strict=True)
)
# Success: Field-level strict=False allows string coercion
assert v.validate_python('123') == 123
Runtime Strictness
You can override both the global config and the schema-level settings by passing the strict argument directly to validate_python.
from pydantic_core import SchemaValidator, core_schema as cs
v = SchemaValidator(cs.int_schema(strict=False))
# Runtime strict=True overrides the schema's strict=False
try:
v.validate_python('123', strict=True)
except Exception as e:
print("Validation failed in strict mode")
Advanced Branching with LaxOrStrictSchema
For complex scenarios where validation logic should differ entirely between lax and strict modes, use LaxOrStrictSchema. This allows you to define two separate validation paths.
from pydantic_core import SchemaValidator, core_schema as cs
v = SchemaValidator(
cs.lax_or_strict_schema(
lax_schema=cs.str_schema(), # Use string validation in lax mode
strict_schema=cs.int_schema(), # Use integer validation in strict mode
strict=True # Default to strict mode
)
)
# Uses strict_schema (int)
assert v.validate_python(123) == 123
# Uses lax_schema (str) when strict=False is passed at runtime
assert v.validate_python('hello', strict=False) == 'hello'
Validating Default Values
By default, pydantic-core does not validate default values. You can enable this globally via CoreConfig or for specific fields using WithDefaultSchema. This ensures that even default values (which might be raw input) conform to the schema.
from pydantic_core import SchemaValidator, core_schema as cs
# Enable validation for a specific default value
v = SchemaValidator(
cs.with_default_schema(
cs.int_schema(),
default='42',
validate_default=True
)
)
# The default '42' is validated against int_schema and coerced to 42
assert v.validate_python(None) == 42
Configuration Precedence
When multiple strictness settings are present, pydantic-core follows this priority (highest to lowest):
- Runtime Argument:
v.validate_python(..., strict=True) - Schema Setting:
cs.int_schema(strict=True) - Global Config:
CoreConfig(strict=True)
Similarly, for validate_default, the setting in WithDefaultSchema takes precedence over the global CoreConfig(validate_default=...).