def decorate_cooperating(cls, method,
                         fixed_keywords  = {},
                         post_cooperate  = False,
                         inner_cooperate = False):
    # TODO: Cleanup this function is too big!

    assert not post_cooperate or \
           not inner_cooperate

    method_name = method.__name__

    if method_name == '__init__':
        check_all_params_are_keyword(method)
    if method_name == '__del__':
        check_no_params(method)

    extractor = make_keyword_extractor(method)

    if post_cooperate:
        if has_keywords(method) and fixed_keywords:
            def wrapper(self, *a, **orig):
                ours = extractor(orig)
                orig.update(fixed_keywords)
                method(self, *a, **ours)
                return getattr(super(cls, self), method_name)(*a, **orig)
        else:
            def wrapper(self, *a, **orig):
                method(self, *a)
                return getattr(super(cls, self), method_name)(*a, **orig)

    elif inner_cooperate:
        assert not fixed_keywords
        # TODO: Maybe disregard this check for the sake of
        # performance or some other patterns.
        inner_call_count = [0]
        def wrapper(self, *a, **orig):
            ours = extractor(orig)
            orig.update(fixed_keywords)
            next_fn = getattr(super(cls, self), method_name)
            def next_method(**kws):
                inner_call_count[0] += 1
                orig.update(kws)
                next_fn(*a, **orig)
            result = method(self, next_method, *a, **ours)
            if inner_call_count[0] != 1:
                raise CooperativeError, "Next method must be called exactly once."
            inner_call_count[0] = 0
            return result

    else:
        if has_keywords(method) or fixed_keywords:
            def wrapper(self, *a, **orig):
                ours = extractor(orig)
                orig.update(fixed_keywords)
                getattr(super(cls, self), method_name)(*a, **orig)
                return method(self, *a, **ours)
        else:
            def wrapper(self, *a, **orig):
                getattr(super(cls, self), method_name)(*a, **orig)
                return method(self, *a)

    wrapper = wraps(method)(wrapper)
    wrapper.__objclass__ = cls
    return wrapper
dataset/ETHPy150Open arximboldi/cooper/cooper/cooper.py/decorate_cooperating/operator `or` -> `and`