import functools
import warnings


def deprecated(_func=None, *, print_msg=None):
    """
    This is a decorator which can be used to mark functions as deprecated.
    It will result in a warning being emitted when the function is used.

    Args:
        print_msg: Information to point user to newest version.
    """

    def decorator_deprecated(func):

        @functools.wraps(func)
        def wrapper_decorator(*args, **kwargs):
            with warnings.catch_warnings():
                if print_msg is None:
                    warnings.warn(f"\nFunction deprecated: {func.__name__}",
                                  category=DeprecationWarning, stacklevel=2)
                else:
                    warnings.warn(f"\nFunction deprecated: {func.__name__}"
                                  f"\n{print_msg}",
                                  category=DeprecationWarning, stacklevel=2)
            return func(*args, **kwargs)

        return wrapper_decorator

    if _func is None:
        return decorator_deprecated
    else:
        return decorator_deprecated(_func)