Engineering note / OpenAPI schemas

Fixing int64 format detection for negative IntegerField minimums

DRF's OpenAPI generator correctly emitted format: int64 when integer bounds exceeded the signed int32 maximum, but omitted it when negative minimums extended below the signed int32 minimum. PR #9989 restored symmetric 32-bit boundary detection.

Project
Django REST Framework
Contribution
PR #9989
Context
Issue #9980
Role
PR author
Outcome
Merged upstream (encode:main)

OpenAPI integer formats require symmetric boundary checks.

In OpenAPI 3.0 specification mappings, integers without an explicit format default to standard signed 32-bit integers (ranging from -2,147,483,648 to 2,147,483,647). When an IntegerField is configured with boundaries that exceed 32-bit signed storage, the generator must emit format: "int64" so API client generators and documentation accurately reflect the 64-bit integer type.

Django REST Framework’s AutoSchema field mapping handled values extending past the signed int32 upper bound (> 2,147,483,647), but failed to detect when a negative minimum value dropped below the signed int32 lower bound (< -2,147,483,648). PR #9989, authored by Zain Nadeem, resolved this discrepancy.

Upper-bound check existed without its lower-bound counterpart.

In rest_framework/schemas/openapi.py, the logic mapping serializers.IntegerField checked whether field.max_value or field.min_value exceeded 2147483647. However, no condition checked whether field.min_value was less than -2147483648.

As a result, a field like IntegerField(max_value=2147483648) correctly generated format: int64, while an equally oversized negative range like IntegerField(min_value=-2147483649) generated only "type": "integer" without format: int64.

Configured valuemin_value = -2147483649
Omitted formatmin < -2147483648 not checked → format omitted

Enforce both signed 32-bit limits with integer coercion.

The patch adds the missing lower signed-int32 boundary check while preserving comparison-time int() coercion. During maintainer review, it was confirmed that field bounds can occasionally be configured as non-coerced strings or numbers, so keeping explicit int() coercion ensures safe comparison across all valid boundary inputs.

# Signed int32 limits: [-2147483648, 2147483647]
if (
    field.max_value is not None and int(field.max_value) > 2147483647
    or field.min_value is not None and (
        int(field.min_value) > 2147483647 or int(field.min_value) < -2147483648
    )
):
    content["format"] = "int64"

Precision schema metadata without runtime side effects.

This is a focused OpenAPI schema metadata fix. It does not alter serializer validation, runtime data parsing, BigIntegerField handling, or coerce_to_string options.

Configured FieldPrevious SchemaFixed Schema
IntegerField(min_value=-2147483649){"type": "integer", "minimum": -2147483649}{"type": "integer", "minimum": -2147483649, "format": "int64"}
IntegerField(min_value=-2147483648){"type": "integer", "minimum": -2147483648}{"type": "integer", "minimum": -2147483648} (no format)
IntegerField(max_value=2147483647){"type": "integer", "maximum": 2147483647}{"type": "integer", "maximum": 2147483647} (no format)
IntegerField(max_value=2147483648){"type": "integer", "maximum": 2147483648, "format": "int64"}{"type": "integer", "maximum": 2147483648, "format": "int64"}
IntegerField(min_value=2147483648){"type": "integer", "minimum": 2147483648, "format": "int64"}{"type": "integer", "minimum": 2147483648, "format": "int64"}

Exhaustive boundary regression test coverage.

Regression tests were added to tests/schemas/test_openapi.py under TestFieldMapping. The test cases verify that -2147483649 triggers format: int64, while boundary values -2147483648 and 2147483647 remain formatted as standard integers without format tags.

Focused field-mapping test execution passed with 7 passed and 23 subtests passed (pytest tests/schemas/test_openapi.py::TestFieldMapping). All 7 continuous integration checks passed on the PR.

Boundary logic must be tested symmetrically.

  • When mapping typed primitives to specification formats, test both positive and negative overflow boundaries.
  • Schema generators are contracts: omitting format metadata causes generated client SDKs to allocate undersized types.
  • Maintain coercion guards on field properties to prevent unexpected type errors during schema export.
  • Targeted metadata improvements preserve full backward compatibility for existing runtime pipelines.

Authoritative upstream record.