Skip to main content

Type dispatch and validation for run-time Python

Project description

alt text

Runtype is a collection of run-time type utilities for Python.

It is:

:runner: Fast! Uses an internal typesystem for maximum performance.

:brain: Smart! Supports typing, forward-references, constraints, auto-casting, and more.

:gear: Configurative! Write your own type system, and use it with dataclass and dispatch.


Modules

  • :star: validation - Provides a smarter alternative to isinstance and issubclass, with support for the typing module, and type constraints.

  • :star: dataclass - Adds run-time type validation to the built-in dataclass.

    • Improves dataclass ergonomics.
    • Supports most mypy constructs, like typing and forward-references (foo: 'Bar').
    • Supports automatic value casting, Pydantic-style. (Optional, off by default)
    • Supports types with constraints. (e.g. String(max_length=10))
    • Supports optional sampling for faster validation of big lists and dicts.
    • Twice faster than Pydantic-v1 with pure Python (read here)
  • :star: dispatch - Provides fast multiple-dispatch for functions and methods, via a decorator.

    • Dispatch on multiple arguments
    • Full specificity resolution
    • Supports mypy, by utilizing the @overload decorator
    • Inspired by Julia.
  • :star: type utilities - Provides a set of classes to implement your own type-system.

    • Supports generics, constraints, phantom types
    • Used by runtype itself, to emulate the Python type-system.

Docs

Read the docs here: https://runtype.readthedocs.io/

Install

pip install runtype

No dependencies.

Requires Python 3.8 or up.

codecov

Examples

Validation (Isa & Subclass)

Use isa and issubclass as a smarter alternative to the builtin isinstance & issubclass -

from runtype import isa, issubclass

assert isa({'a': 1}, dict[str, int])        # == True
assert not isa({'a': 'b'}, dict[str, int])  # == False

assert issubclass(dict[str, int], typing.Mapping[str, int])     # == True
assert not issubclass(dict[str, int], typing.Mapping[int, str]) # == False

Dataclasses

from runtype import dataclass

@dataclass(check_types='cast')  # Cast values to the target type, when applicable
class Person:
    name: str
    birthday: datetime = None   # Implicit optional
    interests: list[str] = []   # The list is copied for each instance


print( Person("Beetlejuice") )
#> Person(name='Beetlejuice', birthday=None, interests=[])
print( Person("Albert", "1955-04-18T00:00", ['physics']) )
#> Person(name='Albert', birthday=datetime.datetime(1955, 4, 18, 0, 0), interests=['physics'])
print( Person("Bad", interests=['a', 1]) )
# TypeError: [Person] Attribute 'interests' expected value of type list[str]. Instead got ['a', 1]
#     Failed on item: 1, expected type str

Multiple Dispatch

Runtype dispatches according to the most specific type match -

from runtype import multidispatch as md

@md
def mul(a: list, b: list):
    return [mul(i, j) for i, j in zip(a, b, strict=True)]
@md
def mul(a: list, b: Any):
    return [ai*b for ai in a]
@md
def mul(a: Any, b: list):
    return [bi*b for bi in b]
@md
def mul(a: Any, b: Any):
    return a * b

assert mul("a", 4)         == "aaaa"        # Any, Any
assert mul([1, 2, 3], 2)   == [2, 4, 6]     # list, Any
assert mul([1, 2], [3, 4]) == [3, 8]        # list, list

Dispatch can also be used for extending the dataclass builtin __init__:

@dataclass
class Point:
    x: int = 0
    y: int = 0

    @md
    def __init__(self, points: list | tuple):
        # Call default constructor
        self.__init__(*points)

    @md
    def __init__(self, points: dict):
        # Call default constructor
        self.__init__(points['x'], points['y'])

# Test constructors
p0 = Point()                         # Default constructor
assert p0 == Point(0, 0)             # Default constructor
assert p0 == Point([0, 0])           # User constructor
assert p0 == Point((0, 0))           # User constructor
assert p0 == Point({"x": 0, "y": 0}) # User constructor

Benchmarks

Runtype beats its competition handily. It is significantly faster than both beartype and plum, and in some cases is even faster than regular Python code.

See the benchmarks page in the documentation for detailed benchmarks.

alt text

alt text

License

Runtype uses the MIT license.

Contribute

If you like Runtype and want to see it grow, you can help by:

  • Reporting bugs or suggesting features

  • Submitting pull requests (better to ask me first)

  • Writing about runtype in a blogpost or even a tweet

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

runtype-0.5.3.tar.gz (30.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

runtype-0.5.3-py3-none-any.whl (31.9 kB view details)

Uploaded Python 3

File details

Details for the file runtype-0.5.3.tar.gz.

File metadata

  • Download URL: runtype-0.5.3.tar.gz
  • Upload date:
  • Size: 30.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.4 Darwin/23.6.0

File hashes

Hashes for runtype-0.5.3.tar.gz
Algorithm Hash digest
SHA256 ccaec05c74f8d213342b9fc25e304560d114bc4d72ec117639cd1e7af9c5db1f
MD5 a7e5f86b7dddd40ca10c1c7ded5f78c4
BLAKE2b-256 6076d8a0f754c834c3d71a0896b1d40a1938244aab4bb5b4bab0b21d21525694

See more details on using hashes here.

File details

Details for the file runtype-0.5.3-py3-none-any.whl.

File metadata

  • Download URL: runtype-0.5.3-py3-none-any.whl
  • Upload date:
  • Size: 31.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.8.3 CPython/3.12.4 Darwin/23.6.0

File hashes

Hashes for runtype-0.5.3-py3-none-any.whl
Algorithm Hash digest
SHA256 ea8cc6828217ebfda5c159dce969e832efd865a09d6ad1fc993f5bf5e1a627ee
MD5 63ca68f32bed8d1dc181468d1dfd21f2
BLAKE2b-256 80db879902580d720925092c86eaab2ceee7493e2fadbb5b718f54289b04d277

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page