"""
meta.py

Some useful metaclasses.
"""


class LeafClassesMeta(type):
    """
    A metaclass for classes that keeps track of all of them that
    aren't base classes.

    >>> Parent = LeafClassesMeta('MyParentClass', (), {})
    >>> Parent in Parent._leaf_classes
    True
    >>> Child = LeafClassesMeta('MyChildClass', (Parent,), {})
    >>> Child in Parent._leaf_classes
    True
    >>> Parent in Parent._leaf_classes
    False

    >>> Other = LeafClassesMeta('OtherClass', (), {})
    >>> Parent in Other._leaf_classes
    False
    >>> len(Other._leaf_classes)
    1
    """

    def __init__(cls, name, bases, attrs):
        if not hasattr(cls, '_leaf_classes'):
            cls._leaf_classes = set()
        leaf_classes = getattr(cls, '_leaf_classes')
        leaf_classes.add(cls)
        # remove any base classes
        leaf_classes -= set(bases)


class TagRegistered(type):
    """
    As classes of this metaclass are created, they keep a registry in the
    base class of all classes by a class attribute, indicated by attr_name.
    """

    attr_name = 'tag'

    def __init__(cls, name, bases, namespace):
        super(TagRegistered, cls).__init__(name, bases, namespace)
        if not hasattr(cls, '_registry'):
            cls._registry = {}
        meta = cls.__class__
        attr = getattr(cls, meta.attr_name, None)
        if attr:
            cls._registry[attr] = cls

@@ -1046,16 +1046,398 @@
 tr_name.
+%0A%0A    %3E%3E%3E FooObject = TagRegistered('FooObject', (), dict(tag='foo'))%0A    %3E%3E%3E FooObject._registry%5B'foo'%5D is FooObject%0A    True%0A    %3E%3E%3E BarObject = TagRegistered('Barobject', (FooObject,), dict(tag='bar'))%0A    %3E%3E%3E FooObject._registry is BarObject._registry%0A    True%0A    %3E%3E%3E len(FooObject._registry)%0A    2%0A    %3E%3E%3E FooObject._registry%5B'bar'%5D%0A    %3Cclass 'jaraco.classes.meta.Barobject'%3E
 %0A    %22%22%22

Add tests for TagRegistered