runtype


Nameruntype JSON
Version 0.4.2 PyPI version JSON
download
home_pagehttps://github.com/erezsh/runtype
SummaryType dispatch and validation for run-time Python
upload_time2024-01-02 04:49:44
maintainer
docs_urlNone
authorErez Shinan
requires_python>=3.6,<4.0
licenseMIT
keywords types typing dispatch multimethods dataclass runtime
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI
coveralls test coverage
            ![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.6 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(frozen=False)
class Point:
    x: int = 0
    y: int = 0
    
    @md
    def __init__(self, points: list | tuple):
        self.x, self.y = points

    @md
    def __init__(self, points: dict):
        self.x = points['x']
        self.y = 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
```


## License

Runtype uses the [MIT license](LICENSE).

## Donate

If you like Runtype and want to show your appreciation, you can do so at my [patreon page](https://www.patreon.com/erezsh), or [ko-fi page](https://ko-fi.com/erezsh).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/erezsh/runtype",
    "name": "runtype",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6,<4.0",
    "maintainer_email": "",
    "keywords": "types,typing,dispatch,multimethods,dataclass,runtime",
    "author": "Erez Shinan",
    "author_email": "erezshin@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/7a/5c/c812596d2e2fce41c0c53d4b44049adc77d00551b72084d080be9dd5103f/runtype-0.4.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.6 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(frozen=False)\nclass Point:\n    x: int = 0\n    y: int = 0\n    \n    @md\n    def __init__(self, points: list | tuple):\n        self.x, self.y = points\n\n    @md\n    def __init__(self, points: dict):\n        self.x = points['x']\n        self.y = 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\n## License\n\nRuntype uses the [MIT license](LICENSE).\n\n## Donate\n\nIf you like Runtype and want to show your appreciation, you can do so at my [patreon page](https://www.patreon.com/erezsh), or [ko-fi page](https://ko-fi.com/erezsh).\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Type dispatch and validation for run-time Python",
    "version": "0.4.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": "58bfa394239b64c739cff5f341afc5cd9ca65db83e177546086b9a20809e6803",
                "md5": "8e38721b99453ba4f8af3e727a31a3a6",
                "sha256": "0e25d408ab6229e7e046b562c3a5f17296b5c777bad7fc037cdc10be88e393a9"
            },
            "downloads": -1,
            "filename": "runtype-0.4.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "8e38721b99453ba4f8af3e727a31a3a6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6,<4.0",
            "size": 24211,
            "upload_time": "2024-01-02T04:49:42",
            "upload_time_iso_8601": "2024-01-02T04:49:42.164860Z",
            "url": "https://files.pythonhosted.org/packages/58/bf/a394239b64c739cff5f341afc5cd9ca65db83e177546086b9a20809e6803/runtype-0.4.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7a5cc812596d2e2fce41c0c53d4b44049adc77d00551b72084d080be9dd5103f",
                "md5": "89485e30bdbccb71212820d44bc36941",
                "sha256": "75c7e18572ff5c38da5b52a47581f2a44e9e5892a91562e004d09586c764318f"
            },
            "downloads": -1,
            "filename": "runtype-0.4.2.tar.gz",
            "has_sig": false,
            "md5_digest": "89485e30bdbccb71212820d44bc36941",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6,<4.0",
            "size": 23769,
            "upload_time": "2024-01-02T04:49:44",
            "upload_time_iso_8601": "2024-01-02T04:49:44.309750Z",
            "url": "https://files.pythonhosted.org/packages/7a/5c/c812596d2e2fce41c0c53d4b44049adc77d00551b72084d080be9dd5103f/runtype-0.4.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-01-02 04:49:44",
    "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"
}
        
Elapsed time: 0.19683s