Decorator that generates ordering operators for the decorated class based
    on the given member names. All ordering except equality functions will
    raise a TypeError when a comparison with an unrelated class is attempted.
    (Comparisons with child classes will thus work fine with the capabilities
    of the base class as python will choose the base classes comparison
    operator in that case.)

    Note that this decorator modifies the given class in place!

    :param members: A list of members to compare, ordered from high priority to
                    low. I.e. if the first member is equal the second will be
                    taken for comparison and so on. If a member is None it is
                    considered smaller than any other value except None.

def generate_ordering(*members):
    """
    Decorator that generates ordering operators for the decorated class based
    on the given member names. All ordering except equality functions will
    raise a TypeError when a comparison with an unrelated class is attempted.
    (Comparisons with child classes will thus work fine with the capabilities
    of the base class as python will choose the base classes comparison
    operator in that case.)

    Note that this decorator modifies the given class in place!

    :param members: A list of members to compare, ordered from high priority to
                    low. I.e. if the first member is equal the second will be
                    taken for comparison and so on. If a member is None it is
                    considered smaller than any other value except None.
    """
    def decorator(cls):
        def lt(self, other):
            if not isinstance(other, cls):
                raise TypeError("Comparison with unrelated classes is "
                                "unsupported.")

            for member in members:
                if getattr(self, member) == getattr(other, member):
                    continue

                if (
                        getattr(self, member) is None or
                        getattr(other, member) is None):
                    return getattr(self, member) is None

                return getattr(self, member) < getattr(other, member)

            return False

        cls.__lt__ = lt
        return total_ordering(generate_eq(*members)(cls))

    return decorator