Skip to main content

A statically-typed authoring language that compiles to standard Python

Project description

TypePython

TypePython

Write richer types in .tpy. Ship plain .py + .pyi.


TypePython is a typed dialect of Python that compiles to standard .py + .pyi. It brings author-time TypeScript-class ergonomics — sealed classes, exhaustive match, strict null checks, unknown, interface, data class — to a language whose output runs anywhere CPython runs.

Those stronger checks are enforced while authoring .tpy; emitted artifacts remain standard Python and do not transfer every TypePython-only constraint to downstream checkers.

No custom runtime. No required per-checker plugin for emitted output. No vendor lock-in.

Status: Core v1.0 RC (v1.0.0-rc.1). Core syntax, config, init/check/ build/clean/verify, Core checker semantics, diagnostic code identity, and emitted .py/.pyi compatibility are the release-candidate surfaces. Supported DX, Experimental opt-in, and Roadmap / prototype features remain outside the Core v1.0 RC compatibility promise and are tracked separately in the Experimental Feature Registry. This is not a full product-wide v1.0 RC: editor UX, VS Code packaging, watch, migration heuristics, and research slices remain outside the stable v1.0 promise until their own gates are complete. Bug reports and contributions are very welcome.

Install

pip install type-python
typepython init --dir hello && cd hello
typepython check --project .
typepython build --project .

You now have .typepython/build/ with .py + .pyi + py.typed ready for any Python interpreter, IDE, or downstream type checker.

  • Wheels are prebuilt for Windows AMD64, macOS x86_64, macOS arm64, and Linux x86_64. Other platforms fall back to source and need Rust + cargo. Wheels are tagged py3-none-<platform> because the bundled Rust CLI is platform-specific while the Python wrapper is ABI-independent.
  • Python: the package bridge supports 3.9+; generated projects target Python 3.10 through 3.14.

See it in 15 lines

# src/app/expr.tpy

sealed class Expr:
    pass

class Num(Expr):  value: int
class Add(Expr):  left: Expr; right: Expr
class Neg(Expr):  operand: Expr

def evaluate(expr: Expr) -> int:
    match expr:
        case Num(value=v):           return v
        case Add(left=l, right=r):   return evaluate(l) + evaluate(r)
        case Neg(operand=o):         return -evaluate(o)
    # No default branch needed — the compiler proves the match is exhaustive.
    # Add a fourth subclass and TypePython tells you exactly where to update.

typepython build lowers that to ordinary Python and writes a matching .pyi that any modern type checker can consume — no TypePython runtime required. The exhaustiveness proof happens before emit; downstream tools see a normal Python class hierarchy.

What you write vs. what ships

You write (.tpy) TypePython emits (.py / .pyi)
interface Drawable: class Drawable(Protocol):
data class User: @dataclass class User:
sealed class Expr: ordinary class + tpy:sealed marker
overload def parse(...) @overload def parse(...)
typealias Pair[T] = tuple[T, T] T = TypeVar("T") + Pair: TypeAlias = tuple[T, T]
def first[T](xs: list[T]) -> T: inline generic on 3.13+, TypeVar-based on 3.10 – 3.12
unsafe: eval(expr) valid Python, marker erased — runtime behavior preserved
unknown (must narrow before use) object in .pyi
Partial[Config] / Pick[Config, …] expanded TypedDict shapes (PEP 655 / 705)

Why not just mypy / pyright / PEP 695?

The comparison below is about .tpy authoring inside the package checked by TypePython. Emitted .py / .pyi remain standard Python typing, so external consumers do not automatically inherit TypePython-only constraints such as sealed exhaustiveness or unknown strictness.

Capability mypy strict pyright strict PEP 695 .py TypePython .tpy authoring
sealed class + compiler-proved exhaustiveness
unknown — safe dynamic boundary, must narrow
unsafe: audit fence for eval / exec / setattr
First-class interface / data class / typealias via via via keyword
Inline generics def f[T] on any target ≥ 3.10 3.12+ 3.12+ 3.12+
TypedDict transforms (Partial, Pick, Readonly…)
Output consumed by mypy / pyright / basedpyright / ty unmodified N/A N/A

TypePython doesn't replace those checkers. It sits one step earlier: you author in .tpy, the compiler emits standard typed Python that those tools then consume normally.

The strongest TypePython guarantees are author-time checks. Emitted artifacts remain standard Python: sealed exhaustiveness, unknown strictness, and unsafe: fences are enforced by TypePython during authoring, but external checkers see the portable .py / .pyi boundary. Carrying TypePython-only semantics across that boundary requires an opt-in sidecar, checker plugin, or TypePython-aware consumer.

