def apply(self, clip: Clip) -> Clip:
        """Apply the effect to the clip."""
        try:
            resample = {
                "bilinear": Image.BILINEAR,
                "nearest": Image.NEAREST,
                "bicubic": Image.BICUBIC,
            }[self.resample]
        except KeyError:
            raise ValueError(
                "'resample' argument must be either 'bilinear', 'nearest' or 'bicubic'"
            )

        if hasattr(self.angle, "__call__"):
            get_angle = self.angle
        else:
            get_angle = lambda t: self.angle

        def filter(get_frame, t):
            angle = get_angle(t)
            im = get_frame(t)

            if self.unit == "rad":
                angle = math.degrees(angle)

            angle %= 360
            if not self.center and not self.translate and not self.bg_color:
                if (angle == 0) and self.expand:
                    return im
                if (angle == 90) and self.expand:
                    transpose = [1, 0] if len(im.shape) == 2 else [1, 0, 2]
                    return np.transpose(im, axes=transpose)[::-1]
                elif (angle == 270) and self.expand:
                    transpose = [1, 0] if len(im.shape) == 2 else [1, 0, 2]
                    return np.transpose(im, axes=transpose)[:, ::-1]
                elif (angle == 180) and self.expand:
                    return im[::-1, ::-1]

            pillow_kwargs = {}

            if self.bg_color is not None:
                pillow_kwargs["fillcolor"] = self.bg_color

            if self.center is not None:
                pillow_kwargs["center"] = self.center

            if self.translate is not None:
                pillow_kwargs["translate"] = self.translate

            # PIL expects uint8 type data. However a mask image has values in the
            # range [0, 1] and is of float type.  To handle this we scale it up by
            # a factor 'a' for use with PIL and then back again by 'a' afterwards.
            if im.dtype == "float64":
                # this is a mask image
                a = 255.0
            else:
                a = 1

            # call PIL.rotate
            return (
                np.array(
                    Image.fromarray(np.array(a * im).astype(np.uint8)).rotate(
                        angle, expand=self.expand, resample=resample, **pillow_kwargs
                    )
                )
                / a
            )

        return clip.transform(filter, apply_to=["mask"])
Apply the effect to the clip.
moviepy/video/fx/Rotate.py