typical


Nametypical JSON
Version 2.9.0 PyPI version JSON
download
home_pagehttps://github.com/seandstewart/typical
SummaryTypical: Python's Typing Toolkit.
upload_time2024-09-09 15:56:00
maintainerNone
docs_urlNone
authorSean Stewart
requires_python<4.0,>=3.8.1
licenseMIT
keywords typing data annotations validation json-schema
VCS
bugtrack_url
requirements atomicwrites attrs black bracex click colorama coverage django djangorestframework dnspython email-validator fastjsonschema flake8 future-typing ghp-import greenlet idna importlib-metadata inflection iniconfig jinja2 markdown markupsafe marshmallow mccabe mergedeep mkdocs-awesome-pages-plugin mkdocs-material-extensions mkdocs-material mkdocs mypy-extensions mypy numpy orjson packaging pandas pathspec pendulum platformdirs pluggy py-cpuinfo py pycodestyle pydantic pyflakes pygal pygaljs pygments pymdown-extensions pyparsing pytest-benchmark pytest-cov pytest python-dateutil pytz pytzdata pyyaml-env-tag pyyaml six sqlalchemy sqlparse toastedmarshmallow toml tomli typed-ast typing-extensions ujson watchdog wcmatch zipp
Travis-CI No Travis.
coveralls test coverage
            # typical: Python's Typing Toolkit
