def get_doc_changes(original, new, base_prefix=()):
    """
    Return a list of changed fields between
    two dict structures.

    :type original: dict
    :rtype: list[(tuple, object, object)]


    >>> get_doc_changes({}, {})
    []
    >>> get_doc_changes({'a': 1}, {'a': 1})
    []
    >>> get_doc_changes({'a': {'b': 1}}, {'a': {'b': 1}})
    []
    >>> get_doc_changes({'a': 1}, {'a': 2})
    [(('a',), 1, 2)]
    >>> get_doc_changes({'a': 1}, {'a': 2})
    [(('a',), 1, 2)]
    >>> get_doc_changes({'a': 1}, {'b': 1})
    [(('a',), 1, None), (('b',), None, 1)]
    >>> get_doc_changes({'a': {'b': 1}}, {'a': {'b': 2}})
    [(('a', 'b'), 1, 2)]
    >>> get_doc_changes({}, {'b': 1})
    [(('b',), None, 1)]
    >>> get_doc_changes({}, None, base_prefix=('a',))
    [(('a',), {}, None)]
    """
    changed_fields = []
    if original == new:
        return changed_fields

    if not isinstance(new, dict):
        changed_fields.append((base_prefix, original, new))
        return changed_fields

    all_keys = set(original.keys()).union(new.keys())

    for key in all_keys:
        key_prefix = base_prefix + (key,)

        original_val = original.get(key)
        new_val = new.get(key)

        if original_val == new_val:
            continue

        if isinstance(original_val, dict):
            changed_fields.extend(get_doc_changes(original_val, new_val, key_prefix))
        else:
            changed_fields.append(
                (key_prefix, original_val, new_val)
            )

    return sorted(changed_fields, key=lambda a: a[0])