Shared implementation of __iFUNC__ method.

    :param self:
        A proxy_base instance
    :param other:
        Any right-hand-side value
    :param name:
        Name of the __iFUNC__
    :param op:
        Appropriate operator.__iFUNC__ operator
    :returns:
        self

def _imethod(self, other, name, op):
    """
    Shared implementation of __iFUNC__ method.

    :param self:
        A proxy_base instance
    :param other:
        Any right-hand-side value
    :param name:
        Name of the __iFUNC__
    :param op:
        Appropriate operator.__iFUNC__ operator
    :returns:
        self
    """
    proxiee_old = proxiee_new = _get_proxiee(self)
    _logger.debug("%s on proxiee (%r)", name, proxiee_old)
    # NOTE: This _may_ or _may not be_ calling __iFUNC__
    # as the proxiee may not support it in the first place
    proxiee_new = op(proxiee_old, other)
    if proxiee_new is not proxiee_old:
        # NOTE: all of the augmented assignment methods handle the case where
        # the __iFUNC__ method returns something other than self. To maintain
        # the illusion that the proxy is not there the internal proxiee
        # reference is changed to the new proxiee.
        _logger.debug("%s creates new %s (%r)",
                      name, type(self).__name__, proxiee_new)
        return type(self)(proxiee_new)
    return self