typical: Python's Typing Toolkit
Introduction
Typical is a library devoted to runtime analysis, inference, validation, and enforcement of Python types, PEP 484 Type Hints, and custom user-defined data-types.
Typical is fully compliant with the following Python Typing PEPs:
- PEP 484 -- Type Hints
- PEP 563 -- Postponed Evaluation of Annotations
- PEP 585 -- Type Hinting Generics In Standard Collections
- PEP 586 -- Literal Types
- PEP 589 -- TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys
- PEP 604 -- Allow writing union types as X | Y
It provides a high-level Protocol API, Functional API, and Object API to suit most any occasion.
Getting Started
Installation is as simple as pip install -U typical.
Help
The latest documentation is hosted at python-typical.org.
Starting with version 2.0, All documentation is hand-crafted markdown & versioned documentation can be found at typical's Git Repo. (Versioned documentation is still in-the-works directly on our domain.)
A Typical Use-Case
The decorator that started it all:
typic.al(...)
import typic
@typic.al
def hard_math(a: int, b: int, *c: int) -> int:
return a + b + sum(c)
hard_math(1, "3")
#> 4
@typic.al(strict=True)
def strict_math(a: int, b: int, *c: int) -> int:
return a + b + sum(c)
strict_math(1, 2, 3, "4")
#> Traceback (most recent call last):
#> ...
#> typic.constraints.error.ConstraintValueError: Given value <'4'> fails constraints: (type=int, nullable=False, coerce=False)
Typical has both a high-level Object API and high-level Functional API. In general, any method registered to one API is also available to the other.
The Protocol API
import dataclasses
from typing import Iterable
import typic
@typic.constrained(ge=1)
class ID(int):
...
@typic.constrained(max_length=280)
class Tweet(str):
...
@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...
class Tweeter:
id: ID
tweets: Iterable[Tweet]
json = '{"id":1,"tweets":["I don\'t understand Twitter"]}'
protocol = typic.protocol(Tweeter)
t = protocol.transmute(json)
print(t)
#> Tweeter(id=1, tweets=["I don't understand Twitter"])
print(protocol.tojson(t))
#> '{"id":1,"tweets":["I don\'t understand Twitter"]}'
protocol.validate({"id": 0, "tweets": []})
#> Traceback (most recent call last):
#> ...
#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)
The Functional API
import dataclasses
from typing import Iterable
import typic
@typic.constrained(ge=1)
class ID(int):
...
@typic.constrained(max_length=280)
class Tweet(str):
...
@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...
class Tweeter:
id: ID
tweets: Iterable[Tweet]
json = '{"id":1,"tweets":["I don\'t understand Twitter"]}'
t = typic.transmute(Tweeter, json)
print(t)
#> Tweeter(id=1, tweets=["I don't understand Twitter"])
print(typic.tojson(t))
#> '{"id":1,"tweets":["I don\'t understand Twitter"]}'
typic.validate(Tweeter, {"id": 0, "tweets": []})
#> Traceback (most recent call last):
#> ...
#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)
The Object API
from typing import Iterable
import typic
@typic.constrained(ge=1)
class ID(int):
...
@typic.constrained(max_length=280)
class Tweet(str):
...
@typic.klass
class Tweeter:
id: ID
tweets: Iterable[Tweet]
json = '{"id":1,"tweets":["I don\'t understand Twitter"]}'
t = Tweeter.transmute(json)
print(t)
#> Tweeter(id=1, tweets=["I don't understand Twitter"])
print(t.tojson())
#> '{"id":1,"tweets":["I don\'t understand Twitter"]}'
Tweeter.validate({"id": 0, "tweets": []})
#> Traceback (most recent call last):
#> ...
#> typic.constraints.error.ConstraintValueError: Given value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)
Changelog
See our Releases.
Metadata
Release files for typical 2.9.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| typical-2.9.0.tar.gz | 90.0 kB | Without provenance | Details for typical-2.9.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| typical-2.9.0-py3-none-any.whl | Python 3 | none | any | Details for typical-2.9.0-py3-none-any.whl |
Total release size: 197.9 kB
Release files / typical-2.9.0.tar.gz
| Download URL | typical-2.9.0.tar.gz |
|---|---|
| Size | 90.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b8fcf86dce410c59cedd0c4a2a80d1b70e11bbe6fe343b81bfa5b303eedc5343
|
|
BLAKE2b-256 checksum How to use checksums |
f303f9460181600e15b303920ba5fe02ab6b55048214416f8812457073b61944
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.3 CPython/3.8.18 Darwin/23.6.0
|
Release files / typical-2.9.0-py3-none-any.whl
| Download URL | typical-2.9.0-py3-none-any.whl |
|---|---|
| Size | 107.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3cd23f6dc8b28f3ffaafeed1aa159e36fd64a999907dec492a359734524ae498
|
|
BLAKE2b-256 checksum How to use checksums |
45afbc9dbafd2bb7bf03449aed06208e0fb2ffc98abadff14d9f4f5df69ecfcc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.3 CPython/3.8.18 Darwin/23.6.0
|
Security for typical 2.9.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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
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.