Numeric Types
Numeric validation in pydantic-core is handled by four primary schemas: IntSchema, FloatSchema, DecimalSchema, and ComplexSchema. These schemas provide fine-grained control over numeric types, including range constraints, precision limits, and coercion rules between Python and JSON.
Integers
The IntSchema (defined in pydantic_core/core_schema.py) validates integer values. It supports standard range constraints and a multiple_of requirement.
Constraints and Validation
Integers can be constrained using the following fields:
ge: Greater than or equal to.gt: Greater than.le: Less than or equal to.lt: Less than.multiple_of: The value must be a multiple of this integer.
In Lax mode (default), IntSchema accepts:
- Actual
intobjects. - Strings that can be parsed as integers (e.g.,
'42'). - Floats that have no fractional part (e.g.,
42.0). - Booleans (
Truebecomes1,Falsebecomes0).
In Strict mode (strict=True), only actual int objects are accepted during Python validation.
from pydantic_core import SchemaValidator, core_schema as cs
# Integer with range and multiple_of constraints
v = SchemaValidator(cs.int_schema(multiple_of=2, le=10, ge=2))
assert v.validate_python('4') == 4
assert v.validate_python(6.0) == 6
Security: Integer Parsing Limits
To prevent potential Denial of Service (DoS) attacks via extremely large integer strings, pydantic-core enforces a maximum character limit for integer parsing. By default, strings exceeding 4300 characters will trigger an int_parsing_size error.
# Exceeding the default parsing limit
v = SchemaValidator(cs.int_schema())
# v.validate_python('1' * 4301) # Raises ValidationError: int_parsing_size
Floating-Point Numbers
The FloatSchema validates floating-point numbers and shares many constraints with IntSchema.
Special Values: Infinity and NaN
A key feature of FloatSchema is the allow_inf_nan flag, which defaults to True. This allows the validator to accept 'NaN', '+inf', and '-inf'.
v = SchemaValidator(cs.float_schema(allow_inf_nan=True))
assert v.validate_python('NaN').__str__() == 'nan'
Coercion Behavior
In Lax mode, FloatSchema accepts integers, strings, and booleans. In Strict mode, it only accepts float instances in Python validation, though it will still accept numbers from JSON.
Decimals
The DecimalSchema provides validation for decimal.Decimal objects, offering higher precision than standard floats.
Precision Constraints
In addition to range constraints, DecimalSchema supports:
max_digits: Total number of allowed digits.decimal_places: Maximum number of allowed decimal places.
Unlike FloatSchema, DecimalSchema defaults allow_inf_nan to False.
from decimal import Decimal
from pydantic_core import SchemaValidator, core_schema as cs
v = SchemaValidator(cs.decimal_schema(max_digits=5, decimal_places=2))
assert v.validate_python('123.45') == Decimal('123.45')
# v.validate_python('123.456') # Raises ValidationError (decimal_places)
Strict Mode and JSON
In Strict mode, DecimalSchema only accepts Decimal instances during Python validation. However, because JSON does not have a native decimal type, it continues to accept strings and numbers when validating JSON data, provided they are valid decimal representations.
Complex Numbers
The ComplexSchema validates complex numbers. It is unique in its ability to parse complex string representations.
Parsing and Coercion
In Lax mode, it accepts:
complexobjects.- Strings following Python's complex number syntax (e.g.,
'1+2j','j','-1.5-j'). - Integers and floats (treated as the real part with
0jimaginary).
v = SchemaValidator(cs.complex_schema())
assert v.validate_python('1+2j') == complex(1, 2)
assert v.validate_python(3) == complex(3, 0)
In Strict mode, only actual complex instances are accepted during Python validation.
Common Features
Multiple Of
The multiple_of constraint is available for IntSchema, FloatSchema, and DecimalSchema. It ensures that the input value v satisfies v % multiple_of == 0. For floating-point and decimal types, this is handled with appropriate precision to avoid common floating-point math issues.
Metadata and Serialization
All numeric schemas support:
ref: Used for recursive schemas or shared definitions.metadata: A dictionary for storing extra information, often used by downstream libraries likepydantic.serialization: Customizes how the numeric value is converted back to JSON or Python objects viaSerSchema.