from typing import OrderedDict


def field_keys_equal(a, b):
    """
    Check equality of `field_keys` recursively between two instances who contains `field_types`.

    This method is widely used to take place of "isinstance(config instance, config meta)",
    which sometimes returns unexpected False.

    :param a:
    :param b:
    :return: whether keys of a are fully equal to keys of b
    """

    assert hasattr(a, '_field_types')
    assert hasattr(b, '_field_types')
    assert isinstance(a._field_types, OrderedDict)
    assert isinstance(b._field_types, OrderedDict)
    for k, v in a._field_types.items():
        if k not in b._field_types:
            return False
        if hasattr(v, '_field_types'):
            if not hasattr(b._field_types[k], '_field_types'):
                return False
            eq = field_keys_equal(v, b._field_types[k])
            if not eq:
                return False
    return True