Skip to content

optype

Building blocks for precise & flexible type hints

GitHub License PyPI Version Conda Version Python Versions PyPI Downloads

numpy basedpyright mypy pyrefly ty ruff


What is optype?

optype is a Python library that provides building blocks for precise and flexible type hints. It focuses on typing utilities and has optional elaborate NumPy support. The library is compatible with all modern static type-checkers (mypy, basedpyright, pyright, pyrefly, ty) and also works with runtime type-checkers like beartype.

Key Features

  • Comprehensive Protocol Collection: Single-method protocols for all builtin special methods (Can* protocols)
  • Precise Type Control: Just[T] types that reject strict subtypes (e.g., reject bool when you want int)
  • Standard Library Support: Type protocols for copy, pickle, json, io, inspect, and more
  • NumPy Integration: Extensive shape-typing, array protocols, and dtype utilities
  • No Dependencies: Core library has zero dependencies (NumPy support is optional)

Quick Example

Let's say you're writing a twice(x) function that evaluates 2 * x. Implementing it is trivial, but what about the type annotations?

Because twice(2) == 4, twice(3.14) == 6.28, and twice('I') == 'II', it might seem like a good idea to type it as twice[T](x: T) -> T: .... However, that wouldn't include cases such as twice(True) == 2 or twice((42, True)) == (42, True, 42, True), where the input and output types differ.

Moreover, twice should accept any type with a custom __rmul__ method that accepts 2 as an argument.

This is where optype comes in handy. Use optype.CanRMul[T, R], which is a protocol with (only) the __rmul__(self, lhs: T) -> R method:

from typing import Literal
import optype as op

type Two = Literal[2]
type RMul2[R] = op.CanRMul[Two, R]


def twice[R](x: RMul2[R]) -> R:
    return 2 * x
from typing import Literal, TypeAlias, TypeVar
import optype as op

R = TypeVar("R")
Two: TypeAlias = Literal[2]
RMul2: TypeAlias = op.CanRMul[Two, R]


def twice(x: RMul2[R]) -> R:
    return 2 * x

See the Getting Started guide for more detailed examples.

Next Steps