Exemple #1
0
def event_source(method: t.Callable, name: t.Optional[str] = None):
    """A decorator which makes the function act as a source of before and after call events.

    You can later subscribe to these event with :py:func:`before` and :py:func`after` decorators.

    :param method: Target class method

    :param: Name of for the join point. If not given use the function name.
    """

    # We must use function name instead of function pointer for the registry, because function object changes with unbound vs. bound Python class methods

    if not name:
        name = method.__name__

    @functools.wraps(method)
    def _inner(*args, **kwargs):
        _self = args[0]
        fire_advisor_event(_self, name, AdvisorRole.before)
        retval = method(*args, **kwargs)
        fire_advisor_event(_self, name, AdvisorRole.after)
        return retval

    assert name not in _event_source_hooks, "There already exist event_source with same name"

    _event_source_hooks.append(name)
    method._event_source_name = name

    return _inner