How typing.SupportsInt and SupportsIndex Work in Python

Structural protocols like typing.SupportsInt and typing.SupportsIndex enable static duck typing in Python by verifying whether an object implements specific conversion methods. Instead of checking whether an object inherits directly from the int class, type checkers and runtime guards inspect an object's structural capabilities. This article explains how these two protocols work, how they map to Python's special dunder methods, the critical functional differences between them, and how to apply them effectively in typed code.

The Concept of Structural Protocols

Python's typing system uses structural subtyping (defined in PEP 544) to evaluate an object's type based on its operations and attributes rather than its explicit class hierarchy. The typing module provides several pre-defined protocols representing standard Python data model behaviors.

Both SupportsInt and SupportsIndex are runtime-checkable protocols. They allow static analyzers (like mypy or Pyright) and runtime functions (via isinstance()) to verify whether an arbitrary object can safely produce an integer representation.

typing.SupportsInt

The typing.SupportsInt protocol checks whether an object implements the __int__() special method. Objects satisfying this protocol can be passed directly to the built-in int() constructor for explicit type conversion.

from typing import SupportsInt

class StringLength:
    def __init__(self, text: str):
        self.text = text

    def __int__(self) -> int:
        return len(self.text)

def to_integer(val: SupportsInt) -> int:
    return int(val)

item = StringLength("hello")
print(to_integer(item))  # Outputs: 5
print(isinstance(item, SupportsInt))  # Outputs: True

This protocol accepts types where conversion to an integer may involve rounding, truncation, or transformation. For example, standard Python float instances satisfy SupportsInt because float defines __int__().

typing.SupportsIndex

The typing.SupportsIndex protocol checks whether an object implements the __index__() special method (defined in PEP 357). This method is used when Python requires a lossless, unambiguous integer value, specifically for operations like sequence indexing, slicing, and bitwise manipulation.

from typing import SupportsIndex

class CustomIndex:
    def __init__(self, position: int):
        self.position = position

    def __index__(self) -> int:
        return self.position

def get_first_elements(data: list[str], count: SupportsIndex) -> list[str]:
    return data[:count]

names = ["Alice", "Bob", "Charlie", "Diana"]
idx = CustomIndex(2)

print(get_first_elements(names, idx))  # Outputs: ['Alice', 'Bob']
print(isinstance(idx, SupportsIndex))  # Outputs: True

Unlike int(), sequence indexing does not invoke __int__(). Python requires __index__() to prevent unintentional or lossy conversions from types like float.

Key Differences Between SupportsInt and SupportsIndex

The primary difference lies in the intended semantics of truncation versus lossless integer representation:

Feature SupportsInt SupportsIndex
Required Method __int__(self) -> int __index__(self) -> int
Primary Use Case Explicit conversion via int(x) Slicing, indexing, bin(), hex()
Includes float? Yes (via truncation) No (prevents fractional indexing)
Equivalent Function int(x) operator.index(x)

Because float implements __int__ but does not implement __index__, it satisfies SupportsInt but fails SupportsIndex:

from typing import SupportsInt, SupportsIndex

value = 3.14

print(isinstance(value, SupportsInt))    # True
print(isinstance(value, SupportsIndex))  # False

When to Use Each Protocol

Use SupportsInt when writing functions that convert general numerical or custom types into an integer using int(), and where truncation or explicit type casting is acceptable.

Use SupportsIndex when writing functions that accept integer-like inputs for slicing, sequence lookup, byte manipulations, or memory offsets. Using SupportsIndex guarantees that the caller provides a type that behaves strictly as an integer without silent truncation bugs.