[![image](https://img.shields.io/pypi/v/typical.svg)](https://pypi.org/project/typical/)
[![image](https://img.shields.io/pypi/l/typical.svg)](https://pypi.org/project/typical/)
[![image](https://img.shields.io/pypi/pyversions/typical.svg)](https://pypi.org/project/typical/)
[![image](https://img.shields.io/github/languages/code-size/seandstewart/typical.svg?style=flat)](https://github.com/seandstewart/typical)
[![Test & Lint](https://github.com/seandstewart/typical/workflows/Test%20&%20Lint/badge.svg)](https://github.com/seandstewart/typical/actions)
[![Coverage](https://codecov.io/gh/seandstewart/typical/branch/master/graph/badge.svg)](https://codecov.io/gh/seandstewart/typical)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)
[![Netlify Status](https://api.netlify.com/api/v1/badges/982a0ced-bb7f-4391-87e8-1957071d2f66/deploy-status)](https://app.netlify.com/sites/typical-python/deploys)

![How Typical](static/typical.png)

## Introduction

Typical is a library devoted to runtime analysis, inference,
validation, and enforcement of Python types,
[PEP 484](https://www.python.org/dev/peps/pep-0484/) Type Hints, and
custom user-defined data-types.

Typical is fully compliant with the following Python Typing PEPs:

- [PEP 484 -- Type Hints](https://www.python.org/dev/peps/pep-0484/)
- [PEP 563 -- Postponed Evaluation of Annotations](https://www.python.org/dev/peps/pep-0563/)
- [PEP 585 -- Type Hinting Generics In Standard Collections](https://www.python.org/dev/peps/pep-0585/)
- [PEP 586 -- Literal Types](https://www.python.org/dev/peps/pep-0586/)
- [PEP 589 -- TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys](https://www.python.org/dev/peps/pep-0589/)
- [PEP 604 -- Allow writing union types as X | Y](https://www.python.org/dev/peps/pep-0604/)

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](https://python-typical.org/).

> Starting with version 2.0, All documentation is hand-crafted
> markdown & versioned documentation can be found at typical's
> [Git Repo](https://github.com/seandstewart/typical/tree/master/docs).
> (Versioned documentation is still in-the-works directly on our
> domain.)

## A Typical Use-Case

The decorator that started it all:

### `typic.al(...)`

```python
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

```python
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

```python
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

```python
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](https://github.com/seandstewart/typical/releases).

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/seandstewart/typical",
    "name": "typical",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8.1",
    "maintainer_email": null,
    "keywords": "typing, data, annotations, validation, json-schema",
    "author": "Sean Stewart",
    "author_email": "sean_stewart@me.com",
    "download_url": "https://files.pythonhosted.org/packages/f3/03/f9460181600e15b303920ba5fe02ab6b55048214416f8812457073b61944/typical-2.9.0.tar.gz",
    "platform": null,
    "description": "# typical: Python's Typing Toolkit\n[![image](https://img.shields.io/pypi/v/typical.svg)](https://pypi.org/project/typical/)\n[![image](https://img.shields.io/pypi/l/typical.svg)](https://pypi.org/project/typical/)\n[![image](https://img.shields.io/pypi/pyversions/typical.svg)](https://pypi.org/project/typical/)\n[![image](https://img.shields.io/github/languages/code-size/seandstewart/typical.svg?style=flat)](https://github.com/seandstewart/typical)\n[![Test & Lint](https://github.com/seandstewart/typical/workflows/Test%20&%20Lint/badge.svg)](https://github.com/seandstewart/typical/actions)\n[![Coverage](https://codecov.io/gh/seandstewart/typical/branch/master/graph/badge.svg)](https://codecov.io/gh/seandstewart/typical)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black)\n[![Netlify Status](https://api.netlify.com/api/v1/badges/982a0ced-bb7f-4391-87e8-1957071d2f66/deploy-status)](https://app.netlify.com/sites/typical-python/deploys)\n\n![How Typical](static/typical.png)\n\n## Introduction\n\nTypical is a library devoted to runtime analysis, inference,\nvalidation, and enforcement of Python types,\n[PEP 484](https://www.python.org/dev/peps/pep-0484/) Type Hints, and\ncustom user-defined data-types.\n\nTypical is fully compliant with the following Python Typing PEPs:\n\n- [PEP 484 -- Type Hints](https://www.python.org/dev/peps/pep-0484/)\n- [PEP 563 -- Postponed Evaluation of Annotations](https://www.python.org/dev/peps/pep-0563/)\n- [PEP 585 -- Type Hinting Generics In Standard Collections](https://www.python.org/dev/peps/pep-0585/)\n- [PEP 586 -- Literal Types](https://www.python.org/dev/peps/pep-0586/)\n- [PEP 589 -- TypedDict: Type Hints for Dictionaries with a Fixed Set of Keys](https://www.python.org/dev/peps/pep-0589/)\n- [PEP 604 -- Allow writing union types as X | Y](https://www.python.org/dev/peps/pep-0604/)\n\nIt provides a high-level Protocol API, Functional API, and Object API to suit most any\noccasion.\n\n## Getting Started\n\nInstallation is as simple as `pip install -U typical`.\n## Help\n\nThe latest documentation is hosted at\n[python-typical.org](https://python-typical.org/).\n\n> Starting with version 2.0, All documentation is hand-crafted\n> markdown & versioned documentation can be found at typical's\n> [Git Repo](https://github.com/seandstewart/typical/tree/master/docs).\n> (Versioned documentation is still in-the-works directly on our\n> domain.)\n\n## A Typical Use-Case\n\nThe decorator that started it all:\n\n### `typic.al(...)`\n\n```python\nimport typic\n\n\n@typic.al\ndef hard_math(a: int, b: int, *c: int) -> int:\n    return a + b + sum(c)\n\nhard_math(1, \"3\")\n#> 4\n\n\n@typic.al(strict=True)\ndef strict_math(a: int, b: int, *c: int) -> int:\n    return a + b + sum(c)\n\nstrict_math(1, 2, 3, \"4\")\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Given value <'4'> fails constraints: (type=int, nullable=False, coerce=False)\n  \n```\n\nTypical has both a high-level *Object API* and high-level\n*Functional API*. In general, any method registered to one API is also\navailable to the other.\n\n### The Protocol API\n\n```python\nimport dataclasses\nfrom typing import Iterable\n\nimport typic\n\n\n@typic.constrained(ge=1)\nclass ID(int):\n    ...\n\n\n@typic.constrained(max_length=280)\nclass Tweet(str):\n    ...\n\n\n@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...\nclass Tweeter:\n    id: ID\n    tweets: Iterable[Tweet]\n\n\njson = '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\nprotocol = typic.protocol(Tweeter)\n\nt = protocol.transmute(json)\nprint(t)\n#> Tweeter(id=1, tweets=[\"I don't understand Twitter\"])\n\nprint(protocol.tojson(t))\n#> '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\nprotocol.validate({\"id\": 0, \"tweets\": []})\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)\n```\n\n### The Functional API\n\n```python\nimport dataclasses\nfrom typing import Iterable\n\nimport typic\n\n\n@typic.constrained(ge=1)\nclass ID(int):\n    ...\n\n\n@typic.constrained(max_length=280)\nclass Tweet(str):\n    ...\n\n\n@dataclasses.dataclass # or typing.TypedDict or typing.NamedTuple or annotated class...\nclass Tweeter:\n    id: ID\n    tweets: Iterable[Tweet]\n\n\njson = '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\nt = typic.transmute(Tweeter, json)\nprint(t)\n#> Tweeter(id=1, tweets=[\"I don't understand Twitter\"])\n\nprint(typic.tojson(t))\n#> '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\ntypic.validate(Tweeter, {\"id\": 0, \"tweets\": []})\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Tweeter.id: value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)\n```\n\n### The Object API\n\n```python\nfrom typing import Iterable\n\nimport typic\n\n\n@typic.constrained(ge=1)\nclass ID(int):\n    ...\n\n\n@typic.constrained(max_length=280)\nclass Tweet(str):\n    ...\n\n\n@typic.klass\nclass Tweeter:\n    id: ID\n    tweets: Iterable[Tweet]\n    \n\njson = '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\nt = Tweeter.transmute(json)\n\nprint(t)\n#> Tweeter(id=1, tweets=[\"I don't understand Twitter\"])\n\nprint(t.tojson())\n#> '{\"id\":1,\"tweets\":[\"I don\\'t understand Twitter\"]}'\n\nTweeter.validate({\"id\": 0, \"tweets\": []})\n#> Traceback (most recent call last):\n#>  ...\n#> typic.constraints.error.ConstraintValueError: Given value <0> fails constraints: (type=int, nullable=False, coerce=False, ge=1)\n```\n\n\n## Changelog\n\nSee our\n[Releases](https://github.com/seandstewart/typical/releases).\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Typical: Python's Typing Toolkit.",
    "version": "2.9.0",
    "project_urls": {
        "Homepage": "https://github.com/seandstewart/typical",
        "Repository": "https://github.com/seandstewart/typical"
    },
    "split_keywords": [
        "typing",
        " data",
        " annotations",
        " validation",
        " json-schema"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "45afbc9dbafd2bb7bf03449aed06208e0fb2ffc98abadff14d9f4f5df69ecfcc",
                "md5": "38949dfd05210df7a953ec50a3ad2754",
                "sha256": "3cd23f6dc8b28f3ffaafeed1aa159e36fd64a999907dec492a359734524ae498"
            },
            "downloads": -1,
            "filename": "typical-2.9.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "38949dfd05210df7a953ec50a3ad2754",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8.1",
            "size": 107939,
            "upload_time": "2024-09-09T15:55:59",
            "upload_time_iso_8601": "2024-09-09T15:55:59.337075Z",
            "url": "https://files.pythonhosted.org/packages/45/af/bc9dbafd2bb7bf03449aed06208e0fb2ffc98abadff14d9f4f5df69ecfcc/typical-2.9.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f303f9460181600e15b303920ba5fe02ab6b55048214416f8812457073b61944",
                "md5": "b9662e5a51fb412c15e89cb950a5eecf",
                "sha256": "b8fcf86dce410c59cedd0c4a2a80d1b70e11bbe6fe343b81bfa5b303eedc5343"
            },
            "downloads": -1,
            "filename": "typical-2.9.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b9662e5a51fb412c15e89cb950a5eecf",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8.1",
            "size": 90001,
            "upload_time": "2024-09-09T15:56:00",
            "upload_time_iso_8601": "2024-09-09T15:56:00.547287Z",
            "url": "https://files.pythonhosted.org/packages/f3/03/f9460181600e15b303920ba5fe02ab6b55048214416f8812457073b61944/typical-2.9.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-09 15:56:00",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "seandstewart",
    "github_project": "typical",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [
        {
            "name": "atomicwrites",
            "specs": [
                [
                    "==",
                    "1.4.0"
                ]
            ]
        },
        {
            "name": "attrs",
            "specs": [
                [
                    "==",
                    "21.2.0"
                ]
            ]
        },
        {
            "name": "black",
            "specs": [
                [
                    "==",
                    "21.12b0"
                ]
            ]
        },
        {
            "name": "bracex",
            "specs": [
                [
                    "==",
                    "2.2.1"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    "==",
                    "8.0.3"
                ]
            ]
        },
        {
            "name": "colorama",
            "specs": [
                [
                    "==",
                    "0.4.4"
                ]
            ]
        },
        {
            "name": "coverage",
            "specs": [
                [
                    "==",
                    "6.2"
                ]
            ]
        },
        {
            "name": "django",
            "specs": [
                [
                    "==",
                    "2.2.25"
                ]
            ]
        },
        {
            "name": "djangorestframework",
            "specs": [
                [
                    "==",
                    "3.13.0"
                ]
            ]
        },
        {
            "name": "dnspython",
            "specs": [
                [
                    "==",
                    "2.1.0"
                ]
            ]
        },
        {
            "name": "email-validator",
            "specs": [
                [
                    "==",
                    "1.1.3"
                ]
            ]
        },
        {
            "name": "fastjsonschema",
            "specs": [
                [
                    "==",
                    "2.15.2"
                ]
            ]
        },
        {
            "name": "flake8",
            "specs": [
                [
                    "==",
                    "3.9.2"
                ]
            ]
        },
        {
            "name": "future-typing",
            "specs": [
                [
                    "==",
                    "0.4.1"
                ]
            ]
        },
        {
            "name": "ghp-import",
            "specs": [
                [
                    "==",
                    "2.0.2"
                ]
            ]
        },
        {
            "name": "greenlet",
            "specs": [
                [
                    "==",
                    "1.1.2"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.3"
                ]
            ]
        },
        {
            "name": "importlib-metadata",
            "specs": [
                [
                    "==",
                    "4.8.2"
                ]
            ]
        },
        {
            "name": "inflection",
            "specs": [
                [
                    "==",
                    "0.5.1"
                ]
            ]
        },
        {
            "name": "iniconfig",
            "specs": [
                [
                    "==",
                    "1.1.1"
                ]
            ]
        },
        {
            "name": "jinja2",
            "specs": [
                [
                    "==",
                    "3.0.3"
                ]
            ]
        },
        {
            "name": "markdown",
            "specs": [
                [
                    "==",
                    "3.3.6"
                ]
            ]
        },
        {
            "name": "markupsafe",
            "specs": [
                [
                    "==",
                    "2.0.1"
                ]
            ]
        },
        {
            "name": "marshmallow",
            "specs": [
                [
                    "==",
                    "3.14.1"
                ]
            ]
        },
        {
            "name": "mccabe",
            "specs": [
                [
                    "==",
                    "0.6.1"
                ]
            ]
        },
        {
            "name": "mergedeep",
            "specs": [
                [
                    "==",
                    "1.3.4"
                ]
            ]
        },
        {
            "name": "mkdocs-awesome-pages-plugin",
            "specs": [
                [
                    "==",
                    "2.6.1"
                ]
            ]
        },
        {
            "name": "mkdocs-material-extensions",
            "specs": [
                [
                    "==",
                    "1.0.3"
                ]
            ]
        },
        {
            "name": "mkdocs-material",
            "specs": [
                [
                    "==",
                    "8.1.3"
                ]
            ]
        },
        {
            "name": "mkdocs",
            "specs": [
                [
                    "==",
                    "1.2.3"
                ]
            ]
        },
        {
            "name": "mypy-extensions",
            "specs": [
                [
                    "==",
                    "0.4.3"
                ]
            ]
        },
        {
            "name": "mypy",
            "specs": [
                [
                    "==",
                    "0.910"
                ]
            ]
        },
        {
            "name": "numpy",
            "specs": [
                [
                    "==",
                    "1.21.4"
                ]
            ]
        },
        {
            "name": "orjson",
            "specs": [
                [
                    "==",
                    "3.6.5"
                ]
            ]
        },
        {
            "name": "packaging",
            "specs": [
                [
                    "==",
                    "21.3"
                ]
            ]
        },
        {
            "name": "pandas",
            "specs": [
                [
                    "==",
                    "1.3.5"
                ]
            ]
        },
        {
            "name": "pathspec",
            "specs": [
                [
                    "==",
                    "0.9.0"
                ]
            ]
        },
        {
            "name": "pendulum",
            "specs": [
                [
                    "==",
                    "2.1.2"
                ]
            ]
        },
        {
            "name": "platformdirs",
            "specs": [
                [
                    "==",
                    "2.4.0"
                ]
            ]
        },
        {
            "name": "pluggy",
            "specs": [
                [
                    "==",
                    "1.0.0"
                ]
            ]
        },
        {
            "name": "py-cpuinfo",
            "specs": [
                [
                    "==",
                    "8.0.0"
                ]
            ]
        },
        {
            "name": "py",
            "specs": [
                [
                    "==",
                    "1.11.0"
                ]
            ]
        },
        {
            "name": "pycodestyle",
            "specs": [
                [
                    "==",
                    "2.7.0"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    "==",
                    "1.8.2"
                ]
            ]
        },
        {
            "name": "pyflakes",
            "specs": [
                [
                    "==",
                    "2.3.1"
                ]
            ]
        },
        {
            "name": "pygal",
            "specs": [
                [
                    "==",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "pygaljs",
            "specs": [
                [
                    "==",
                    "1.0.2"
                ]
            ]
        },
        {
            "name": "pygments",
            "specs": [
                [
                    "==",
                    "2.10.0"
                ]
            ]
        },
        {
            "name": "pymdown-extensions",
            "specs": [
                [
                    "==",
                    "9.1"
                ]
            ]
        },
        {
            "name": "pyparsing",
            "specs": [
                [
                    "==",
                    "3.0.6"
                ]
            ]
        },
        {
            "name": "pytest-benchmark",
            "specs": [
                [
                    "==",
                    "3.4.1"
                ]
            ]
        },
        {
            "name": "pytest-cov",
            "specs": [
                [
                    "==",
                    "2.12.1"
                ]
            ]
        },
        {
            "name": "pytest",
            "specs": [
                [
                    "==",
                    "6.2.5"
                ]
            ]
        },
        {
            "name": "python-dateutil",
            "specs": [
                [
                    "==",
                    "2.8.2"
                ]
            ]
        },
        {
            "name": "pytz",
            "specs": [
                [
                    "==",
                    "2021.3"
                ]
            ]
        },
        {
            "name": "pytzdata",
            "specs": [
                [
                    "==",
                    "2020.1"
                ]
            ]
        },
        {
            "name": "pyyaml-env-tag",
            "specs": [
                [
                    "==",
                    "0.1"
                ]
            ]
        },
        {
            "name": "pyyaml",
            "specs": [
                [
                    "==",
                    "6.0"
                ]
            ]
        },
        {
            "name": "six",
            "specs": [
                [
                    "==",
                    "1.16.0"
                ]
            ]
        },
        {
            "name": "sqlalchemy",
            "specs": [
                [
                    "==",
                    "1.4.28"
                ]
            ]
        },
        {
            "name": "sqlparse",
            "specs": [
                [
                    "==",
                    "0.4.2"
                ]
            ]
        },
        {
            "name": "toastedmarshmallow",
            "specs": [
                [
                    "==",
                    "2.15.2.post1"
                ]
            ]
        },
        {
            "name": "toml",
            "specs": [
                [
                    "==",
                    "0.10.2"
                ]
            ]
        },
        {
            "name": "tomli",
            "specs": [
                [
                    "==",
                    "1.2.3"
                ]
            ]
        },
        {
            "name": "typed-ast",
            "specs": [
                [
                    "==",
                    "1.4.3"
                ]
            ]
        },
        {
            "name": "typing-extensions",
            "specs": [
                [
                    "==",
                    "3.10.0.2"
                ]
            ]
        },
        {
            "name": "ujson",
            "specs": [
                [
                    "==",
                    "3.2.0"
                ]
            ]
        },
        {
            "name": "watchdog",
            "specs": [
                [
                    "==",
                    "2.1.6"
                ]
            ]
        },
        {
            "name": "wcmatch",
            "specs": [
                [
                    "==",
                    "8.3"
                ]
            ]
        },
        {
            "name": "zipp",
            "specs": [
                [
                    "==",
                    "3.6.0"
                ]
            ]
        }
    ],
    "lcname": "typical"
}
        
Elapsed time: 0.53669s