Runtime contracts and predicate-based validation for Python.
Project description
ironclad
ironclad helps developers write defensive, self-documenting Python code.
It enforces parameter types, constrains values with predicates or enums, and raises precise errors on violation—keeping interfaces explicit and code clean. Simple, composable guards harden functions and classes with correctness and security, with minimal overhead and maximum readability.
Features
- Strict type checks: Fail fast on mismatches with clear
TypeErrors. - Value constraints: Allowlists, enums, ranges, and custom predicates.
- Composable guards: Combine checks for rich, readable contracts.
- Low-boilerplate API: Keep validation close to the signature, not scattered.
- Security-minded: Reduce attack surface from unexpected inputs.
Installation
You can install ironclad in one of two ways:
- Install via pip:
pip install ironclad
- Clone this repository:
git clone https://github.com/Zentiph/ironclad
Quick Start
Importing the library:
>>> import ironclad as ic
Ensuring strict type enforcements on functions:
>>> # enforcing types with instance/type spec checks
>>> @ic.enforce_types(price=float, tax_rate=float)
... def add_sales_tax(price, tax_rate):
... return price * (1 + tax_rate)
...
>>> add_sales_tax(50.0, 0.08)
54.0
>>> add_sales_tax(50.0, "0.08")
TypeError: add_sales_tax(): 'tax_rate' expected 'float', got 'str' with value '0.08'
>>>
>>> # enforcing types with type annotations
>>> @ic.enforce_annotations()
... def get_even(l: list[int]) -> list[int]:
... return [e for e in l if e % 2 == 0]
...
>>> get_even([1, 2, 3])
[2]
>>> get_even([1.0, 2.0, 3.0])
TypeError: get_even(): 'l' expected 'list[int]', got 'list' with value [1.0, 2.0, 3.0]
Creating type-enforced runtime overloads:
>>> @ic.runtime_overload
... def describe(x: int):
... return f"int: {x}"
...
>>> @describe.overload
... def _(x: str):
... return f"str: '{x}'"
...
>>> describe(1)
'int: 1'
>>> describe("hi")
"str: 'hi'"
>>> describe(2.3)
InvalidOverloadError: No overload of describe() matches (float). Candidates: describe(x: int) | describe(x: str)
Creating predicates
>>> is_pos = ic.predicates.Predicate[int](
... lambda x: x > 0, "is positive"
... )
>>> is_pos(4)
True
>>> is_pos(-1)
False
Documentation
ironclad's documentation is deployed on GitHub Pages.
Contributions
License
See the license page.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ironclad-0.1.0.tar.gz.
File metadata
- Download URL: ironclad-0.1.0.tar.gz
- Upload date:
- Size: 20.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e0d43950ee70922a4b13274ad39f33bc70c784e7a5ac2e76efec6f689149ad8a
|
|
| MD5 |
ca7d0321639f60fbdfde4c3af43f8343
|
|
| BLAKE2b-256 |
d79792d216d293cae030096bc24da8d2a53ff1a3f9b96025e27a2e1b2f09b6df
|
File details
Details for the file ironclad-0.1.0-py3-none-any.whl.
File metadata
- Download URL: ironclad-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8e42816e4c30ae8aa4b06bee770809d516af4226ed5a1ce3044ae7e5ecae1bf
|
|
| MD5 |
8d4d8ca218546f5548e06cf3c105e7e8
|
|
| BLAKE2b-256 |
3d1854060b275d3e6c0bd35487d1fdac5adccb6f3bc5de345fc3075f9b5d672b
|