Skip to content

input4mips_validation.attrs_helpers#

input4mips_validation.attrs_helpers #

Tools for helping with attrs, particularly validators

add_attrs_context(original) #

Decorate function with a try...except to add the attrs context

This means that the information about what attribute was being set and what value it was passed is also shown to the user.

Parameters:

Name Type Description Default
original Callable[[Any, Attribute[Any], T], None]

Function to decorate

required

Returns:

Type Description
Callable[[Any, Attribute[Any], T], None]

Decorated function

Notes

Only works with Python 3.11 and above. For other Python versions, the raw error is simply shown instead.

Source code in src/input4mips_validation/attrs_helpers.py
def add_attrs_context(
    original: Callable[[Any, attr.Attribute[Any], T], None],
) -> Callable[[Any, attr.Attribute[Any], T], None]:
    """
    Decorate function with a `try...except` to add the [`attrs`][] context

    This means that the information about what attribute was being set and
    what value it was passed is also shown to the user.

    Parameters
    ----------
    original
        Function to decorate

    Returns
    -------
    :
        Decorated function

    Notes
    -----
    Only works with Python 3.11 and above.
    For other Python versions, the raw error is simply shown instead.
    """

    @wraps(original)
    def with_attrs_context(
        instance: Any,
        attribute: attr.Attribute[Any],
        value: T,
    ) -> None:
        try:
            original(instance, attribute, value)
        except Exception as exc:
            if hasattr(exc, "add_note"):
                exc.add_note(
                    "\nError raised while initialising attribute "
                    f"``{attribute.name}`` of ``{type(instance)}``. "
                    f"\nValue provided: {value}"
                )

            raise

    return with_attrs_context

make_attrs_validator_compatible_single_input(func_to_wrap) #

Create a function that is compatible with validation via attrs.field.

This assumes that the function you're wrapping only takes a single input.

Parameters:

Name Type Description Default
func_to_wrap Callable[[T], None]

Function to wrap

required

Returns:

Type Description
Callable[[Any, Attribute[Any], T], None]

Wrapped function, which can be used as a validator with attrs.field.

Source code in src/input4mips_validation/attrs_helpers.py
def make_attrs_validator_compatible_single_input(
    func_to_wrap: Callable[[T], None],
) -> Callable[[Any, attr.Attribute[Any], T], None]:
    """
    Create a function that is compatible with validation via [`attrs.field`][].

    This assumes that the function you're wrapping only takes a single input.

    Parameters
    ----------
    func_to_wrap
        Function to wrap

    Returns
    -------
    :
        Wrapped function, which can be used as a validator with
        [`attrs.field`][].
    """

    @add_attrs_context
    @wraps(func_to_wrap)
    def attrs_compatible(
        instance: Any,
        attribute: attr.Attribute[Any],
        value: T,
    ) -> None:
        func_to_wrap(value)

    return attrs_compatible

make_attrs_validator_compatible_value_instance_input(func_to_wrap) #

Create a function that is compatible with validation via attrs.field.

This assumes that the function you're wrapping takes the instance and the values as inputs.

Parameters:

Name Type Description Default
func_to_wrap Callable[[Any, T], None]

Function to wrap

required

Returns:

Type Description
Callable[[Any, Attribute[Any], T], None]

Wrapped function, which can be used as a validator with attrs.field.

Source code in src/input4mips_validation/attrs_helpers.py
def make_attrs_validator_compatible_value_instance_input(
    func_to_wrap: Callable[[Any, T], None],
) -> Callable[[Any, attr.Attribute[Any], T], None]:
    """
    Create a function that is compatible with validation via [`attrs.field`][].

    This assumes that the function you're wrapping takes the instance and the
    values as inputs.

    Parameters
    ----------
    func_to_wrap
        Function to wrap

    Returns
    -------
    :
        Wrapped function, which can be used as a validator with [`attrs.field`][].
    """

    @add_attrs_context
    @wraps(func_to_wrap)
    def attrs_compatible(
        instance: Any,
        attribute: attr.Attribute[Any],
        value: T,
    ) -> None:
        func_to_wrap(instance, value)

    return attrs_compatible