def depends(func=None, after=None, before=None, priority=None):
    if not (func is None or inspect.ismethod(func) or inspect.isfunction(func)):
        raise ValueError("depends decorator can only be used on functions or methods")
    if not (after or before or priority):
        raise ValueError("depends decorator needs at least one argument")
    if func is None:
        return partial(depends, after=after, before=before, priority=priority)
    def self_check(a, b):
        if a == b:
            raise ValueError("Test '{}' cannot depend on itself".format(a))
    def handle_dep(conditions, _before=True):
        if conditions:
            if type(conditions) is not list:
                conditions = [conditions]
            for cond in conditions:
                if hasattr(cond, '__call__'):
                    cond = cond.__name__
                self_check(func.__name__, cond)
                if _before:
                    soft_dependencies[cond].add(func.__name__)
                else:
                    dependencies[func.__name__].add(cond)
    handle_dep(before)
    handle_dep(after, False)
    if priority:
        priorities[func.__name__] = priority
    @wraps(func)
    def inner(*args, **kwargs):
        return func(*args, **kwargs)
    return inner