def blit_mask(source, dest, destpos, mask, maskrect):
    """
    Blit an source image to the dest surface, at destpos, with a mask, using
    only the maskrect part of the mask.
    """
tmp = source.copy()
tmp.blit(mask, maskrect.topleft, maskrect, special_flags=pygame.BLEND_RGBA_MULT
    )
dest.blit(tmp, destpos, dest.get_rect().clip(maskrect))
Pygame: How to draw in non rectangle clipping area