import six


def downgrader(version):
    """
    A decorator for marking a method as a downgrader to an older
    version of a given object.  Note that downgrader methods are
    implicitly class methods.  Also note that downgraders take a
    single argument--a dictionary of attributes--and must return a
    dictionary.  Downgraders may modify the argument in place, if
    desired.

    :param version: The version number the downgrader returns the
                    attributes for.  Must be provided.

    :returns: A decorator.
    """

    def decorator(func):
        # Save the version to downgrade to
        func.__vers_downgrader__ = version
        return func

    # Sanity-check the version number
    if not isinstance(version, six.integer_types) or version < 1:
        raise TypeError("Invalid downgrader version number %r" % version)

    return decorator