Skip to content

API

This page is generated from docstrings.


Top-level API

ironclad

DEFAULT_ENFORCE_OPTIONS = EnforceOptions() module-attribute

Default type enforcement options.

(allow_subclasses=True, check_defaults=True, strict_bools=True)

ClassInfo = type | UnionType | tuple['ClassInfo', ...] module-attribute

A type alias to match Python's _ClassInfo used for isinstance() arguments.

version_info module-attribute

Multimethod

Runtime overloads with type-hint matching.

It is generally recommended to use the runtime_overload decorator instead of this class directly to create runtime overloads, as the error message diagnostics are better.

__call__(*args, **kwargs)

Call this Multimethod with the given argument overload.

Raises:

Type Description
InvalidOverloadError

If an overload that does not exist is called.

Returns:

Name Type Description
Any Any

The return value matching the overload and arguments called.

__init__(func=None, /, *, options=DEFAULT_ENFORCE_OPTIONS)

__init__(func: Callable[..., Any], /, *, options: EnforceOptions = DEFAULT_ENFORCE_OPTIONS) -> None
__init__(func: None = None, /, *, options: EnforceOptions = DEFAULT_ENFORCE_OPTIONS) -> None

Runtime overloads with type-hint matching.

It is generally recommended to use the runtime_overload decorator instead of this class directly to create runtime overloads, as the error message diagnostics are better.

Parameters:

Name Type Description Default
func Callable[..., Any] | None

The function to overload. Defaults to None.

None
options EnforceOptions

Type enforcement options. Defaults to DEFAULT_ENFORCE_OPTIONS.

DEFAULT_ENFORCE_OPTIONS

overload(func)

Register a new function overload to this Multimethod.

Parameters:

Name Type Description Default
func Callable[..., Any]

The function to register.

required

Returns:

Name Type Description
Multimethod Multimethod

The updated Multimethod now including the given function.

EnforceOptions dataclass

A configuration of type enforcement options.

allow_subclasses = True class-attribute instance-attribute

Whether to allow subclasses to count as a valid type for a parameter.

check_defaults = True class-attribute instance-attribute

Whether to apply defaults for missing arguments.

strict_bools = True class-attribute instance-attribute

Whether to strictly disallow bools to count as integers.

coerce_types(**coercers)

Decorator that coerces the types of function parameters using coercer functions.

This decorator is particularly useful for coercing string arguments into their proper types when using CLI/ENV arguments, web handlers, enums, and JSONs.

Parameters:

Name Type Description Default
coercers Coercer

A mapping of argument names to coercer functions.

{}

Examples:

>>> import ironclad as ic
>>>
>>> @ic.coerce_types(data=str)
... def parse_data(data):
...     if len(data) > 3:
...         return data[:3]
...     return data
...
>>> parse_data("hi")
'hi'
>>> parse_data(123)
'123'
>>> parse_data(1.7823)
'1.7'

enforce_annotations(*, check_return=True)

Decorator that enforces the function's type hints at runtime.

Parameters:

Name Type Description Default
check_return bool

Whether to enforce the return type. Defaults to True.

True

Examples:

>>> import ironclad as ic
>>>
>>> @ic.enforce_annotations()
... def report(code: int, msg: str = "Error: {code}") -> None:
...     print(msg.format(code=code))
...
>>> report(1)
Error: 1
>>> report(1, "Uh oh: {code}")
Uh oh: 1
>>> report(2.3)
TypeError: report(): 'code' expected 'int' (...), got 'float' with value 2.3

enforce_types(options=DEFAULT_ENFORCE_OPTIONS, /, **types)

Decorator that enforces the types of function parameters.

Supports typing types.

Parameters:

Name Type Description Default
options EnforceOptions

Type enforcement options. Defaults to DEFAULT_ENFORCE_OPTIONS.

DEFAULT_ENFORCE_OPTIONS
types ClassInfo

A mapping of argument names to expected types.

{}

Examples:

>>> import ironclad as ic
>>>
>>> @ic.enforce_types(code=int, msg=str)
... def report(code, msg="Error: {code}"):
...     print(msg.format(code=code))
...
>>> report(1)
Error: 1
>>> report(1, "Uh oh: {code}")
Uh oh: 1
>>> report(2.3)
TypeError: report(): 'code' expected 'int' (...), got 'float' with value 2.3

enforce_values(**predicate_map)

Decorator that enforces value constraints on function parameters.

Parameters:

Name Type Description Default
predicate_map Predicate

A mapping of argument names to predicates.

{}

Examples:

