Skip to main content

typecheck-runtime

Tiny runtime checker for typing annotations with an Option-like API.

py-typecheck solves a very specific problem:

I have a value (object or Any) and I want to check if the value refers to specific typing annotation.

Does not parse data. Does not transforms data. Just checks structure and returns refered value or None if validation failed.

Installation

pip install typecheck-runtime

Python ≥ 3.10

Core idea

Main function is checked

from py_typecheck import checked

Acts like Option[T] or Rust-like Some(T, None):

  • returns value if matches the type
  • returns None if validation failed

No exceptions, no side-efects.


Basic usage

value: object = {"a": 1}

if (d := checked(value, dict[str, int])) is not None:
    print(d["a"] + 1)

Important

  • always compare against None when using checked
  • do not rely on truthiness (0, False, [] are valid values!)
  • bool is treated as not matching int (so True wont pass as int)

checked_or

If you want the same runtime check as checked(), but with a convenient fallback, use checked_or().

  • returns the original value if it matches the target type
  • otherwise returns the provided default

This is especially handy when you want a safe, typed value in one expression without handling None.

from py_typecheck import checked_or

age: object = "not-a-number"

# returns 10 because "not-a-number" is not an int
value = checked_or(age, int, 10)

Works with typing constructs the same way as checked():

from py_typecheck import checked_or

payload: object = {"tags": ["a", "b"]}

tags = checked_or(payload, dict[str, list[str]], {"tags": []})["tags"]

Important notes:

  • checked_or() relies on checked() semantics (including the bool vs int rule)
  • default should already be the correct value you want to use (no coercion happens)

Supported typing constructs

py-typecheck supports common runtime-validable constructs from typing:

Primitive types

checked(1, int)          # 1
checked("x", int)        # None
checked(True, int)       # None

Note: bool is not considered an int in this library.

Union (X | Y, typing.Union)

checked(1, int | str)      # 1
checked("x", int | str)    # "x"
checked(1.5, int | str)    # None

List / Set / FrozenSet

checked([1, 2], list[int])           # [1, 2]
checked({1, 2}, set[int])            # {1, 2}
checked(frozenset({1}), frozenset[int])

Nested structures work as expected:

checked([[1, 2], [3]], list[list[int]])

Dict

checked({"a": 1}, dict[str, int])
checked({"a": "x"}, dict[str, int])   # None

Supports unions and nesting:

checked({"a": [1, 2]}, dict[str, list[int]])

Tuple

Fixed-length:

checked((1, "x"), tuple[int, str])

Variadic:

checked((1, 2, 3), tuple[int, ...])

Literal

from typing import Literal

checked(True, Literal[True])    # True
checked(False, Literal[True])   # None

Any

from typing import Any

checked(object(), Any)   # always matches

is_type

There is also a boolean helper:

from py_typecheck import is_type

if is_type(value, dict[str, int]):
    ...
  • It returns only True / False.
  • For most code paths, checked is preferred, because it avoids type confusion and double-checking mistakes.

Design principles

  • Explicit is better than clever
  • No exceptions for control flow
  • No implicit casting
  • No data mutation
  • No dependency on dataclasses or models
  • One function, one responsibility

This is not a validator framework. This is a runtime structural check with a safe return value.

Non-goals

py-typecheck intentionally does not:

  • coerce types ("1" → 1)
  • fill defaults
  • validate constraints (ranges, regexes, etc.)
  • replace pydantic or attrs

If you want parsing + validation + coercion → use Pydantic. If you want “is this already the right shape?” → use this.


Comparison

Tool Purpose
isinstance Runtime type only
typing Static type checking
pydantic Parsing + validation + coercion
py-typecheck Runtime structural check only

Development status

  • Fully typed (basedpyright strict)
  • Tested against Python 3.10 – 3.13
  • CI + lint + coverage
  • Small surface area, easy to audit

License MIT

Metadata

Release files for typecheck-runtime 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for typecheck-runtime 0.2.0
File Size Uploaded Provenance Actions
typecheck_runtime-0.2.0.tar.gz 7.8 kB With provenance Details for typecheck_runtime-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for typecheck-runtime 0.2.0
File Interpreter ABI Platform Actions
typecheck_runtime-0.2.0-py3-none-any.whl Python 3 none any Details for typecheck_runtime-0.2.0-py3-none-any.whl

Total release size: 13.2 kB

Release files / typecheck_runtime-0.2.0.tar.gz

Download URL typecheck_runtime-0.2.0.tar.gz
Size 7.8 kB
Tags Source
SHA-256 checksum
How to use checksums
9e61569045a0d9f346c677e7da49004ebc4b861b25c49c2479391808d28e071a
BLAKE2b-256 checksum
How to use checksums
ac70869d7c6a217b1ba88d6b4a894221964d5b7c63b1110ba9bf101133ac0071
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.

Transparency log

Release files / typecheck_runtime-0.2.0-py3-none-any.whl

Download URL typecheck_runtime-0.2.0-py3-none-any.whl
Size 5.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
757a93909928c333c112761fef994e87d899ba3a744e05f26a1d698d83e7b304
BLAKE2b-256 checksum
How to use checksums
6f19ffa7e20b9aab5a5896bdeb54cc062c57f44fd8cb640945d1a3e9f8bfc7cf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.

Transparency log

Security for typecheck-runtime 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for typecheck_runtime-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jan 18, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page