{"id":13468049,"url":"https://github.com/Parquery/icontract","last_synced_at":"2025-03-26T03:31:28.878Z","repository":{"id":32799689,"uuid":"142971238","full_name":"Parquery/icontract","owner":"Parquery","description":"Design-by-contract in Python3 with informative violation messages and inheritance","archived":false,"fork":false,"pushed_at":"2024-09-21T05:49:27.000Z","size":767,"stargazers_count":355,"open_issues_count":2,"forks_count":19,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-01T03:47:47.661Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Parquery.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGELOG.rst","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-31T06:22:46.000Z","updated_at":"2025-02-27T09:02:18.000Z","dependencies_parsed_at":"2023-10-17T05:01:11.733Z","dependency_job_id":"479bd2f7-5e76-4368-96a2-a4861ecf4c0c","html_url":"https://github.com/Parquery/icontract","commit_stats":{"total_commits":231,"total_committers":13,"mean_commits":17.76923076923077,"dds":"0.17748917748917747","last_synced_commit":"7d1cd7aaff73f0842ba671f48302c7ee4f5159f8"},"previous_names":[],"tags_count":62,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Parquery%2Ficontract","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Parquery%2Ficontract/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Parquery%2Ficontract/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Parquery%2Ficontract/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Parquery","download_url":"https://codeload.github.com/Parquery/icontract/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245584888,"owners_count":20639639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-31T15:01:04.736Z","updated_at":"2025-03-26T03:31:28.199Z","avatar_url":"https://github.com/Parquery.png","language":"Python","readme":"icontract\n=========\n.. image:: https://github.com/Parquery/icontract/workflows/CI/badge.svg\n    :target: https://github.com/Parquery/icontract/actions?query=workflow%3ACI\n    :alt: Continuous integration\n\n.. image:: https://coveralls.io/repos/github/Parquery/icontract/badge.svg?branch=master\n    :target: https://coveralls.io/github/Parquery/icontract\n\n.. image:: https://badge.fury.io/py/icontract.svg\n    :target: https://badge.fury.io/py/icontract\n    :alt: PyPI - version\n\n.. image:: https://img.shields.io/pypi/pyversions/icontract.svg\n    :alt: PyPI - Python Version\n\n.. image:: https://readthedocs.org/projects/icontract/badge/?version=latest\n    :target: https://icontract.readthedocs.io/en/latest/\n    :alt: Documentation\n\n.. image:: https://badges.gitter.im/gitterHQ/gitter.svg\n    :target: https://gitter.im/Parquery-icontract/community\n    :alt: Gitter chat\n\nicontract provides `design-by-contract \u003chttps://en.wikipedia.org/wiki/Design_by_contract\u003e`_ to Python3 with informative\nviolation messages and inheritance.\n\nIt also gives a base for a flourishing of a wider ecosystem:\n\n* A linter `pyicontract-lint`_,\n* A sphinx plug-in `sphinx-icontract`_,\n* A tool `icontract-hypothesis`_ for automated testing and ghostwriting test files which infers\n  `Hypothesis`_ strategies based on the contracts,\n\n  * together with IDE integrations such as\n    `icontract-hypothesis-vim`_,\n    `icontract-hypothesis-pycharm`_, and\n    `icontract-hypothesis-vscode`_,\n* Directly integrated into `CrossHair`_, a tool for automatic verification of Python programs,\n\n  * together with IDE integrations such as\n    `crosshair-pycharm`_ and `crosshair-vscode`_, and\n* An integration with `FastAPI`_ through `fastapi-icontract`_ to enforce contracts on your HTTP API and display them\n  in OpenAPI 3 schema and Swagger UI, and\n* An extensive corpus, `Python-by-contract corpus`_, of Python programs annotated with contracts for educational, testing and research purposes.\n\n.. _pyicontract-lint: https://pypi.org/project/pyicontract-lint\n.. _sphinx-icontract: https://pypi.org/project/sphinx-icontract\n.. _icontract-hypothesis: https://github.com/mristin/icontract-hypothesis\n.. _Hypothesis: https://hypothesis.readthedocs.io/en/latest/\n.. _icontract-hypothesis-vim: https://github.com/mristin/icontract-hypothesis-vim\n.. _icontract-hypothesis-pycharm: https://github.com/mristin/icontract-hypothesis-pycharm\n.. _icontract-hypothesis-vscode: https://github.com/mristin/icontract-hypothesis-vscode\n.. _CrossHair: https://github.com/pschanely/CrossHair\n.. _crosshair-pycharm: https://github.com/mristin/crosshair-pycharm/\n.. _crosshair-vscode: https://github.com/mristin/crosshair-vscode/\n.. _FastAPI: https://github.com/tiangolo/fastapi/issues/1996\n.. _fastapi-icontract: https://pypi.org/project/fastapi-icontract/\n.. _Python-by-contract corpus: https://github.com/mristin/python-by-contract-corpus\n\nRelated Projects\n----------------\nThere exist a couple of contract libraries. However, at the time of this writing (September 2018), they all required the\nprogrammer either to learn a new syntax (`PyContracts \u003chttps://pypi.org/project/PyContracts/\u003e`_) or to write\nredundant condition descriptions (\n*e.g.*,\n`contracts \u003chttps://pypi.org/project/contracts/\u003e`_,\n`covenant \u003chttps://github.com/kisielk/covenant\u003e`_,\n`deal \u003chttps://github.com/life4/deal\u003e`_,\n`dpcontracts \u003chttps://pypi.org/project/dpcontracts/\u003e`_,\n`pyadbc \u003chttps://pypi.org/project/pyadbc/\u003e`_ and\n`pcd \u003chttps://pypi.org/project/pcd\u003e`_).\n\nThis library was strongly inspired by them, but we go two steps further.\n\nFirst, our violation message on contract breach are much more informative. The message includes the source code of the\ncontract condition as well as variable values at the time of the breach. This promotes don't-repeat-yourself principle\n(`DRY \u003chttps://en.wikipedia.org/wiki/Don%27t_repeat_yourself\u003e`_) and spare the programmer the tedious task of repeating\nthe message that was already written in code.\n\nSecond, icontract allows inheritance of the contracts and supports weakining of the preconditions\nas well as strengthening of the postconditions and invariants. Notably, weakining and strengthening of the contracts\nis a feature indispensable for modeling many non-trivial class hierarchies. Please see Section\n`Inheritance \u003chttps://icontract.readthedocs.io/en/latest/usage.html#inheritance\u003e`_.\nTo the best of our knowledge, there is currently no other Python library that supports inheritance of the contracts in a\ncorrect way.\n\nIn the long run, we hope that design-by-contract will be adopted and integrated in the language. Consider this library\na work-around till that happens. You might be also interested in the archived discussion on how to bring\ndesign-by-contract into Python language on\n`python-ideas mailing list \u003chttps://groups.google.com/forum/#!topic/python-ideas/JtMgpSyODTU\u003e`_.\n\nTeasers\n=======\nWe give a couple of teasers here to motivate the library.\nPlease see the documentation available on `icontract.readthedocs.io\n\u003chttps://icontract.readthedocs.io/en/latest/\u003e`_ for a full scope of its\ncapabilities.\n\nThe script is also available as a `repl.it post`_.\n\n.. _repl.it post: https://repl.it/talk/share/icontract-example-script/121190\n\n.. code-block:: python\n\n    \u003e\u003e\u003e import icontract\n\n    \u003e\u003e\u003e @icontract.require(lambda x: x \u003e 3)\n    ... def some_func(x: int, y: int = 5) -\u003e None:\n    ...     pass\n    ...\n\n    \u003e\u003e\u003e some_func(x=5)\n\n    # Pre-condition violation\n    \u003e\u003e\u003e some_func(x=1)\n    Traceback (most recent call last):\n      ...\n    icontract.errors.ViolationError: File \u003cdoctest README.rst[1]\u003e, line 1 in \u003cmodule\u003e:\n    x \u003e 3:\n    x was 1\n    y was 5\n\n    # Pre-condition violation with a description\n    \u003e\u003e\u003e @icontract.require(lambda x: x \u003e 3, \"x must not be small\")\n    ... def some_func(x: int, y: int = 5) -\u003e None:\n    ...     pass\n    ...\n    \u003e\u003e\u003e some_func(x=1)\n    Traceback (most recent call last):\n      ...\n    icontract.errors.ViolationError: File \u003cdoctest README.rst[4]\u003e, line 1 in \u003cmodule\u003e:\n    x must not be small: x \u003e 3:\n    x was 1\n    y was 5\n\n    # Pre-condition violation with more complex values\n    \u003e\u003e\u003e class B:\n    ...     def __init__(self) -\u003e None:\n    ...         self.x = 7\n    ...\n    ...     def y(self) -\u003e int:\n    ...         return 2\n    ...\n    ...     def __repr__(self) -\u003e str:\n    ...         return \"instance of B\"\n    ...\n    \u003e\u003e\u003e class A:\n    ...     def __init__(self) -\u003e None:\n    ...         self.b = B()\n    ...\n    ...     def __repr__(self) -\u003e str:\n    ...         return \"instance of A\"\n    ...\n    \u003e\u003e\u003e SOME_GLOBAL_VAR = 13\n    \u003e\u003e\u003e @icontract.require(lambda a: a.b.x + a.b.y() \u003e SOME_GLOBAL_VAR)\n    ... def some_func(a: A) -\u003e None:\n    ...     pass\n    ...\n    \u003e\u003e\u003e an_a = A()\n    \u003e\u003e\u003e some_func(an_a)\n    Traceback (most recent call last):\n      ...\n    icontract.errors.ViolationError: File \u003cdoctest README.rst[9]\u003e, line 1 in \u003cmodule\u003e:\n    a.b.x + a.b.y() \u003e SOME_GLOBAL_VAR:\n    SOME_GLOBAL_VAR was 13\n    a was instance of A\n    a.b was instance of B\n    a.b.x was 7\n    a.b.y() was 2\n\n    # Post-condition\n    \u003e\u003e\u003e @icontract.ensure(lambda result, x: result \u003e x)\n    ... def some_func(x: int, y: int = 5) -\u003e int:\n    ...     return x - y\n    ...\n    \u003e\u003e\u003e some_func(x=10)\n    Traceback (most recent call last):\n      ...\n    icontract.errors.ViolationError: File \u003cdoctest README.rst[12]\u003e, line 1 in \u003cmodule\u003e:\n    result \u003e x:\n    result was 5\n    x was 10\n    y was 5\n\n\n    # Pre-conditions fail before post-conditions.\n    \u003e\u003e\u003e @icontract.ensure(lambda result, x: result \u003e x)\n    ... @icontract.require(lambda x: x \u003e 3, \"x must not be small\")\n    ... def some_func(x: int, y: int = 5) -\u003e int:\n    ...    return x - y\n    ...\n    \u003e\u003e\u003e some_func(x=3)\n    Traceback (most recent call last):\n      ...\n    icontract.errors.ViolationError: File \u003cdoctest README.rst[14]\u003e, line 2 in \u003cmodule\u003e:\n    x must not be small: x \u003e 3:\n    x was 3\n    y was 5\n\n    # Invariant\n    \u003e\u003e\u003e @icontract.invariant(lambda self: self.x \u003e 0)\n    ... class SomeClass:\n    ...     def __init__(self) -\u003e None:\n    ...         self.x = -1\n    ...\n    ...     def __repr__(self) -\u003e str:\n    ...         return \"an instance of SomeClass\"\n    ...\n    \u003e\u003e\u003e some_instance = SomeClass()\n    Traceback (most recent call last):\n     ...\n    icontract.errors.ViolationError: File \u003cdoctest README.rst[16]\u003e, line 1 in \u003cmodule\u003e:\n    self.x \u003e 0:\n    self was an instance of SomeClass\n    self.x was -1\n\n\nInstallation\n============\n\n* Install icontract with pip:\n\n.. code-block:: bash\n\n    pip3 install icontract\n\nVersioning\n==========\nWe follow `Semantic Versioning \u003chttp://semver.org/spec/v1.0.0.html\u003e`_. The version X.Y.Z indicates:\n\n* X is the major version (backward-incompatible),\n* Y is the minor version (backward-compatible), and\n* Z is the patch version (backward-compatible bug fix).\n","funding_links":[],"categories":["Python","Design by Contract","Programming Languages"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FParquery%2Ficontract","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FParquery%2Ficontract","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FParquery%2Ficontract/lists"}