>>> import ironclad as ic
>>> from ironclad.predicates import Predicate
>>>
>>> nonnegative = Predicate[float](lambda x: x >= 0, "nonnegative")
>>>
>>> @ic.enforce_values(price=nonnegative)
... def add_sales_tax(price: float) -> float:
...     return price * 1.08
...
>>> add_sales_tax(50)
54.0
>>> add_sales_tax(0)
0.0
>>> add_sales_tax(-2)
ValueError: add_sales_tax(): 'price' failed constraint: nonnegative; got -2

runtime_overload(func, /, *, options=DEFAULT_ENFORCE_OPTIONS)

Turn a function into a Multimethod, allowing for runtime overloads.

Parameters:

Name Type Description Default
func Callable[..., Any]

The function to turn into a Multimethod.

required
options EnforceOptions

Type enforcement options. Defaults to DEFAULT_ENFORCE_OPTIONS.

DEFAULT_ENFORCE_OPTIONS

Examples:

>>> import ironclad as ic
>>>
>>> @ic.runtime_overload
... def describe(x: int) -> str:
...     return f"int: {x}"
...
>>> @describe.overload
>>> def _(x: str) -> str:
...     return f"str: '{x}'"
...
>>> describe(32)
'int: 32'
>>> describe("python")
"str: 'python'"
>>> describe(2.4)
InvalidOverloadError: No overload of describe() matches (float). (...)

Predicates

ironclad.predicates

Tools for creating predicates for logic or validation.

ALWAYS = Predicate[Any](lambda _: True, 'always', 'always true') module-attribute

A predicate that always evaluates to True.

NEGATIVE = Predicate[AnyRealNumber](lambda x: x < 0, 'negative', lambda _: 'expected a negative number') module-attribute

A predicate that checks if a number is negative.

NEVER = Predicate[Any](lambda _: False, 'never', 'always false') module-attribute

A predicate that always evaluates to False.

NON_EMPTY = (~length(0)).with_name('non empty').with_msg(lambda _: 'expected non empty sized object') module-attribute

A predicate that checks if the given value is sized and non empty.

NOT_NONE = Predicate[Any](lambda x: x is not None, 'not None', lambda _: 'expected a not-None value') module-attribute

A predicate that checks if a value is not None.

POSITIVE = Predicate[AnyRealNumber](lambda x: x > 0, 'positive', lambda _: 'expected a positive number') module-attribute

A predicate that checks if a number is positive.

Predicate

Bases: Generic[T]

A predicate, containing a predicate function and a failure message.

Predicates can be modified/combined using the logical operators and ('&'), or ('|'), and not ('~').

func property

Get the function this predicate runs to test values.

Returns:

Type Description
Callable[[T], bool]

Callable[[T], bool]: The function this predicate uses.

msg property

Get the failure name of this predicate.

Returns:

Type Description
str | Callable[[T | None], str]

str | Callable[[T | None], str]: The failure message of this predicate.

name property

Get the name of this predicate.

Returns:

Name Type Description
str str

The name of this predicate.

__and__(other)

Combine this predicate with another, merging their conditions with an 'AND'.

Parameters:

Name Type Description Default
other Predicate[T]

The other predicate.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: The combined predicate.

__bool__()

Raise a TypeError if a predicate object is converted to a bool.

Raises:

Type Description
TypeError

If this function is called.

__call__(x)

Evaluate this predicate with a value.

Parameters:

Name Type Description Default
x T

Value to pass to the predicate.

required

Returns:

Name Type Description
bool bool

Whether the given value is accepted by this predicate.

__init__(func, /, name, msg=None)

__init__(func: Callable[[T], bool], /, name: str, msg: str) -> None
__init__(func: Callable[[T], bool], /, name: str, msg: Callable[[T | None], str]) -> None
__init__(func: Callable[[T], bool], /, name: str, msg: None = None) -> None

A predicate, containing a predicate function, a name, and a failure message.

Parameters:

Name Type Description Default
func Callable[[T], bool]

The function that accepts or rejects values.

required
name str

The name of the predicate.

required
msg str | Callable[[T | None], str] | None

The rejection message, message supplier, or None for a default message. Defaults to None.

None

Examples:

>>> from ironclad.predicates import Predicate
>>>
>>> positive = Predicate[float](lambda x: x > 0, "positive")
>>> positive(4)
True
>>> positive(-2)
False

__invert__()

Negate this predicate.

Returns:

Type Description
Predicate[T]

Predicate[T]: The negated predicate.

__or__(other)

Combine this predicate with another, merging their conditions with an 'OR'.

Parameters:

Name Type Description Default
other Predicate[T]

