![alt text](logo.png "Logo")
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**](https://runtype.readthedocs.io/en/latest/validation.html) - Provides a smarter alternative to `isinstance` and `issubclass`, with support for the `typing` module, and type constraints.
- :star: [**dataclass**](https://runtype.readthedocs.io/en/latest/dataclass.html) - 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](https://runtype.readthedocs.io/en/latest/dataclass.html#compared-to-pydantic))
- :star: [**dispatch**](https://runtype.readthedocs.io/en/latest/dispatch.html) - Provides fast multiple-dispatch for functions and methods, via a decorator.
- Dispatch on multiple arguments
- Full [specificity](https://runtype.readthedocs.io/en/latest/dispatch.html#specificity) resolution
- [Supports mypy](https://runtype.readthedocs.io/en/latest/dispatch.html#mypy-support), by utilizing the `@overload` decorator
- Inspired by Julia.
- :star: [**type utilities**](https://runtype.readthedocs.io/en/latest/types.html) - 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
```bash
pip install runtype
```
No dependencies.
Requires Python 3.8 or up.
[![codecov](https://codecov.io/gh/erezsh/runtype/branch/master/graph/badge.svg)](https://codecov.io/gh/erezsh/runtype)
## Examples
### Validation (Isa & Subclass)
Use `isa` and `issubclass` as a smarter alternative to the builtin isinstance & issubclass -
```python
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
```python
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 -
```python
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__`:
```python
@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](https://runtype.readthedocs.io/en/latest/benchmarks.html) in the documentation for detailed benchmarks.
![alt text](bench1.jpg "Validation Benchmark")
![alt text](bench2.jpg "Dispatch Benchmark")
## License
Runtype uses the [MIT license](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
Raw data
{
"_id": null,
"home_page": "https://github.com/erezsh/runtype",
"name": "runtype",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.8",
"maintainer_email": null,
"keywords": "types, typing, dispatch, multimethods, dataclass, runtime",
"author": "Erez Shinan",
"author_email": "erezshin@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/a3/2c/d4c555d8516b1817973123bd1aca65e307101f846dd4947fc2797d975345/runtype-0.5.2.tar.gz",
"platform": null,
"description": "![alt text](logo.png \"Logo\")\n\n\nRuntype is a collection of run-time type utilities for Python.\n\nIt is:\n\n:runner: Fast! Uses an internal typesystem for maximum performance.\n\n:brain: Smart! Supports `typing`, forward-references, constraints, auto-casting, and more.\n\n:gear: Configurative! Write your own type system, and use it with *dataclass* and *dispatch*.\n\n------\n\n### Modules\n\n- :star: [**validation**](https://runtype.readthedocs.io/en/latest/validation.html) - Provides a smarter alternative to `isinstance` and `issubclass`, with support for the `typing` module, and type constraints.\n\n- :star: [**dataclass**](https://runtype.readthedocs.io/en/latest/dataclass.html) - Adds run-time type validation to the built-in dataclass.\n\n - Improves dataclass ergonomics.\n - Supports most mypy constructs, like `typing` and forward-references (`foo: 'Bar'`).\n - Supports automatic value casting, Pydantic-style. (Optional, off by default)\n - Supports types with constraints. (e.g. `String(max_length=10)`)\n - Supports optional sampling for faster validation of big lists and dicts.\n - Twice faster than Pydantic-v1 with pure Python ([read here](https://runtype.readthedocs.io/en/latest/dataclass.html#compared-to-pydantic))\n\n- :star: [**dispatch**](https://runtype.readthedocs.io/en/latest/dispatch.html) - Provides fast multiple-dispatch for functions and methods, via a decorator.\n\n - Dispatch on multiple arguments\n - Full [specificity](https://runtype.readthedocs.io/en/latest/dispatch.html#specificity) resolution\n - [Supports mypy](https://runtype.readthedocs.io/en/latest/dispatch.html#mypy-support), by utilizing the `@overload` decorator\n - Inspired by Julia.\n\n- :star: [**type utilities**](https://runtype.readthedocs.io/en/latest/types.html) - Provides a set of classes to implement your own type-system.\n\n - Supports generics, constraints, phantom types\n - Used by runtype itself, to emulate the Python type-system.\n \n\n## Docs\n\nRead the docs here: https://runtype.readthedocs.io/\n\n## Install\n\n```bash\npip install runtype\n```\n\nNo dependencies.\n\nRequires Python 3.8 or up.\n\n[![codecov](https://codecov.io/gh/erezsh/runtype/branch/master/graph/badge.svg)](https://codecov.io/gh/erezsh/runtype)\n\n## Examples\n\n### Validation (Isa & Subclass)\n\nUse `isa` and `issubclass` as a smarter alternative to the builtin isinstance & issubclass -\n\n```python\nfrom runtype import isa, issubclass\n\nassert isa({'a': 1}, dict[str, int]) # == True\nassert not isa({'a': 'b'}, dict[str, int]) # == False\n\nassert issubclass(dict[str, int], typing.Mapping[str, int]) # == True\nassert not issubclass(dict[str, int], typing.Mapping[int, str]) # == False\n```\n\n### Dataclasses\n\n```python\nfrom runtype import dataclass\n\n@dataclass(check_types='cast') # Cast values to the target type, when applicable\nclass Person:\n name: str\n birthday: datetime = None # Implicit optional\n interests: list[str] = [] # The list is copied for each instance\n\n\nprint( Person(\"Beetlejuice\") )\n#> Person(name='Beetlejuice', birthday=None, interests=[])\nprint( Person(\"Albert\", \"1955-04-18T00:00\", ['physics']) )\n#> Person(name='Albert', birthday=datetime.datetime(1955, 4, 18, 0, 0), interests=['physics'])\nprint( Person(\"Bad\", interests=['a', 1]) )\n# TypeError: [Person] Attribute 'interests' expected value of type list[str]. Instead got ['a', 1]\n# Failed on item: 1, expected type str\n```\n\n### Multiple Dispatch\n\nRuntype dispatches according to the most specific type match -\n\n```python\nfrom runtype import multidispatch as md\n\n@md\ndef mul(a: list, b: list):\n return [mul(i, j) for i, j in zip(a, b, strict=True)]\n@md\ndef mul(a: list, b: Any):\n return [ai*b for ai in a]\n@md\ndef mul(a: Any, b: list):\n return [bi*b for bi in b]\n@md\ndef mul(a: Any, b: Any):\n return a * b\n\nassert mul(\"a\", 4) == \"aaaa\" # Any, Any\nassert mul([1, 2, 3], 2) == [2, 4, 6] # list, Any\nassert mul([1, 2], [3, 4]) == [3, 8] # list, list\n\n```\n\nDispatch can also be used for extending the dataclass builtin `__init__`:\n\n```python\n@dataclass\nclass Point:\n x: int = 0\n y: int = 0\n\n @md\n def __init__(self, points: list | tuple):\n # Call default constructor\n self.__init__(*points)\n\n @md\n def __init__(self, points: dict):\n # Call default constructor\n self.__init__(points['x'], points['y'])\n\n# Test constructors\np0 = Point() # Default constructor\nassert p0 == Point(0, 0) # Default constructor\nassert p0 == Point([0, 0]) # User constructor\nassert p0 == Point((0, 0)) # User constructor\nassert p0 == Point({\"x\": 0, \"y\": 0}) # User constructor\n```\n\n## Benchmarks\n\nRuntype beats its competition handily. It is significantly faster than both *beartype* and *plum*, and in some cases is even faster than regular Python code.\n\nSee the [benchmarks page](https://runtype.readthedocs.io/en/latest/benchmarks.html) in the documentation for detailed benchmarks.\n\n![alt text](bench1.jpg \"Validation Benchmark\")\n\n![alt text](bench2.jpg \"Dispatch Benchmark\")\n\n## License\n\nRuntype uses the [MIT license](LICENSE).\n\n## Contribute\n\nIf you like Runtype and want to see it grow, you can help by:\n\n- Reporting bugs or suggesting features\n\n- Submitting pull requests (better to ask me first)\n\n- Writing about runtype in a blogpost or even a tweet\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Type dispatch and validation for run-time Python",
"version": "0.5.2",
"project_urls": {
"Homepage": "https://github.com/erezsh/runtype",
"Repository": "https://github.com/erezsh/runtype"
},
"split_keywords": [
"types",
" typing",
" dispatch",
" multimethods",
" dataclass",
" runtime"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "4814a55fab2317a0de3ada38eb620e81ff0b91e1d6b0fe34b47fc8a858a0298b",
"md5": "d58e70a611ee112757f3a536fe26cbf5",
"sha256": "fb8b7098d62621dae682135f66ddf4e366a094e1c83e271730e1031c84b330fa"
},
"downloads": -1,
"filename": "runtype-0.5.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d58e70a611ee112757f3a536fe26cbf5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.8",
"size": 30341,
"upload_time": "2024-10-15T13:52:24",
"upload_time_iso_8601": "2024-10-15T13:52:24.263819Z",
"url": "https://files.pythonhosted.org/packages/48/14/a55fab2317a0de3ada38eb620e81ff0b91e1d6b0fe34b47fc8a858a0298b/runtype-0.5.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a32cd4c555d8516b1817973123bd1aca65e307101f846dd4947fc2797d975345",
"md5": "fb621841960ac7dc3caacf00105f9be6",
"sha256": "496797110f7a94001fefadc181708b26262a0be5b456eb780300b6436b79d0fd"
},
"downloads": -1,
"filename": "runtype-0.5.2.tar.gz",
"has_sig": false,
"md5_digest": "fb621841960ac7dc3caacf00105f9be6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.8",
"size": 28841,
"upload_time": "2024-10-15T13:52:26",
"upload_time_iso_8601": "2024-10-15T13:52:26.263532Z",
"url": "https://files.pythonhosted.org/packages/a3/2c/d4c555d8516b1817973123bd1aca65e307101f846dd4947fc2797d975345/runtype-0.5.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-15 13:52:26",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "erezsh",
"github_project": "runtype",
"travis_ci": true,
"coveralls": true,
"github_actions": true,
"tox": true,
"lcname": "runtype"
}