ensures


Nameensures JSON
Version 0.3.0 PyPI version JSON
download
home_pageNone
SummaryDesign by Contract with Functional Programming
upload_time2025-09-10 00:13:51
maintainerNone
docs_urlNone
authorBruno Dantas
requires_python>=3.10
licenseNone
keywords design-by-contract precondition postcondition invariant testing validation
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # ensures

[![CI](https://github.com/brunodantas/ensures/actions/workflows/ci.yml/badge.svg)](https://github.com/brunodantas/ensures/actions/workflows/ci.yml)
[![PyPI version](https://badge.fury.io/py/ensures.svg)](https://badge.fury.io/py/ensures)
[![PyPI - Downloads](https://img.shields.io/pypi/dm/ensures)](https://pypi.org/project/ensures/)
[![codecov](https://codecov.io/gh/brunodantas/ensures/graph/badge.svg)](https://codecov.io/gh/brunodantas/ensures)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
[![PyPI - Status](https://img.shields.io/pypi/status/ensures)](https://pypi.org/project/ensures/)
[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)
[![Type checked: mypy](https://img.shields.io/badge/type%20checked-mypy-blue.svg)](https://mypy-lang.org/)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)

`ensures` is a simple Python package that implements the idea of [Design by Contract](https://en.wikipedia.org/wiki/Design_by_contract) described in the *Pragmatic Paranoia* chapter of [The Pragmatic Programmer](https://en.wikipedia.org/wiki/The_Pragmatic_Programmer). That's the chapter where they say you should *trust nobody, not even yourself*.

![](trust.jpg)

## Main Features

- Verification of lists of pre/post condition and invariant functions.
- Usage of arbitrary functions for such verification.
- [Result-type](https://en.wikipedia.org/wiki/Result_type) return values.


## Installation

```bash
pip install ensures
```

## Usage

### `precondition` / `require`

Runs a list of functions on all args.

Returns `Error` if any of them fails.

```python
from ensures import precondition


def is_positive(x):
    """Check if a number is positive."""
    return x > 0


@precondition(is_positive)
def square_root(x):
    """Calculate square root with precondition that x must be positive."""
    return x**0.5
```

### `postcondition` / `ensure`

Runs a list of functions on the result.

Returns `Error` if any of them fails.

```python
from ensures import ensure


def result_is_even(result):
    """Check if result is even."""
    return result % 2 == 0


@ensure(result_is_even)  # Using the alias
def double_number(x):
    """Double a number with postcondition that result is even."""
    return x * 2
```


### `invariant`

Runs a list of functions on all args.

Returns `Error` if any of them fails.

```python
from ensures import invariant


@invariant(lambda x: x >= 0)  # Simple lambda invariant
def increment_counter(x):
    """Increment a counter with invariant that it stays non-negative."""
    return x + 1
```

### Result Handling

Pattern matching is supported to unpack the `Return` value.

```python
from ensures import Error, Success


result1 = square_root(1)
result2 = square_root(-1)  # This will return an Error instance

def handle_result(res):
    match res:
        case Success(value):
            print(f"Square root calculated: {value}")
        case Error(func, args):
            print(f"Precondition failed in {func.__name__} with args {args}")

handle_result(result1)
handle_result(result2)
```


## More examples

Check [examples.py](/src/ensures/examples.py)

## 📊 Performance

Contract validation adds minimal overhead:
- **Precondition**: ~7x baseline function call
- **Postcondition**: ~8x baseline function call
- **Memory**: Constant memory usage, no leaks

See [performance benchmarks](/src/ensures/test_benchmarks.py) for detailed analysis.

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

## 📝 Changelog

See [CHANGELOG.md](CHANGELOG.md) for a list of changes in each version.

## 📄 License

This project is licensed under the GPL-3.0-or-later License - see the [LICENSE](LICENSE) file for details.
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ensures",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "design-by-contract, precondition, postcondition, invariant, testing, validation",
    "author": "Bruno Dantas",
    "author_email": "Bruno Dantas <4422988+brunodantas@users.noreply.github.com>",
    "download_url": "https://files.pythonhosted.org/packages/f2/8a/b0a59612bc6765df516939ff80453e7ef1c4530d3e199d4ef7f1d71720c0/ensures-0.3.0.tar.gz",
    "platform": null,
    "description": "# ensures\n\n[![CI](https://github.com/brunodantas/ensures/actions/workflows/ci.yml/badge.svg)](https://github.com/brunodantas/ensures/actions/workflows/ci.yml)\n[![PyPI version](https://badge.fury.io/py/ensures.svg)](https://badge.fury.io/py/ensures)\n[![PyPI - Downloads](https://img.shields.io/pypi/dm/ensures)](https://pypi.org/project/ensures/)\n[![codecov](https://codecov.io/gh/brunodantas/ensures/graph/badge.svg)](https://codecov.io/gh/brunodantas/ensures)\n[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)\n[![PyPI - Status](https://img.shields.io/pypi/status/ensures)](https://pypi.org/project/ensures/)\n[![Code style: ruff](https://img.shields.io/badge/code%20style-ruff-000000.svg)](https://github.com/astral-sh/ruff)\n[![Type checked: mypy](https://img.shields.io/badge/type%20checked-mypy-blue.svg)](https://mypy-lang.org/)\n[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n\n`ensures` is a simple Python package that implements the idea of [Design by Contract](https://en.wikipedia.org/wiki/Design_by_contract) described in the *Pragmatic Paranoia* chapter of [The Pragmatic Programmer](https://en.wikipedia.org/wiki/The_Pragmatic_Programmer). That's the chapter where they say you should *trust nobody, not even yourself*.\n\n![](trust.jpg)\n\n## Main Features\n\n- Verification of lists of pre/post condition and invariant functions.\n- Usage of arbitrary functions for such verification.\n- [Result-type](https://en.wikipedia.org/wiki/Result_type) return values.\n\n\n## Installation\n\n```bash\npip install ensures\n```\n\n## Usage\n\n### `precondition` / `require`\n\nRuns a list of functions on all args.\n\nReturns `Error` if any of them fails.\n\n```python\nfrom ensures import precondition\n\n\ndef is_positive(x):\n    \"\"\"Check if a number is positive.\"\"\"\n    return x > 0\n\n\n@precondition(is_positive)\ndef square_root(x):\n    \"\"\"Calculate square root with precondition that x must be positive.\"\"\"\n    return x**0.5\n```\n\n### `postcondition` / `ensure`\n\nRuns a list of functions on the result.\n\nReturns `Error` if any of them fails.\n\n```python\nfrom ensures import ensure\n\n\ndef result_is_even(result):\n    \"\"\"Check if result is even.\"\"\"\n    return result % 2 == 0\n\n\n@ensure(result_is_even)  # Using the alias\ndef double_number(x):\n    \"\"\"Double a number with postcondition that result is even.\"\"\"\n    return x * 2\n```\n\n\n### `invariant`\n\nRuns a list of functions on all args.\n\nReturns `Error` if any of them fails.\n\n```python\nfrom ensures import invariant\n\n\n@invariant(lambda x: x >= 0)  # Simple lambda invariant\ndef increment_counter(x):\n    \"\"\"Increment a counter with invariant that it stays non-negative.\"\"\"\n    return x + 1\n```\n\n### Result Handling\n\nPattern matching is supported to unpack the `Return` value.\n\n```python\nfrom ensures import Error, Success\n\n\nresult1 = square_root(1)\nresult2 = square_root(-1)  # This will return an Error instance\n\ndef handle_result(res):\n    match res:\n        case Success(value):\n            print(f\"Square root calculated: {value}\")\n        case Error(func, args):\n            print(f\"Precondition failed in {func.__name__} with args {args}\")\n\nhandle_result(result1)\nhandle_result(result2)\n```\n\n\n## More examples\n\nCheck [examples.py](/src/ensures/examples.py)\n\n## \ud83d\udcca Performance\n\nContract validation adds minimal overhead:\n- **Precondition**: ~7x baseline function call\n- **Postcondition**: ~8x baseline function call\n- **Memory**: Constant memory usage, no leaks\n\nSee [performance benchmarks](/src/ensures/test_benchmarks.py) for detailed analysis.\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.\n\n## \ud83d\udcdd Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for a list of changes in each version.\n\n## \ud83d\udcc4 License\n\nThis project is licensed under the GPL-3.0-or-later License - see the [LICENSE](LICENSE) file for details.",
    "bugtrack_url": null,
    "license": null,
    "summary": "Design by Contract with Functional Programming",
    "version": "0.3.0",
    "project_urls": {
        "Changelog": "https://github.com/brunodantas/ensures/blob/main/CHANGELOG.md",
        "Documentation": "https://github.com/brunodantas/ensures#readme",
        "Homepage": "https://github.com/brunodantas/ensures",
        "Issues": "https://github.com/brunodantas/ensures/issues",
        "Repository": "https://github.com/brunodantas/ensures"
    },
    "split_keywords": [
        "design-by-contract",
        " precondition",
        " postcondition",
        " invariant",
        " testing",
        " validation"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "73c63c3b7edf647732849de54d1dc2629a80423c2441f7451a9773594f286a87",
                "md5": "07a3535f61b5152231dd06d0d6707afd",
                "sha256": "510c32145fe2ee7f25bac8d7c9c6e2123c24c381dacf84c2aed9144b8ac069ca"
            },
            "downloads": -1,
            "filename": "ensures-0.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "07a3535f61b5152231dd06d0d6707afd",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 29694,
            "upload_time": "2025-09-10T00:13:49",
            "upload_time_iso_8601": "2025-09-10T00:13:49.694975Z",
            "url": "https://files.pythonhosted.org/packages/73/c6/3c3b7edf647732849de54d1dc2629a80423c2441f7451a9773594f286a87/ensures-0.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "f28ab0a59612bc6765df516939ff80453e7ef1c4530d3e199d4ef7f1d71720c0",
                "md5": "27d917806fc1d98e621943b2e992cf8a",
                "sha256": "57620b48bc2a6e91d1ac766a82bb1df89cfa82830b7a6442845aa6f19737dd37"
            },
            "downloads": -1,
            "filename": "ensures-0.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "27d917806fc1d98e621943b2e992cf8a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 28029,
            "upload_time": "2025-09-10T00:13:51",
            "upload_time_iso_8601": "2025-09-10T00:13:51.186894Z",
            "url": "https://files.pythonhosted.org/packages/f2/8a/b0a59612bc6765df516939ff80453e7ef1c4530d3e199d4ef7f1d71720c0/ensures-0.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-10 00:13:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "brunodantas",
    "github_project": "ensures",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "ensures"
}
        
Elapsed time: 3.70296s