The other predicate.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: The combined predicate.

__repr__()

Get a representation of this predicate.

Returns:

Name Type Description
str str

The repr.

__xor__(other)

Combine this predicate with another, merging their conditions with an 'XOR'.

Parameters:

Name Type Description Default
other Predicate[T]

The other predicate.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: The combined predicate.

all()

Check if every element in an iterable is accepted.

Returns:

Type Description
Predicate[Iterable[T]]

Predicate[Iterable[T]]: The new predicate.

any()

Check if any element in an iterable is accepted.

Returns:

Type Description
Predicate[Iterable[T]]

Predicate[Iterable[T]]: The new predicate.

at_least(n)

Check if at least n elements in an iterable are accepted.

Parameters:

Name Type Description Default
n int

The minimum number of elements that must be accepted.

required

Returns:

Type Description
Predicate[Iterable[T]]

Predicate[Iterable[T]]: The new predicate.

Raises:

Type Description
ValueError

If n is less than 0.

at_most(n)

Check if at most n elements in an iterable are accepted.

Parameters:

Name Type Description Default
n int

The maximum number of elements that must be accepted.

required

Returns:

Type Description
Predicate[Iterable[T]]

Predicate[Iterable[T]]: The new predicate.

Raises:

Type Description
ValueError

If n is less than 0.

clone(*, name=None, msg=None)

Clone this predicate.

Parameters:

Name Type Description Default
name str | None

The new predicate's name. Copies the old one if None or "". Defaults to None.

None
msg (str | Callable[[Any | None], str], None)

The new predicate's failure message. Copies the old one if None. Defaults to None.

None

Returns:

Type Description
Predicate[T]

Predicate[T]: The cloned predicate.

exactly(n)

Check if exactly n elements in an iterable are accepted.

Parameters:

Name Type Description Default
n int

The exact number of elements that must be accepted.

required

Returns:

Type Description
Predicate[Iterable[T]]

Predicate[Iterable[T]]: The new predicate.

Raises:

Type Description
ValueError

If n is less than 0.

explain(x)

Explain this predicate's output for x.

Parameters:

Name Type Description Default
x T

The value to test.

required

Returns:

Type Description
str | None

str | None: None if ok, otherwise an explanation of why this predicate will fail for x.

implies(other)

A predicate which checks that this predicate implies another predicate.

Parameters:

Name Type Description Default
other Predicate[T]

The predicate to imply.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: The implication predicate.

lift(func, /, name, msg)

lift(func: Callable[[T], bool], /, name: str | None, msg: str | Callable[[T | None], str]) -> Predicate[T]
lift(func: Callable[[U], bool], /, name: str | None, msg: str | Callable[[U | None], str]) -> Predicate[U]

Lift this predicate to create a new one.

This is the ideal way to create a predicate based on another one, because this method adds the previous predicate to the new predicate's failure context.

When lifting a predicate, the new function should utilize the original predicate's function in order to maintain a semantic hierarchy.

Parameters:

Name Type Description Default
func Callable[[Any], bool]

The new predicate function.

required
name str | None

The new predicate's name. Copies the old one if None.

required
msg (str | Callable[[Any | None], str], None)

The new predicate's failure message.

required

Returns:

Type Description
Predicate[Any]

Predicate[Any]: The lifted predicate.

on(getter)

Check if a property of an object validates it.

Parameters:

Name Type Description Default
getter Callable[[Obj], T]

function to access the property of an object.

required

Returns:

Type Description
Predicate[Obj]

Predicate[Obj]: The new predicate.

quantify(quantifier, /, label, *, prefix)

Build a predicate that approves an iterable via a boolean quantifier.

Parameters:

Name Type Description Default
quantifier Callable[[Iterable[bool]], bool]

Function that takes an iterable of bools and determines if it is approved.

required
label str

A name label for the quantifier.

required
prefix str

A prefix for the predicate's failure message.

required

Returns:

Type Description
Predicate[Iterable[T]]

Predicate[Iterable[T]]: The quantified predicate.

render_msg(x=None)

render_msg(x: T) -> str
render_msg(x: None = None) -> str

Render this predicate's message with a given input value.

Parameters:

Name Type Description Default
x T | None

The value given to the predicate. Defaults to None.

None

Returns:

Name Type Description
str str

The formatted message with the given test value.

render_tree(x=None)

render_tree(x: T) -> str
render_tree(x: None = None) -> str

Render this predicate's message with a given input value as a tree.

Parameters:

Name Type Description Default
x T | None

The value given to the predicate. Defaults to None.

None

Returns:

Name Type Description
str str

