def combine_reducers(reducers):
final_reducers = {key: reducer<EOL>for key, reducer in reducers.items()<EOL>if hasattr(reducer, '<STR_LIT>')}<EOL>sanity_error = None<EOL>try:<EOL><INDENT>assert_reducer_sanity(final_reducers)<EOL><DEDENT>except Exception as e:<EOL><INDENT>sanity_error = e<EOL><DEDENT>def combination(state=None, action=None):<EOL><INDENT>if state is None:<EOL><INDENT>state = {}<EOL><DEDENT>if sanity_error:<EOL><INDENT>raise sanity_error<EOL><DEDENT>has_changed = False<EOL>next_state = {}<EOL>for key, reducer in final_reducers.items():<EOL><INDENT>previous_state_for_key = state.get(key)<EOL>next_state_for_key = reducer(previous_state_for_key, action)<EOL>if next_state_for_key is None:<EOL><INDENT>msg = get_undefined_state_error_message(key, action)<EOL>raise Exception(msg)<EOL><DEDENT>next_state[key] = next_state_for_key<EOL>has_changed = (has_changed or<EOL>next_state_for_key != previous_state_for_key)<EOL><DEDENT>return next_state if has_changed else state<EOL><DEDENT>return combination<EOL>
composition tool for creating reducer trees.

Args:
    reducers: dict with state keys and reducer functions
              that are responsible for each key

Returns:
    a new, combined reducer function