from typing import Callable
from typing import Any


def _apply_constraints(method: Callable[..., Any]) -> Callable[..., Any]:
    """Decorator for (re)applying constraint after updating hfun spec

    This function is a deocrator that takes in a callable and assumes
    the callable is a method whose first argument is an object. In the
    wrapper function, after the wrapped method is called the
    `apply_added_constraints` method is called on the object and
    then the return value of the wrapped method is returned to the
    caller.

    Parameters
    ----------
    method : callable
        Method to be wrapped so that the constraints are automatically
        re-applied after method is executed.

    Returns
    -------
    callable
        The wrapped method
    """

    def wrapped(obj, *args, **kwargs):
        rv = method(obj, *args, **kwargs)
        obj.apply_added_constraints()
        return rv
    return wrapped