The formatted tree with the given test value.

render_with_context(x=None, /, *, max_chain=6)

render_with_context(x: T, /, *, max_chain: int = 6) -> str
render_with_context(x: None = None, /, *, max_chain: int = 6) -> str

Render this predicate's message with a given input value and context.

Parameters:

Name Type Description Default
x T | None

The value given to the predicate. Defaults to None.

None
max_chain int

The maximum number of chains to report. Defaults to 6.

6

Returns:

Name Type Description
str str

The formatted message with the given test value.

validate(x, /, *, label='value', exc=ValueError)

validate(x: T, /, *, label: str = 'value', exc: type[BaseException] = ValueError) -> T
validate(x: T, /, *, label: str = 'value', exc: ExceptionFactory[T]) -> T

Return x if ok, otherwise raise an error with useful context.

Parameters:

Name Type Description Default
x T

The value to test.

required
label str

A label for the tested value. Defaults to "value".

'value'
exc type[BaseException] | ExceptionFactory[T]

An exception or exception factory called on failure. If a factory, it should take a label, the tested value, and error message and return an exception to raise. Defaults to ValueError.

ValueError

Raises:

Type Description
BaseException

If the validation fails, the exception returned by exc_factory will be raised.

Returns:

Name Type Description
T T

x, if the predicate accepts it.

with_msg(msg)

with_msg(msg: str) -> Predicate[T]
with_msg(msg: Callable[[T | None], str]) -> Predicate[T]

Clone this predicate and give it a new message.

Parameters:

Name Type Description Default
msg str | Callable[[T | None], str]

The new message.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: The cloned predicate with the new message.

with_name(name)

Clone this predicate and give it a new name.

Parameters:

Name Type Description Default
name str

The new name.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: The cloned predicate with the new name.

all_of(*predicates)

Combine multiple predicates, merging their conditions with an 'AND'.

Parameters:

Name Type Description Default
predicates Predicate[T]

The predicates to merge.

()

Raises:

Type Description
ValueError

If there are no predicates given.

Returns:

Type Description
Predicate[T]

Predicate[T]: The combined predicate.

any_of(*predicates)

Combine multiple predicates, merging their conditions with an 'OR'.

Parameters:

Name Type Description Default
predicates Predicate[T]

The predicates to merge.

()

Raises:

Type Description
ValueError

If there are no predicates given.

Returns:

Type Description
Predicate[T]

Predicate[T]: The combined predicate.

between(low, high, /, *, inclusive=True)

A predicate that checks if a value is within a range of values.

Parameters:

Name Type Description Default
low C

The lower bound (must be comparable).

required
high C

The upper bound (must be comparable).

required
inclusive bool

Whether the bounds are inclusive. Defaults to True.

True

Returns:

Type Description
Predicate[C]

Predicate[C]: A predicate that checks if the given value is in the valid range.

equals(value)

A predicate that checks if a value is equal to another.

Parameters:

Name Type Description Default
value T

The value to store and use to check against.

required

Returns:

Type Description
Predicate[T]

Predicate[T]: A predicate that checks if a value is equal to another.

instance_of(t)

A predicate that checks if a value is an instance of a type/types.

Parameters:

Name Type Description Default
t ClassInfo

The type/types to check.

required

Returns:

Type Description
Predicate[object]

Predicate[object]: A predicate that checks if a value is an instance of a type.

length(size)

A predicate that checks if the given value has a size matching the given length.

Parameters:

Name Type Description Default
size int

The approved length of the sized object.

required

Returns:

Type Description
Predicate[Sized]

Predicate[Sized]: A predicate that checks if the object's size matches the length.

length_between(low, high, /, *, inclusive=True)

A predicate that checks if the size of a sized object is within a range of sizes.

Parameters:

Name Type Description Default
low int

The lower bound.

required
high int

The upper bound.

required
inclusive bool

Whether the bounds are inclusive. Defaults to True.

True

Returns:

Type Description
Predicate[Sized]

Predicate[Sized]: A predicate that checks if the size of a given sized object is in the valid range.

one_of(values)

A predicate that checks if a value is one of the values in an iterable.

Args: values (Iterable[T]): The iterable of valid values.

Returns:

Type Description
Predicate[T]

Predicate[T]: A predicate that checks if the given value is in the iterable of valid values.

regex(pattern, flags=0)

A predicate that checks if a string matches the given regex.

Parameters:

Name Type Description Default
pattern str

The regex pattern.

required
flags int

The number of flags, by default 0.

0

Returns:

Type Description
Predicate[str]

Predicate[str]: A predicate that checks if a string matches the given regex.