def make_raw_diff(repo, base, branch, max_diff_size_utf8_bytes):
    raw_diff = phlgit_diff.raw_diff_range(
        repo, base, branch, _FULL_DIFF_CONTEXT_LINES)
    new_raw_diff = unicode(raw_diff, errors='replace')
    full_diff_size_utf8_bytes = len(new_raw_diff.encode("utf-8"))
    diff_size_utf8_bytes = full_diff_size_utf8_bytes

    if not raw_diff:
        raise NoDiffError()

    reduction_list = []

    # TODO: detect generated files and try less context on just those first
    # TODO: detect generated files and try no context on just those first
    # TODO: detect generated files and try excluding those first

    # if the diff is too big then regen with less context
    for context_lines in [_GOOD_DIFF_CONTEXT_LINES, _SOME_DIFF_CONTEXT_LINES]:
        if diff_size_utf8_bytes > max_diff_size_utf8_bytes:
            raw_diff = phlgit_diff.raw_diff_range(
                repo, base, branch, context_lines)
            new_raw_diff = unicode(raw_diff, errors='replace')
            diff_size_utf8_bytes = len(new_raw_diff.encode("utf-8"))
            reduction_list.append(
                LessContextReduction(
                    diff_size_utf8_bytes,
                    context_lines))

    # if the diff is still too big then regen with no context
    if diff_size_utf8_bytes > max_diff_size_utf8_bytes:
        raw_diff = phlgit_diff.raw_diff_range(repo, base, branch, None)
        new_raw_diff = unicode(raw_diff, errors='replace')
        diff_size_utf8_bytes = len(new_raw_diff.encode("utf-8"))
        reduction_list.append(
            RemoveContextReduction(
                diff_size_utf8_bytes))

    # if the diff is still too big then just use the diff stat with message
    if diff_size_utf8_bytes > max_diff_size_utf8_bytes:
        stat = phlgit_diff.stat_range(repo, base, branch)
        content = "this diff is very large, it has been reduced to a summary:"
        content = '\n\n'.join([content, stat])
        raw_diff = phlgit_diff.create_add_file('diffstat', content)
        new_raw_diff = unicode(raw_diff, errors='replace')
        diff_size_utf8_bytes = len(new_raw_diff.encode("utf-8"))
        reduction_list.append(
            DiffStatReduction(
                diff_size_utf8_bytes))

    # if the diff is still too big then error
    if diff_size_utf8_bytes > max_diff_size_utf8_bytes:
        raise abdt_exception.LargeDiffException(
            "diff too big", diff_size_utf8_bytes, max_diff_size_utf8_bytes)

    did_replace_unicode = new_raw_diff != raw_diff

    return DiffResult(
        new_raw_diff,
        reduction_list,
        did_replace_unicode,
        diff_size_utf8_bytes,
        full_diff_size_utf8_bytes,
        max_diff_size_utf8_bytes)


# -----------------------------------------------------------------------------
# Copyright (C) 2013-2014 Bloomberg Finance L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ------------------------------ END-OF-FILE ----------------------------------
Is the value hashable, i.e. suitable for dictionary/set keying.
dataset/ETHPy150Open bloomberg/phabricator-tools/py/abd/abdt_differ.py/make_raw_diff--crossover with--dataset/ETHPy150Open kayhayen/Nuitka/nuitka/nodes/NodeBases.py/ExpressionMixin.isKnownToBeHashable