Duplicate a model, optionally choose which fields to include, exclude and change.

        :param include: fields to include in new model
        :param exclude: fields to exclude from new model, as with values this takes precedence over include
        :param update: values to change/add in the new model. Note: the data is not validated before creating
            the new model: you should trust this data
        :param deep: set to `True` to make a deep copy of the model
        :return: new model instance

def copy(
        self: 'Model',
        *,
        include: 'SetStr' = None,
        exclude: 'SetStr' = None,
        update: 'DictStrAny' = None,
        deep: bool = False,
    ) -> 'Model':
        """
        Duplicate a model, optionally choose which fields to include, exclude and change.

        :param include: fields to include in new model
        :param exclude: fields to exclude from new model, as with values this takes precedence over include
        :param update: values to change/add in the new model. Note: the data is not validated before creating
            the new model: you should trust this data
        :param deep: set to `True` to make a deep copy of the model
        :return: new model instance
        """
        if include is None and exclude is None and update is None:
            # skip constructing values if no arguments are passed
            v = self.__values__
        else:
            return_keys = self._calculate_keys(include=include, exclude=exclude, skip_defaults=False)
            if return_keys:
                v = {**{k: v for k, v in self.__values__.items() if k in return_keys}, **(update or {})}
            else:
                v = {**self.__values__, **(update or {})}

        if deep:
            v = deepcopy(v)
        m = self.__class__.construct(v, self.__fields_set__.copy())
        return m