Take a spec in dict form, and return a function that validates objects

    The spec maps each object's key to a chain of validator functions.

    The ``key`` argument can be used to customize the way value matching a spec
    key from the object. By default, it uses ``operator.itemgetter``. It should
    be assigned a function that takes a key value and returns a function that
    returns the vale from an object that is passed to it.

def spec_validator(spec, key=operator.itemgetter):
    """ Take a spec in dict form, and return a function that validates objects

    The spec maps each object's key to a chain of validator functions.

    The ``key`` argument can be used to customize the way value matching a spec
    key from the object. By default, it uses ``operator.itemgetter``. It should
    be assigned a function that takes a key value and returns a function that
    returns the vale from an object that is passed to it.
    """
    spec = {k: (key(k), make_chain(v)) for k, v in spec.items()}

    def validator(obj):
        errors = {}
        for k, v in spec.items():
            getter, chain = v
            val = getter(obj)
            try:
                chain(val)
            except ValueError as err:
                errors[k] = err
        return errors

    return validator