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)
__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__()
__or__(other)
__repr__()
Get a representation of this predicate.
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
The repr. |
__xor__(other)
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)
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)
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. |