Skip to main content

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 int objects.
  • Strings that can be parsed as integers (e.g., '42').
  • Floats that have no fractional part (e.g., 42.0).
  • Booleans (True becomes 1, False becomes 0).

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:

  • complex objects.
  • Strings following Python's complex number syntax (e.g., '1+2j', 'j', '-1.5-j').
  • Integers and floats (treated as the real part with 0j imaginary).
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 like pydantic.
  • serialization: Customizes how the numeric value is converted back to JSON or Python objects via SerSchema.