import inspect
import types


class ReprMixin:
    """
    Mixin class to provide a default __repr__  method for
    classes which merely store the __init__ arguments as attributes
    with the same name.
    """

    def __repr__(self):
        cls_name = self.__class__.__name__

        # try to find out whether the class defines it's own __init__
        # the built in object's __init__ type is wrapper_descriptor
        if type(self.__class__.__init__) == types.FunctionType:
            init_signature = inspect.signature(self.__init__)
            assigned_parameters = {key: getattr(self, key) if hasattr(self, key) else None
                                   for key in init_signature.parameters}
            par_str = ", ".join(
                key + "=" + (repr(value) if value is not None else "?")
                for key, value in assigned_parameters.items())
        else:
            par_str = ""
        return cls_name + "(" + par_str + ")"
