Prevents methods from mutating the receiver

def does_not_mutate(func):
    """Prevents methods from mutating the receiver"""
    def wrapper(self, *args, **kwargs):
        new = self.copy()
        return func(new, *args, **kwargs)
    wrapper.__name__ = func.__name__
    wrapper.__doc__ = func.__doc__
    return wrapper