@classmethod
def subclasses(cls):
    """Return a set of all subclasses, recursively."""
    seen = set()
    queue = set([cls])
    while queue:
        c = queue.pop()
        seen.add(c)
        sc = c.__subclasses__()
        for c in sc:
            if c not in seen:
                queue.add(c)
    seen.remove(cls)
    return seen
