import attr


def typed_attrs(cls):
    """
    Created a type-validated attrs class.
    Attributes are set to their default values if they're assigned `None` to.
    """
    for attrib in cls.__dict__.values():
        try:
            if not attrib.type:
                continue
            validator = attrib._validator
        except AttributeError:
            continue
        instance_of = attr.validators.instance_of(attrib.type)
        attrib._validator = (
            attr.validators.and_(validator, instance_of) if validator else instance_of
        )
        if attrib._default != attr.NOTHING:

            def converter(default):
                """
                Create a converter that interprets `None` as "use default".
                Required in order to create a new lexical scope, see https://stackoverflow.com/a/233835
                """
                return lambda x: default if x is None else x

            attrib.converter = converter(attrib._default)

    return attr.s(cls)