What you also get

  • Rust-native, incremental compiler — public-API fingerprints skip downstream rechecks when only a body changes.
  • Full toolchaininit, check, build, watch, clean, verify, compat, api-diff, type-health, migrate, lsp.
  • Supported DX LSP server — hover, go to definition, references, rename, completions, signature help, real-time diagnostics, and code-action quick fixes. The repository includes a source-installable VS Code extension plus copy-paste setup for Neovim, Helix, Sublime Text, and Emacs. Editor UX and extension packaging are still outside the Core v1.0 RC compatibility promise.
  • Standard, portable output — emitted .py + .pyi work with mypy, pyright, and ty out of the box. PEP 561 py.typed is written automatically.
  • Mixed projects.tpy, .py, and .pyi live in the same source tree. .py is pass-through; .pyi is stub-authoritative.

For library authors

Five commands aimed at people who publish typed Python:

typepython build       --project .
typepython verify      --project . --checker-preset all
typepython compat      --project . --profile library-portable
typepython api-diff    dist/previous.whl .typepython/build
typepython type-health --project . --fail-under 85

These catch missing/stale py.typed, wheel ↔ build-tree drift, multi-checker portability gaps, public-API drift between releases, and runtime-annotation hazards for frameworks that introspect annotations. They validate the standard published surface; they do not make ordinary downstream .py checkers enforce TypePython-only facts.

Documentation

Links

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

type_python-1.0.0rc1.tar.gz (1.1 MB view details)

Uploaded Source

Built Distributions

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

type_python-1.0.0rc1-py3-none-win_amd64.whl (5.4 MB view details)

Uploaded Python 3Windows x86-64

type_python-1.0.0rc1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl (5.5 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

type_python-1.0.0rc1-py3-none-macosx_11_0_arm64.whl (4.9 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

type_python-1.0.0rc1-py3-none-macosx_10_13_x86_64.whl (5.4 MB view details)

Uploaded Python 3macOS 10.13+ x86-64

File details

Details for the file type_python-1.0.0rc1.tar.gz.

File metadata

  • Download URL: type_python-1.0.0rc1.tar.gz
  • Upload date:
  • Size: 1.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for type_python-1.0.0rc1.tar.gz
Algorithm Hash digest
SHA256 8066815ebea49ed7f9d19f80497d9065069a05f3570780c81deaed13fba7ad2f
MD5 88ae484cae6dd1f000beb4f24893568c
BLAKE2b-256 d41d95f6e1fc631be55341c0e8cc2b77f5390d50f79f34d2ba082f430d3a6b22

See more details on using hashes here.

Provenance

The following attestation bundles were made for type_python-1.0.0rc1.tar.gz:

Publisher: publish.yml on type-python/type-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file type_python-1.0.0rc1-py3-none-win_amd64.whl.

File metadata

File hashes

Hashes for type_python-1.0.0rc1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 f4147a361b4a441cd5ace16c64b9f01f0dd4b5f5829976d51cd84b006cad2871
MD5 8e1af9915e5fcb60d9667dc84b194693
BLAKE2b-256 a52020ac63fd382307df458c7ca65dc638f97272f6bdef5cdce9f4d91b1c3315

See more details on using hashes here.

Provenance

The following attestation bundles were made for type_python-1.0.0rc1-py3-none-win_amd64.whl:

Publisher: publish.yml on type-python/type-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file type_python-1.0.0rc1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl.

File metadata

File hashes

Hashes for type_python-1.0.0rc1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 0010e62657816e31b4265ee6fc627486fa08278b5fbcb05b0ed0c802c6e1d24f
MD5 61acba0a3c902a166fdb033afc48f263
BLAKE2b-256 321209d4fc7cd550bb393244069fb06d8af4281064038e1487bfe169de5ded43

See more details on using hashes here.

Provenance

The following attestation bundles were made for type_python-1.0.0rc1-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl:

Publisher: publish.yml on type-python/type-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file type_python-1.0.0rc1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for type_python-1.0.0rc1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2b76a744f08791dcd579cb6045344ded28f8063226355b33e8fd69217feced0e
MD5 1ed274f18ead36358917e8dbf7f1f69b
BLAKE2b-256 710d82f9a6bc2aad99dd9c3826dea604b7ef5f2b1b19e26c191d0ec4e1ab2ada

See more details on using hashes here.

Provenance

The following attestation bundles were made for type_python-1.0.0rc1-py3-none-macosx_11_0_arm64.whl:

Publisher: publish.yml on type-python/type-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file type_python-1.0.0rc1-py3-none-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for type_python-1.0.0rc1-py3-none-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 09d34075c31224609d81b7ca7bd64dd986c6e21493390c88abe8455325df6256
MD5 7d17ff43f8ec3233b38a9b7847f0dcd2
BLAKE2b-256 264a1d42a22927dd5220fb2b528e8a869b309d51362ed6651e0d2e0825d39628

See more details on using hashes here.

Provenance

The following attestation bundles were made for type_python-1.0.0rc1-py3-none-macosx_10_13_x86_64.whl:

Publisher: publish.yml on type-python/type-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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