from typing import Callable


def _setter_by_attribute(clazz: type, attribute: str) -> Callable:
    """
    Internal method to get the setter method for an attribute.

    Note that if the attribute in question is a @property (read-only attribute),
    it assumes that the correct choice is just setting the field name with a
    prepended underscore.

    Parameters
    ----------
    clazz: type
        The class of the object you wish to interrogate.
    attribute: str
        The name of the attribute you with to set.

    Returns
    -------
    Callable
        The attribute's setter method, callable w/ setter(object, value).

    """
    def _emulator(inner_name: str) -> Callable:
        return lambda self, value: setattr(self, inner_name, value)

    prop = getattr(clazz, attribute, None)
    if prop is None:  # It's not a property, just an ordinary attribute
        setter = _emulator(attribute)
    elif prop.fset is None:  # It's read only, so set directly
        setter = _emulator(f"_{attribute}")
    else:
        setter = prop.fset

    return setter