def relation_target_types(schema, rtype, role, preset_types=None):
    """Yield target entity types for (rtype, role) relation, possibly filtered
    out from values not in `preset_types`.
    """
    rschema = schema[rtype]
    for target_eschema in sorted(rschema.targets(role=role)):
        if target_eschema.final:
            continue
        target_type = target_eschema.type
        if preset_types is not None and target_type not in preset_types:
            continue
        yield target_type
