Using __new__ to return the correct subclass, preserving changes made to arguments

Solution 1:

Rather than forcing __new__ to do this, I would define a separate class method for deciding what to do based on the given path:

class FileHandler:    
    def __init__(self, path, new_arg, arg1, arg2, kwarg1=None):
        # stuff

    @classmethod
    def from_path(cls, path, *args, **kwargs):
        path = do_stuff_to_path(path)
        new_arg = do_more_stuff(path)
        if check_format(path) == "video":
             cls = VideoHandler
        elif check_format(path) == "image":
             cls = ImageHandler
        return cls(path, new_arg, *args, **kwargs)

fh1 = FileHandler.from_path("path_to_video")  # instance of VideoHandler
fh2 = FileHandler.from_path("path_to_image")  # instance of ImageHandler

Now when you actually instantiate the object, only the modified arguments are passed to __init__, since you never actually call the selected type with the original arguments.