def merge_metadata(cls):
    """
    Merge all the __metadata__ dicts in a class's hierarchy

    keys that do not begin with '_' will be inherited.

    keys that begin with '_' will only apply to the object that defines them.

    """
    cls_meta = cls.__dict__.get('__metadata__', {})
    meta = {}
    for base in cls.__bases__:
        meta.update(getattr(base, '__metadata__', {}))
    for key in list(meta.keys()):
        if key.startswith('_'):
            del meta[key]
    meta.update(cls_meta)
    return meta
